pcsc-lite 2.3.0
libredirect.c
Go to the documentation of this file.
1/*
2 * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ )
3 *
4 * Copyright (C) 2024
5 * Ludovic Rousseau <ludovic.rousseau@free.fr>
6 *
7Redistribution and use in source and binary forms, with or without
8modification, are permitted provided that the following conditions
9are met:
10
111. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
132. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
163. The name of the author may not be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
36#include <dlfcn.h>
37#include <stdio.h>
38#include <stdarg.h>
39#include <fcntl.h>
40#include <stdlib.h>
41#include <errno.h>
42#include <string.h>
43#include <unistd.h>
44#include <sys/time.h>
45#include <pthread.h>
46
47#include "misc.h"
48#include <winscard.h>
49#include "sys_generic.h"
50
51#define DEBUG
52
53#define DLSYM_DECLARE(symbol) \
54 typeof(symbol)* symbol
55#define DLSYM_SET_VALUE(symbol) \
56 .symbol = (typeof(symbol)(*))internal_error
57
58/* fake function to just return en error code */
59static LONG internal_error(void)
60{
62}
63
64#pragma GCC diagnostic push
65#pragma GCC diagnostic ignored "-Wcast-function-type"
66/* contains pointers to real functions */
67static struct
68{
69 DLSYM_DECLARE(SCardEstablishContext);
70 DLSYM_DECLARE(SCardReleaseContext);
71 DLSYM_DECLARE(SCardIsValidContext);
72 DLSYM_DECLARE(SCardConnect);
73 DLSYM_DECLARE(SCardReconnect);
74 DLSYM_DECLARE(SCardDisconnect);
75 DLSYM_DECLARE(SCardBeginTransaction);
76 DLSYM_DECLARE(SCardEndTransaction);
77 DLSYM_DECLARE(SCardStatus);
78 DLSYM_DECLARE(SCardGetStatusChange);
79 DLSYM_DECLARE(SCardControl);
80 DLSYM_DECLARE(SCardTransmit);
81 DLSYM_DECLARE(SCardListReaderGroups);
82 DLSYM_DECLARE(SCardListReaders);
83 DLSYM_DECLARE(SCardFreeMemory);
84 DLSYM_DECLARE(SCardCancel);
85 DLSYM_DECLARE(SCardGetAttrib);
86 DLSYM_DECLARE(SCardSetAttrib);
87} redirect = {
88 /* initialized with the fake internal_error() function */
89 DLSYM_SET_VALUE(SCardEstablishContext),
90 DLSYM_SET_VALUE(SCardReleaseContext),
91 DLSYM_SET_VALUE(SCardIsValidContext),
92 DLSYM_SET_VALUE(SCardConnect),
93 DLSYM_SET_VALUE(SCardReconnect),
94 DLSYM_SET_VALUE(SCardDisconnect),
95 DLSYM_SET_VALUE(SCardBeginTransaction),
96 DLSYM_SET_VALUE(SCardEndTransaction),
97 DLSYM_SET_VALUE(SCardStatus),
98 DLSYM_SET_VALUE(SCardGetStatusChange),
99 DLSYM_SET_VALUE(SCardControl),
100 DLSYM_SET_VALUE(SCardTransmit),
101 DLSYM_SET_VALUE(SCardListReaderGroups),
102 DLSYM_SET_VALUE(SCardListReaders),
103 DLSYM_SET_VALUE(SCardFreeMemory),
104 DLSYM_SET_VALUE(SCardCancel),
105 DLSYM_SET_VALUE(SCardGetAttrib),
106 DLSYM_SET_VALUE(SCardSetAttrib)
107};
108#pragma GCC diagnostic pop
109
110static void *Lib_handle = NULL;
111
112#ifdef DEBUG
113static void log_line(const char *fmt, ...)
114{
115 va_list args;
116
117 va_start(args, fmt);
118 vfprintf(stderr, fmt, args);
119 fprintf(stderr, "\n");
120 va_end(args);
121}
122#else
123static void log_line(const char *fmt, ...)
124{
125}
126#endif
127
128static LONG load_lib(void)
129{
130#define LIBPCSC "libpcsclite_real.so.1"
131
132 const char *lib;
133
134 lib = SYS_GetEnv("LIBPCSCLITE_DELEGATE");
135 if (NULL == lib)
136 lib = LIBPCSC;
137
138 /* load the real library */
139 Lib_handle = dlopen(lib, RTLD_LAZY);
140 if (NULL == Lib_handle)
141 {
142 log_line("loading \"%s\" failed: %s", lib, dlerror());
144 }
145
146#define get_symbol(s) do { redirect.s = dlsym(Lib_handle, #s); if (NULL == redirect.s) { log_line("%s", dlerror()); return SCARD_F_INTERNAL_ERROR; } } while (0)
147
148 if (SCardEstablishContext == dlsym(Lib_handle, "SCardEstablishContext"))
149 {
150 log_line("Symbols dlsym error");
152 }
153
154 get_symbol(SCardEstablishContext);
155 get_symbol(SCardReleaseContext);
156 get_symbol(SCardIsValidContext);
157 get_symbol(SCardConnect);
158 get_symbol(SCardReconnect);
159 get_symbol(SCardDisconnect);
160 get_symbol(SCardBeginTransaction);
161 get_symbol(SCardEndTransaction);
162 get_symbol(SCardStatus);
163 get_symbol(SCardGetStatusChange);
164 get_symbol(SCardControl);
165 get_symbol(SCardTransmit);
166 get_symbol(SCardListReaderGroups);
167 get_symbol(SCardListReaders);
168 get_symbol(SCardFreeMemory);
169 get_symbol(SCardCancel);
170 get_symbol(SCardGetAttrib);
171 get_symbol(SCardSetAttrib);
172
173 return SCARD_S_SUCCESS;
174}
175
176
177/* exported functions */
178PCSC_API LONG SCardEstablishContext(DWORD dwScope,
179 LPCVOID pvReserved1,
180 LPCVOID pvReserved2,
181 LPSCARDCONTEXT phContext)
182{
183 LONG rv;
184 static int init = 0;
185
186 if (!init)
187 {
188 init = 1;
189
190 /* load the real library */
191 rv = load_lib();
192 if (rv != SCARD_S_SUCCESS)
193 return rv;
194 }
195
196 return redirect.SCardEstablishContext(dwScope, pvReserved1, pvReserved2,
197 phContext);
198}
199
200PCSC_API LONG SCardReleaseContext(SCARDCONTEXT hContext)
201{
202 return redirect.SCardReleaseContext(hContext);
203}
204
205PCSC_API LONG SCardIsValidContext(SCARDCONTEXT hContext)
206{
207 return redirect.SCardIsValidContext(hContext);
208}
209
210PCSC_API LONG SCardConnect(SCARDCONTEXT hContext,
211 LPCSTR szReader,
212 DWORD dwShareMode,
213 DWORD dwPreferredProtocols,
214 LPSCARDHANDLE phCard,
215 LPDWORD pdwActiveProtocol)
216{
217 return redirect.SCardConnect(hContext, szReader, dwShareMode,
218 dwPreferredProtocols, phCard, pdwActiveProtocol);
219}
220
221PCSC_API LONG SCardReconnect(SCARDHANDLE hCard,
222 DWORD dwShareMode,
223 DWORD dwPreferredProtocols,
224 DWORD dwInitialization,
225 LPDWORD pdwActiveProtocol)
226{
227 return redirect.SCardReconnect(hCard, dwShareMode, dwPreferredProtocols,
228 dwInitialization, pdwActiveProtocol);
229}
230
231PCSC_API LONG SCardDisconnect(SCARDHANDLE hCard,
232 DWORD dwDisposition)
233{
234 return redirect.SCardDisconnect(hCard, dwDisposition);
235}
236
237PCSC_API LONG SCardBeginTransaction(SCARDHANDLE hCard)
238{
239 return redirect.SCardBeginTransaction(hCard);
240}
241
242PCSC_API LONG SCardEndTransaction(SCARDHANDLE hCard,
243 DWORD dwDisposition)
244{
245 return redirect.SCardEndTransaction(hCard, dwDisposition);
246}
247
248PCSC_API LONG SCardStatus(SCARDHANDLE hCard,
249 LPSTR mszReaderName,
250 LPDWORD pcchReaderLen,
251 LPDWORD pdwState,
252 LPDWORD pdwProtocol,
253 LPBYTE pbAtr,
254 LPDWORD pcbAtrLen)
255{
256 return redirect.SCardStatus(hCard, mszReaderName, pcchReaderLen, pdwState,
257 pdwProtocol, pbAtr, pcbAtrLen);
258}
259
260PCSC_API LONG SCardGetStatusChange(SCARDCONTEXT hContext,
261 DWORD dwTimeout,
262 SCARD_READERSTATE *rgReaderStates,
263 DWORD cReaders)
264{
265 return redirect.SCardGetStatusChange(hContext, dwTimeout, rgReaderStates,
266 cReaders);
267}
268
269PCSC_API LONG SCardControl(SCARDHANDLE hCard,
270 DWORD dwControlCode,
271 LPCVOID pbSendBuffer,
272 DWORD cbSendLength,
273 LPVOID pbRecvBuffer,
274 DWORD cbRecvLength,
275 LPDWORD lpBytesReturned)
276{
277 return redirect.SCardControl(hCard, dwControlCode, pbSendBuffer, cbSendLength,
278 pbRecvBuffer, cbRecvLength, lpBytesReturned);
279}
280
281PCSC_API LONG SCardTransmit(SCARDHANDLE hCard,
282 const SCARD_IO_REQUEST *pioSendPci,
283 LPCBYTE pbSendBuffer,
284 DWORD cbSendLength,
285 SCARD_IO_REQUEST *pioRecvPci,
286 LPBYTE pbRecvBuffer,
287 LPDWORD pcbRecvLength)
288{
289 return redirect.SCardTransmit(hCard, pioSendPci, pbSendBuffer, cbSendLength,
290 pioRecvPci, pbRecvBuffer, pcbRecvLength);
291}
292
293PCSC_API LONG SCardListReaderGroups(SCARDCONTEXT hContext,
294 LPSTR mszGroups,
295 LPDWORD pcchGroups)
296{
297 return redirect.SCardListReaderGroups(hContext, mszGroups, pcchGroups);
298}
299
300PCSC_API LONG SCardListReaders(SCARDCONTEXT hContext,
301 LPCSTR mszGroups,
302 LPSTR mszReaders,
303 LPDWORD pcchReaders)
304{
305 return redirect.SCardListReaders(hContext, mszGroups, mszReaders, pcchReaders);
306}
307
308PCSC_API LONG SCardFreeMemory(SCARDCONTEXT hContext,
309 LPCVOID pvMem)
310{
311 return redirect.SCardFreeMemory(hContext, pvMem);
312}
313
314PCSC_API LONG SCardCancel(SCARDCONTEXT hContext)
315{
316 return redirect.SCardCancel(hContext);
317}
318
319PCSC_API LONG SCardGetAttrib(SCARDHANDLE hCard,
320 DWORD dwAttrId,
321 LPBYTE pbAttr,
322 LPDWORD pcbAttrLen)
323{
324 return redirect.SCardGetAttrib(hCard, dwAttrId, pbAttr, pcbAttrLen);
325}
326
327PCSC_API LONG SCardSetAttrib(SCARDHANDLE hCard,
328 DWORD dwAttrId,
329 LPCBYTE pbAttr,
330 DWORD cbAttrLen)
331{
332 return redirect.SCardSetAttrib(hCard, dwAttrId, pbAttr, cbAttrLen);
333}
334
341
#define SCARD_F_INTERNAL_ERROR
An internal consistency check failed.
Definition pcsclite.h:109
#define SCARD_S_SUCCESS
No error was encountered.
Definition pcsclite.h:107
PCSC_API const SCARD_IO_REQUEST g_rgSCardRawPci
Protocol Control Information for raw access.
PCSC_API const SCARD_IO_REQUEST g_rgSCardT1Pci
Protocol Control Information for T=1.
PCSC_API const SCARD_IO_REQUEST g_rgSCardT0Pci
Protocol Control Information for T=0.
LONG SCARDCONTEXT
hContext returned by SCardEstablishContext()
Definition pcsclite.h:52
#define SCARD_PROTOCOL_T1
T=1 active protocol.
Definition pcsclite.h:243
#define SCARD_PROTOCOL_T0
T=0 active protocol.
Definition pcsclite.h:242
#define SCARD_PROTOCOL_RAW
Raw active protocol.
Definition pcsclite.h:244
LONG SCARDHANDLE
hCard returned by SCardConnect()
Definition pcsclite.h:55
Protocol Control Information (PCI)
Definition pcsclite.h:80
This handles abstract system level calls.
const char * SYS_GetEnv(const char *name)
(More) secure version of getenv(3)
Definition sys_unix.c:168
This handles smart card reader communications.