108#include <sys/types.h>
138static bool sharing_shall_block =
true;
140#define COLOR_RED "\33[01;31m"
141#define COLOR_GREEN "\33[32m"
142#define COLOR_BLUE "\33[34m"
143#define COLOR_MAGENTA "\33[35m"
144#define COLOR_NORMAL "\33[0m"
155 fprintf(
stderr, COLOR_GREEN
"%c " COLOR_BLUE
"[%lX] " COLOR_GREEN
"%s ",
166#define API_TRACE_IN(...) trace(__FUNCTION__, '<', __VA_ARGS__);
167#define API_TRACE_OUT(...) trace(__FUNCTION__, '>', __VA_ARGS__);
169#define API_TRACE_IN(...)
170#define API_TRACE_OUT(...)
175#define PROFILE_FILE "/tmp/pcsc_profile"
186#define PROFILE_START profile_start();
187#define PROFILE_END(rv) profile_end(__FUNCTION__, rv);
204 fprintf(
stderr, COLOR_RED
"Can't open %s: %s" COLOR_NORMAL
"\n",
243 fprintf(
stderr, COLOR_BLUE
" WARNING: no start info for %s\n",
f);
256 COLOR_RED
"RESULT %s " COLOR_MAGENTA
"%ld "
257 COLOR_BLUE
"0x%08lX %s" COLOR_NORMAL
"\n",
261 COLOR_NORMAL
"\n",
f,
d);
269#define PROFILE_END(rv)
284static int CHANNEL_MAP_seeker(
const void *
el,
const void *key)
290 Log3(PCSC_LOG_CRITICAL,
291 "CHANNEL_MAP_seeker called with NULL pointer: el=%p, key=%p",
322static list_t contextMapList;
324static int SCONTEXTMAP_seeker(
const void *
el,
const void *key)
330 Log3(PCSC_LOG_CRITICAL,
331 "SCONTEXTMAP_seeker called with NULL pointer: el=%p, key=%p",
369static LONG SCardGetContextChannelAndLockFromHandle(
SCARDHANDLE,
371static LONG SCardGetContextAndChannelFromHandleTH(
SCARDHANDLE,
375static LONG SCardGetSetAttrib(
SCARDHANDLE hCard,
int command, DWORD dwAttrId,
490DESTRUCTOR
static void destructor(
void)
492 list_destroy(&contextMapList);
500static void init_lib(
void)
507 lrv = list_init(&contextMapList);
510 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d",
515 lrv = list_attributes_seeker(&contextMapList,
519 Log2(PCSC_LOG_CRITICAL,
520 "list_attributes_seeker failed with return value: %d",
lrv);
521 list_destroy(&contextMapList);
527 Log1(PCSC_LOG_INFO,
"Disable shared blocking");
528 sharing_shall_block =
false;
602 Log1(PCSC_LOG_CRITICAL,
603 "Your pcscd is too old and does not support CMD_VERSION");
607 Log3(PCSC_LOG_INFO,
"Server is protocol version %d:%d",
694 API_TRACE_IN(
"%ld", hContext)
801 DWORD dwShareMode, DWORD dwPreferredProtocols, LPSCARDHANDLE
phCard,
809 API_TRACE_IN(
"%ld %s %ld %ld", hContext, szReader, dwShareMode, dwPreferredProtocols)
819 if (szReader ==
NULL)
825 if (
strlen(szReader) > MAX_READERNAME)
956 DWORD dwPreferredProtocols, DWORD dwInitialization,
965 API_TRACE_IN(
"%ld %ld %ld", hCard, dwShareMode, dwPreferredProtocols)
1062 API_TRACE_IN(
"%ld %ld", hCard, dwDisposition)
1095 SCardRemoveHandle(hCard);
1153 API_TRACE_IN(
"%ld", hCard)
1253 API_TRACE_IN(
"%ld", hCard)
1764 const char *readerName;
1778 if (
strcasecmp(readerName,
"\\\\?PnP?\\Notification") != 0)
1793 Log2(PCSC_LOG_DEBUG,
"Event Loop Start, dwTimeout: %ld",
dwTimeout);
1816 const char *readerName;
1834 if (
strcasecmp(readerName,
"\\\\?PnP?\\Notification") == 0)
1844 Log1(PCSC_LOG_INFO,
"Reader list changed");
1876 Log0(PCSC_LOG_DEBUG);
1897 Log0(PCSC_LOG_DEBUG);
1915 Log0(PCSC_LOG_DEBUG);
1926 Log0(PCSC_LOG_DEBUG);
1934#ifndef DISABLE_AUTO_POWER_ON
1965 Log0(PCSC_LOG_DEBUG);
1983 Log0(PCSC_LOG_DEBUG);
1993 Log0(PCSC_LOG_DEBUG);
2003 Log0(PCSC_LOG_DEBUG);
2017 Log0(PCSC_LOG_DEBUG);
2031 Log0(PCSC_LOG_DEBUG);
2044 Log0(PCSC_LOG_DEBUG);
2051 Log0(PCSC_LOG_DEBUG);
2063 Log0(PCSC_LOG_DEBUG);
2157 Log1(PCSC_LOG_DEBUG,
"Event Loop End");
2230 DWORD cbSendLength, LPVOID
pbRecvBuffer, DWORD cbRecvLength,
2467 *(
unsigned char **)pbAttr =
buf;
2530 if (
NULL == pbAttr || 0 == cbAttrLen)
2541static LONG SCardGetSetAttrib(
SCARDHANDLE hCard,
int command, DWORD dwAttrId,
2683 LPDWORD pcbRecvLength)
2872 API_TRACE_IN(
"%ld", hContext)
3061 const char ReaderGroup[] =
"SCard$DefaultReaders\0";
3150 API_TRACE_IN(
"%ld", hContext)
3236 API_TRACE_IN(
"%ld", hContext)
3277 Log2(PCSC_LOG_DEBUG,
"Allocating new SCONTEXTMAP @%p",
newContextMap);
3287 Log2(PCSC_LOG_CRITICAL,
"list_init failed with return value: %d",
lrv);
3292 CHANNEL_MAP_seeker);
3295 Log2(PCSC_LOG_CRITICAL,
3296 "list_attributes_seeker failed with return value: %d",
lrv);
3304 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
3366 return list_seek(&contextMapList, &hContext);
3402 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed for index %d",
3418 Log2(PCSC_LOG_CRITICAL,
3419 "list_delete failed with return value: %d",
lrv);
3449 Log2(PCSC_LOG_CRITICAL,
"list_append failed with return value: %d",
3474 Log2(PCSC_LOG_CRITICAL,
3475 "list_delete failed with return value: %d",
lrv);
3483static LONG SCardGetContextChannelAndLockFromHandle(
SCARDHANDLE hCard,
3503static LONG SCardGetContextAndChannelFromHandleTH(
SCARDHANDLE hCard,
3515 listSize = list_size(&contextMapList);
3522 Log2(PCSC_LOG_CRITICAL,
"list_get_at failed for index %d",
3557 Log3(PCSC_LOG_INFO,
"PCSC Not Running: %s: %s",
3606 dwClientID, 0,
NULL);
This handles card insertion/removal events, updates ATR, protocol, and status information.
#define PCSCLITE_SHARING_EXCLUSIVE_CONTEXT
Reader used in exclusive mode.
#define PCSCLITE_SHARING_NO_CONTEXT
No application is using the reader.
#define PCSCLITE_SHARING_LAST_CONTEXT
One application is using the reader.
PCSC_API const char * pcsc_stringify_error(const LONG pcscError)
Returns a human readable text for the given PC/SC error code.
#define SCARD_E_INVALID_HANDLE
The supplied handle was invalid.
#define SCARD_E_UNKNOWN_READER
The specified reader name is not recognized.
#define SCARD_E_INVALID_PARAMETER
One or more of the supplied parameters could not be properly interpreted.
#define SCARD_E_CANCELLED
The action was cancelled by an SCardCancel request.
#define SCARD_S_SUCCESS
No error was encountered.
#define SCARD_E_NO_MEMORY
Not enough memory available to complete this command.
#define SCARD_E_NO_READERS_AVAILABLE
Cannot find a smart card reader.
#define SCARD_E_SHARING_VIOLATION
The smart card cannot be accessed because of other connections outstanding.
#define SCARD_E_INVALID_VALUE
One or more of the supplied parameters values could not be properly interpreted.
#define SCARD_E_TIMEOUT
The user-specified timeout value has expired.
#define SCARD_E_INSUFFICIENT_BUFFER
The data buffer to receive returned data is too small for the returned data.
#define SCARD_E_NO_SERVICE
The Smart card resource manager is not running.
#define SCARD_E_READER_UNAVAILABLE
The specified reader is not currently available for use.
This keeps a list of defines for pcsc-lite.
#define PCSCLITE_STATUS_POLL_RATE
Status polling rate.
@ POWER_STATE_POWERED
powered
#define PCSCLITE_LOCK_POLL_RATE
Lock polling rate.
#define SCARD_STATE_IGNORE
Ignore this reader.
#define SCARD_SWALLOWED
Card not powered.
LONG SCARDCONTEXT
hContext returned by SCardEstablishContext()
#define SCARD_PRESENT
Card is present.
#define SCARD_STATE_INUSE
Shared Mode.
#define SCARD_AUTOALLOCATE
see SCardFreeMemory()
#define SCARD_STATE_UNAVAILABLE
Status unavailable.
#define SCARD_STATE_PRESENT
Card inserted.
#define SCARD_ABSENT
Card is absent.
#define SCARD_UNKNOWN
Unknown state.
#define SCARD_STATE_UNKNOWN
Reader unknown.
#define INFINITE
Infinite timeout.
#define SCARD_STATE_EMPTY
Card removed.
#define SCARD_STATE_MUTE
Unresponsive card.
#define SCARD_STATE_CHANGED
State has changed.
#define SCARD_PROTOCOL_ANY
IFD determines prot.
#define MAX_BUFFER_SIZE
Maximum Tx/Rx Buffer for short APDU.
#define MAX_BUFFER_SIZE_EXTENDED
enhanced (64K + APDU + Lc + Le + SW) Tx/Rx Buffer
#define SCARD_STATE_EXCLUSIVE
Exclusive Mode.
#define SCARD_STATE_UNAWARE
App wants status.
LONG SCARDHANDLE
hCard returned by SCardConnect()
#define PCSCLITE_MAX_READERS_CONTEXTS
Maximum readers context (a slot is count as a reader)
This keeps track of a list of currently available reader structures.
Protocol Control Information (PCI)
Represents an Application Context Channel.
Represents an Application Context on the Client side.
pthread_mutex_t mMutex
Mutex for this context.
SCARDCONTEXT hContext
Application Context ID.
DWORD dwClientID
Client Connection ID.
bool cancellable
We are in a cancellable call.
contained in SCARD_BEGIN_TRANSACTION Messages.
contained in SCARD_CANCEL Messages.
contained in SCARD_CONNECT Messages.
contained in SCARD_CONTROL Messages.
contained in SCARD_DISCONNECT Messages.
contained in SCARD_END_TRANSACTION Messages.
Information contained in SCARD_ESTABLISH_CONTEXT Messages.
contained in SCARD_GET_ATTRIB and Messages.
Define an exported public reader state structure so each application gets instant notification of cha...
uint32_t cardProtocol
SCARD_PROTOCOL_* value.
uint32_t eventCounter
number of card events
_Atomic uint32_t cardAtrLength
ATR length.
uint32_t readerState
SCARD_* bit field.
contained in SCARD_RECONNECT Messages.
Information contained in SCARD_RELEASE_CONTEXT Messages.
contained in SCARD_STATUS Messages.
contained in SCARD_TRANSMIT Messages.
Information transmitted in CMD_VERSION Messages.
int32_t major
IPC major PROTOCOL_VERSION_MAJOR.
Information contained in CMD_WAIT_READER_STATE_CHANGE Messages.
This handles abstract system level calls.
const char * SYS_GetEnv(const char *name)
(More) secure version of getenv(3)
int SYS_USleep(int)
Makes the current process sleep for some microseconds.
long int time_sub(struct timeval *a, struct timeval *b)
return the difference (as long int) in µs between 2 struct timeval r = a - b
This handles smart card reader communications.
static bool isExecuted
Make sure the initialization code is executed only once.
static void SCardLockThread(void)
Locks a mutex so another thread must wait to use this function.
static void SCardRemoveContext(SCARDCONTEXT)
Removes an Application Context from a control vector.
static SCONTEXTMAP * SCardGetAndLockContext(SCARDCONTEXT)
Get the SCONTEXTMAP * from the Application Context vector _psContextMap for the passed context.
static bool SCardGetContextValidity(SCARDCONTEXT hContext)
Tell if a context index from the Application Context vector _psContextMap is valid or not.
static void SCardUnlockThread(void)
Unlocks a mutex so another thread may use the client.
static pthread_mutex_t clientMutex
Ensure that some functions be accessed in thread-safe mode.
LONG SCardCheckDaemonAvailability(void)
Checks if the server is running.
static SCONTEXTMAP * SCardGetContextTH(SCARDCONTEXT)
Get the address from the Application Context list _psContextMap for the passed context.
static LONG SCardEstablishContextTH(DWORD, LPCVOID, LPCVOID, LPSCARDCONTEXT)
Creates a communication context to the PC/SC Resource Manager.
static LONG SCardAddContext(SCARDCONTEXT, DWORD)
Functions for managing instances of SCardEstablishContext() These functions keep track of Context han...
static READER_STATE readerStates[PCSCLITE_MAX_READERS_CONTEXTS]
Area used to read status information about the readers.
INTERNAL int ClientSetupSession(uint32_t *pdwClientID)
Prepares a communication channel for the client to talk to the server.
INTERNAL LONG MessageReceiveTimeout(uint32_t command, void *buffer_void, uint64_t buffer_size, int32_t filedes, long timeOut)
Called by the Client to get the response from the server or vice-versa.
INTERNAL LONG MessageSendWithHeader(uint32_t command, uint32_t dwClientID, uint64_t size, void *data_void)
Wrapper for the MessageSend() function.
INTERNAL LONG MessageSend(void *buffer_void, uint64_t buffer_size, int32_t filedes)
Sends a menssage from client to server or vice-versa.
INTERNAL void ClientCloseSession(uint32_t dwClientID)
Closes the socket used by the client to communicate with the server.
INTERNAL LONG MessageReceive(void *buffer_void, uint64_t buffer_size, int32_t filedes)
Called by the Client to get the response from the server or vice-versa.
This defines some structures and #defines to be used over the transport layer.
#define PROTOCOL_VERSION_MAJOR
Major version of the current message protocol.
#define PROTOCOL_VERSION_MINOR
Minor version of the current message protocol.
@ SCARD_DISCONNECT
used by SCardDisconnect()
@ SCARD_SET_ATTRIB
used by SCardSetAttrib()
@ SCARD_RELEASE_CONTEXT
used by SCardReleaseContext()
@ CMD_STOP_WAITING_READER_STATE_CHANGE
stop waiting for a reader state change
@ CMD_GET_READERS_STATE
get the readers state
@ SCARD_CONTROL
used by SCardControl()
@ CMD_VERSION
get the client/server protocol version
@ CMD_WAIT_READER_STATE_CHANGE
wait for a reader state change
@ SCARD_RECONNECT
used by SCardReconnect()
@ SCARD_STATUS
used by SCardStatus()
@ SCARD_GET_ATTRIB
used by SCardGetAttrib()
@ SCARD_BEGIN_TRANSACTION
used by SCardBeginTransaction()
@ SCARD_TRANSMIT
used by SCardTransmit()
@ SCARD_END_TRANSACTION
used by SCardEndTransaction()
@ SCARD_CANCEL
used by SCardCancel()
@ SCARD_CONNECT
used by SCardConnect()
@ SCARD_ESTABLISH_CONTEXT
used by SCardEstablishContext()