pcsc-lite 1.5.5
|
00001 /* 00002 * MUSCLE SmartCard Development ( http://www.linuxnet.com ) 00003 * 00004 * Copyright (C) 2001-2004 00005 * David Corcoran <corcoran@linuxnet.com> 00006 * Damien Sauveron <damien.sauveron@labri.fr> 00007 * Ludovic Rousseau <ludovic.rousseau@free.fr> 00008 * 00009 * $Id: winscard_svc.c 4334 2009-07-21 14:26:19Z rousseau $ 00010 */ 00011 00022 #include "config.h" 00023 #include <time.h> 00024 #include <stdio.h> 00025 #include <string.h> 00026 #include <stddef.h> 00027 00028 #include "pcscd.h" 00029 #include "winscard.h" 00030 #include "debuglog.h" 00031 #include "winscard_msg.h" 00032 #include "winscard_svc.h" 00033 #include "sys_generic.h" 00034 #include "thread_generic.h" 00035 #include "readerfactory.h" 00036 00042 static struct _psContext 00043 { 00044 uint32_t hContext; 00045 uint32_t hCard[PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS]; 00046 uint32_t dwClientID; 00047 PCSCLITE_THREAD_T pthThread; 00048 sharedSegmentMsg msgStruct; 00049 int protocol_major, protocol_minor; 00050 } psContext[PCSCLITE_MAX_APPLICATIONS_CONTEXTS]; 00051 00052 static LONG MSGCheckHandleAssociation(SCARDHANDLE, DWORD); 00053 static LONG MSGFunctionDemarshall(psharedSegmentMsg, DWORD); 00054 static LONG MSGAddContext(SCARDCONTEXT, DWORD); 00055 static LONG MSGRemoveContext(SCARDCONTEXT, DWORD); 00056 static LONG MSGAddHandle(SCARDCONTEXT, SCARDHANDLE, DWORD); 00057 static LONG MSGRemoveHandle(SCARDHANDLE, DWORD); 00058 static LONG MSGCleanupClient(DWORD); 00059 00060 static void ContextThread(LPVOID pdwIndex); 00061 00062 LONG ContextsInitialize(void) 00063 { 00064 memset(psContext, 0, sizeof(struct _psContext)*PCSCLITE_MAX_APPLICATIONS_CONTEXTS); 00065 return 1; 00066 } 00067 00078 LONG CreateContextThread(uint32_t *pdwClientID) 00079 { 00080 long i; 00081 int rv; 00082 00083 for (i = 0; i < PCSCLITE_MAX_APPLICATIONS_CONTEXTS; i++) 00084 { 00085 if (psContext[i].dwClientID == 0) 00086 { 00087 psContext[i].dwClientID = *pdwClientID; 00088 *pdwClientID = 0; 00089 break; 00090 } 00091 } 00092 00093 if (i == PCSCLITE_MAX_APPLICATIONS_CONTEXTS) 00094 { 00095 Log2(PCSC_LOG_CRITICAL, "No more context available (max: %d)", 00096 PCSCLITE_MAX_APPLICATIONS_CONTEXTS); 00097 return SCARD_F_INTERNAL_ERROR; 00098 } 00099 00100 rv = SYS_ThreadCreate(&psContext[i].pthThread, THREAD_ATTR_DETACHED, 00101 (PCSCLITE_THREAD_FUNCTION( )) ContextThread, (LPVOID) i); 00102 if (rv) 00103 { 00104 (void)SYS_CloseFile(psContext[i].dwClientID); 00105 psContext[i].dwClientID = 0; 00106 Log2(PCSC_LOG_CRITICAL, "SYS_ThreadCreate failed: %s", strerror(rv)); 00107 return SCARD_E_NO_MEMORY; 00108 } 00109 00110 return SCARD_S_SUCCESS; 00111 } 00112 00113 /* 00114 * A list of local functions used to keep track of clients and their 00115 * connections 00116 */ 00117 00126 static void ContextThread(LPVOID dwIndex) 00127 { 00128 LONG rv; 00129 sharedSegmentMsg msgStruct; 00130 DWORD dwContextIndex = (DWORD)dwIndex; 00131 00132 Log2(PCSC_LOG_DEBUG, "Thread is started: %d", 00133 psContext[dwContextIndex].dwClientID); 00134 00135 while (1) 00136 { 00137 switch (rv = SHMProcessEventsContext(psContext[dwContextIndex].dwClientID, &msgStruct)) 00138 { 00139 case 0: 00140 if (msgStruct.mtype == CMD_CLIENT_DIED) 00141 { 00142 /* 00143 * Clean up the dead client 00144 */ 00145 Log2(PCSC_LOG_DEBUG, "Client die: %d", 00146 psContext[dwContextIndex].dwClientID); 00147 (void)MSGCleanupClient(dwContextIndex); 00148 (void)SYS_ThreadExit((LPVOID) NULL); 00149 } 00150 break; 00151 00152 case 1: 00153 if (msgStruct.mtype == CMD_FUNCTION) 00154 { 00155 /* 00156 * Command must be found 00157 */ 00158 rv = MSGFunctionDemarshall(&msgStruct, dwContextIndex); 00159 if (rv) 00160 { 00161 Log2(PCSC_LOG_DEBUG, "MSGFunctionDemarshall failed: %d", 00162 rv); 00163 (void)SHMClientCloseSession(psContext[dwContextIndex].dwClientID); 00164 (void)MSGCleanupClient(dwContextIndex); 00165 (void)SYS_ThreadExit((LPVOID) NULL); 00166 } 00167 00168 /* the SCARD_TRANSMIT_EXTENDED anwser is already sent by 00169 * MSGFunctionDemarshall */ 00170 if ((msgStruct.command != SCARD_TRANSMIT_EXTENDED) 00171 && (msgStruct.command != SCARD_CONTROL_EXTENDED)) 00172 rv = SHMMessageSend(&msgStruct, sizeof(msgStruct), 00173 psContext[dwContextIndex].dwClientID, 00174 PCSCLITE_SERVER_ATTEMPTS); 00175 } 00176 else 00177 /* pcsc-lite client/server protocol version */ 00178 if (msgStruct.mtype == CMD_VERSION) 00179 { 00180 version_struct *veStr; 00181 veStr = &msgStruct.veStr; 00182 00183 /* get the client protocol version */ 00184 psContext[dwContextIndex].protocol_major = veStr->major; 00185 psContext[dwContextIndex].protocol_minor = veStr->minor; 00186 00187 Log3(PCSC_LOG_DEBUG, 00188 "Client is protocol version %d:%d", 00189 veStr->major, veStr->minor); 00190 00191 veStr->rv = SCARD_S_SUCCESS; 00192 00193 /* client is newer than server */ 00194 if ((veStr->major > PROTOCOL_VERSION_MAJOR) 00195 || (veStr->major == PROTOCOL_VERSION_MAJOR 00196 && veStr->minor > PROTOCOL_VERSION_MINOR)) 00197 { 00198 Log3(PCSC_LOG_CRITICAL, 00199 "Client protocol is too new %d:%d", 00200 veStr->major, veStr->minor); 00201 Log3(PCSC_LOG_CRITICAL, 00202 "Server protocol is %d:%d", 00203 PROTOCOL_VERSION_MAJOR, PROTOCOL_VERSION_MINOR); 00204 veStr->rv = SCARD_E_NO_SERVICE; 00205 } 00206 00207 /* set the server protocol version */ 00208 veStr->major = PROTOCOL_VERSION_MAJOR; 00209 veStr->minor = PROTOCOL_VERSION_MINOR; 00210 00211 /* send back the response */ 00212 rv = SHMMessageSend(&msgStruct, sizeof(msgStruct), 00213 psContext[dwContextIndex].dwClientID, 00214 PCSCLITE_SERVER_ATTEMPTS); 00215 } 00216 else 00217 continue; 00218 00219 break; 00220 00221 case 2: 00222 /* 00223 * timeout in SHMProcessEventsContext(): do nothing 00224 * this is used to catch the Ctrl-C signal at some time when 00225 * nothing else happens 00226 */ 00227 break; 00228 00229 case -1: 00230 Log1(PCSC_LOG_ERROR, "Error in SHMProcessEventsContext"); 00231 break; 00232 00233 default: 00234 Log2(PCSC_LOG_ERROR, 00235 "SHMProcessEventsContext unknown retval: %d", rv); 00236 break; 00237 } 00238 } 00239 } 00240 00256 static LONG MSGFunctionDemarshall(psharedSegmentMsg msgStruct, 00257 DWORD dwContextIndex) 00258 { 00259 LONG rv; 00260 establish_struct *esStr; 00261 release_struct *reStr; 00262 connect_struct *coStr; 00263 reconnect_struct *rcStr; 00264 disconnect_struct *diStr; 00265 begin_struct *beStr; 00266 cancel_struct *caStr; 00267 end_struct *enStr; 00268 status_struct *stStr; 00269 transmit_struct *trStr; 00270 control_struct *ctStr; 00271 getset_struct *gsStr; 00272 00273 SCARDCONTEXT hContext; 00274 SCARDHANDLE hCard; 00275 DWORD dwActiveProtocol; 00276 00277 DWORD cchReaderLen; 00278 DWORD dwState; 00279 DWORD dwProtocol; 00280 DWORD cbAtrLen; 00281 DWORD cbRecvLength; 00282 DWORD dwBytesReturned; 00283 DWORD cbAttrLen; 00284 00285 SCARD_IO_REQUEST ioSendPci; 00286 SCARD_IO_REQUEST ioRecvPci; 00287 00288 /* 00289 * Zero out everything 00290 */ 00291 rv = 0; 00292 switch (msgStruct->command) 00293 { 00294 00295 case SCARD_ESTABLISH_CONTEXT: 00296 esStr = ((establish_struct *) msgStruct->data); 00297 00298 hContext = esStr->hContext; 00299 esStr->rv = SCardEstablishContext(esStr->dwScope, 0, 0, &hContext); 00300 esStr->hContext = hContext; 00301 00302 if (esStr->rv == SCARD_S_SUCCESS) 00303 esStr->rv = 00304 MSGAddContext(esStr->hContext, dwContextIndex); 00305 break; 00306 00307 case SCARD_RELEASE_CONTEXT: 00308 reStr = ((release_struct *) msgStruct->data); 00309 reStr->rv = SCardReleaseContext(reStr->hContext); 00310 00311 if (reStr->rv == SCARD_S_SUCCESS) 00312 reStr->rv = 00313 MSGRemoveContext(reStr->hContext, dwContextIndex); 00314 00315 break; 00316 00317 case SCARD_CONNECT: 00318 coStr = ((connect_struct *) msgStruct->data); 00319 00320 hCard = coStr->hCard; 00321 dwActiveProtocol = coStr->dwActiveProtocol; 00322 00323 coStr->rv = SCardConnect(coStr->hContext, coStr->szReader, 00324 coStr->dwShareMode, coStr->dwPreferredProtocols, 00325 &hCard, &dwActiveProtocol); 00326 00327 coStr->hCard = hCard; 00328 coStr->dwActiveProtocol = dwActiveProtocol; 00329 00330 if (coStr->rv == SCARD_S_SUCCESS) 00331 coStr->rv = 00332 MSGAddHandle(coStr->hContext, coStr->hCard, dwContextIndex); 00333 00334 break; 00335 00336 case SCARD_RECONNECT: 00337 rcStr = ((reconnect_struct *) msgStruct->data); 00338 rv = MSGCheckHandleAssociation(rcStr->hCard, dwContextIndex); 00339 if (rv != 0) return rv; 00340 00341 rcStr->rv = SCardReconnect(rcStr->hCard, rcStr->dwShareMode, 00342 rcStr->dwPreferredProtocols, 00343 rcStr->dwInitialization, &dwActiveProtocol); 00344 rcStr->dwActiveProtocol = dwActiveProtocol; 00345 break; 00346 00347 case SCARD_DISCONNECT: 00348 diStr = ((disconnect_struct *) msgStruct->data); 00349 rv = MSGCheckHandleAssociation(diStr->hCard, dwContextIndex); 00350 if (rv != 0) return rv; 00351 diStr->rv = SCardDisconnect(diStr->hCard, diStr->dwDisposition); 00352 00353 if (diStr->rv == SCARD_S_SUCCESS) 00354 diStr->rv = 00355 MSGRemoveHandle(diStr->hCard, dwContextIndex); 00356 break; 00357 00358 case SCARD_BEGIN_TRANSACTION: 00359 beStr = ((begin_struct *) msgStruct->data); 00360 rv = MSGCheckHandleAssociation(beStr->hCard, dwContextIndex); 00361 if (rv != 0) return rv; 00362 beStr->rv = SCardBeginTransaction(beStr->hCard); 00363 break; 00364 00365 case SCARD_END_TRANSACTION: 00366 enStr = ((end_struct *) msgStruct->data); 00367 rv = MSGCheckHandleAssociation(enStr->hCard, dwContextIndex); 00368 if (rv != 0) return rv; 00369 enStr->rv = 00370 SCardEndTransaction(enStr->hCard, enStr->dwDisposition); 00371 break; 00372 00373 case SCARD_CANCEL_TRANSACTION: 00374 caStr = ((cancel_struct *) msgStruct->data); 00375 rv = MSGCheckHandleAssociation(caStr->hCard, dwContextIndex); 00376 if (rv != 0) return rv; 00377 caStr->rv = SCardCancelTransaction(caStr->hCard); 00378 break; 00379 00380 case SCARD_STATUS: 00381 stStr = ((status_struct *) msgStruct->data); 00382 rv = MSGCheckHandleAssociation(stStr->hCard, dwContextIndex); 00383 if (rv != 0) return rv; 00384 00385 cchReaderLen = stStr->pcchReaderLen; 00386 dwState = stStr->dwState; 00387 dwProtocol = stStr->dwProtocol; 00388 cbAtrLen = stStr->pcbAtrLen; 00389 00390 /* avoids buffer overflow */ 00391 if ((cchReaderLen > sizeof(stStr->mszReaderNames)) 00392 || (cbAtrLen > sizeof(stStr->pbAtr))) 00393 { 00394 stStr->rv = SCARD_E_INSUFFICIENT_BUFFER ; 00395 break; 00396 } 00397 00398 stStr->rv = SCardStatus(stStr->hCard, stStr->mszReaderNames, 00399 &cchReaderLen, &dwState, 00400 &dwProtocol, stStr->pbAtr, &cbAtrLen); 00401 00402 stStr->pcchReaderLen = cchReaderLen; 00403 stStr->dwState = dwState; 00404 stStr->dwProtocol = dwProtocol; 00405 stStr->pcbAtrLen = cbAtrLen; 00406 break; 00407 00408 case SCARD_TRANSMIT: 00409 trStr = ((transmit_struct *) msgStruct->data); 00410 rv = MSGCheckHandleAssociation(trStr->hCard, dwContextIndex); 00411 if (rv != 0) return rv; 00412 00413 /* avoids buffer overflow */ 00414 if ((trStr->pcbRecvLength > sizeof(trStr->pbRecvBuffer)) 00415 || (trStr->cbSendLength > sizeof(trStr->pbSendBuffer))) 00416 { 00417 trStr->rv = SCARD_E_INSUFFICIENT_BUFFER ; 00418 break; 00419 } 00420 00421 ioSendPci.dwProtocol = trStr->ioSendPciProtocol; 00422 ioSendPci.cbPciLength = trStr->ioSendPciLength; 00423 ioRecvPci.dwProtocol = trStr->ioRecvPciProtocol; 00424 ioRecvPci.cbPciLength = trStr->ioRecvPciLength; 00425 cbRecvLength = trStr->pcbRecvLength; 00426 00427 trStr->rv = SCardTransmit(trStr->hCard, &ioSendPci, 00428 trStr->pbSendBuffer, trStr->cbSendLength, 00429 &ioRecvPci, trStr->pbRecvBuffer, 00430 &cbRecvLength); 00431 00432 trStr->ioSendPciProtocol = ioSendPci.dwProtocol; 00433 trStr->ioSendPciLength = ioSendPci.cbPciLength; 00434 trStr->ioRecvPciProtocol = ioRecvPci.dwProtocol; 00435 trStr->ioRecvPciLength = ioRecvPci.cbPciLength; 00436 trStr->pcbRecvLength = cbRecvLength; 00437 00438 break; 00439 00440 case SCARD_CONTROL: 00441 ctStr = ((control_struct *) msgStruct->data); 00442 rv = MSGCheckHandleAssociation(ctStr->hCard, dwContextIndex); 00443 if (rv != 0) return rv; 00444 00445 /* avoids buffer overflow */ 00446 if ((ctStr->cbRecvLength > sizeof(ctStr->pbRecvBuffer)) 00447 || (ctStr->cbSendLength > sizeof(ctStr->pbSendBuffer))) 00448 { 00449 ctStr->rv = SCARD_E_INSUFFICIENT_BUFFER; 00450 break; 00451 } 00452 00453 dwBytesReturned = ctStr->dwBytesReturned; 00454 00455 ctStr->rv = SCardControl(ctStr->hCard, ctStr->dwControlCode, 00456 ctStr->pbSendBuffer, ctStr->cbSendLength, 00457 ctStr->pbRecvBuffer, ctStr->cbRecvLength, 00458 &dwBytesReturned); 00459 00460 ctStr->dwBytesReturned = dwBytesReturned; 00461 00462 break; 00463 00464 case SCARD_GET_ATTRIB: 00465 gsStr = ((getset_struct *) msgStruct->data); 00466 rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex); 00467 if (rv != 0) return rv; 00468 00469 /* avoids buffer overflow */ 00470 if (gsStr->cbAttrLen > sizeof(gsStr->pbAttr)) 00471 { 00472 gsStr->rv = SCARD_E_INSUFFICIENT_BUFFER ; 00473 break; 00474 } 00475 00476 cbAttrLen = gsStr->cbAttrLen; 00477 00478 gsStr->rv = SCardGetAttrib(gsStr->hCard, gsStr->dwAttrId, 00479 gsStr->pbAttr, &cbAttrLen); 00480 00481 gsStr->cbAttrLen = cbAttrLen; 00482 00483 break; 00484 00485 case SCARD_SET_ATTRIB: 00486 gsStr = ((getset_struct *) msgStruct->data); 00487 rv = MSGCheckHandleAssociation(gsStr->hCard, dwContextIndex); 00488 if (rv != 0) return rv; 00489 00490 /* avoids buffer overflow */ 00491 if (gsStr->cbAttrLen <= sizeof(gsStr->pbAttr)) 00492 { 00493 gsStr->rv = SCARD_E_INSUFFICIENT_BUFFER ; 00494 break; 00495 } 00496 00497 gsStr->rv = SCardSetAttrib(gsStr->hCard, gsStr->dwAttrId, 00498 gsStr->pbAttr, gsStr->cbAttrLen); 00499 break; 00500 00501 case SCARD_TRANSMIT_EXTENDED: 00502 { 00503 transmit_struct_extended *treStr; 00504 unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED]; 00505 unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED]; 00506 00507 treStr = ((transmit_struct_extended *) msgStruct->data); 00508 rv = MSGCheckHandleAssociation(treStr->hCard, dwContextIndex); 00509 if (rv != 0) return rv; 00510 00511 /* avoids buffer overflow */ 00512 if ((treStr->size > sizeof(pbSendBuffer)) 00513 || (treStr->cbSendLength > sizeof(pbSendBuffer)) 00514 || (treStr->pcbRecvLength > sizeof(pbRecvBuffer))) 00515 { 00516 treStr->rv = SCARD_E_INSUFFICIENT_BUFFER; 00517 break; 00518 } 00519 00520 /* on more block to read? */ 00521 if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE) 00522 { 00523 /* copy the first APDU part */ 00524 memcpy(pbSendBuffer, treStr->data, 00525 PCSCLITE_MAX_MESSAGE_SIZE-offsetof(transmit_struct_extended, data)); 00526 00527 /* receive the second block */ 00528 rv = SHMMessageReceive( 00529 pbSendBuffer+PCSCLITE_MAX_MESSAGE_SIZE-offsetof(transmit_struct_extended, data), 00530 treStr->size - PCSCLITE_MAX_MESSAGE_SIZE, 00531 psContext[dwContextIndex].dwClientID, 00532 PCSCLITE_SERVER_ATTEMPTS); 00533 if (rv) 00534 Log1(PCSC_LOG_CRITICAL, "reception failed"); 00535 } 00536 else 00537 memcpy(pbSendBuffer, treStr->data, treStr->cbSendLength); 00538 00539 ioSendPci.dwProtocol = treStr->ioSendPciProtocol; 00540 ioSendPci.cbPciLength = treStr->ioSendPciLength; 00541 ioRecvPci.dwProtocol = treStr->ioRecvPciProtocol; 00542 ioRecvPci.cbPciLength = treStr->ioRecvPciLength; 00543 cbRecvLength = treStr->pcbRecvLength; 00544 00545 treStr->rv = SCardTransmit(treStr->hCard, &ioSendPci, 00546 pbSendBuffer, treStr->cbSendLength, 00547 &ioRecvPci, pbRecvBuffer, 00548 &cbRecvLength); 00549 00550 treStr->ioSendPciProtocol = ioSendPci.dwProtocol; 00551 treStr->ioSendPciLength = ioSendPci.cbPciLength; 00552 treStr->ioRecvPciProtocol = ioRecvPci.dwProtocol; 00553 treStr->ioRecvPciLength = ioRecvPci.cbPciLength; 00554 treStr->pcbRecvLength = cbRecvLength; 00555 00556 treStr->size = offsetof(transmit_struct_extended, data) + treStr->pcbRecvLength; 00557 if (treStr->size > PCSCLITE_MAX_MESSAGE_SIZE) 00558 { 00559 /* two blocks */ 00560 memcpy(treStr->data, pbRecvBuffer, PCSCLITE_MAX_MESSAGE_SIZE 00561 - offsetof(transmit_struct_extended, data)); 00562 00563 rv = SHMMessageSend(msgStruct, sizeof(*msgStruct), 00564 psContext[dwContextIndex].dwClientID, 00565 PCSCLITE_SERVER_ATTEMPTS); 00566 if (rv) 00567 Log1(PCSC_LOG_CRITICAL, "transmission failed"); 00568 00569 rv = SHMMessageSend(pbRecvBuffer + PCSCLITE_MAX_MESSAGE_SIZE 00570 - offsetof(transmit_struct_extended, data), 00571 treStr->size - PCSCLITE_MAX_MESSAGE_SIZE, 00572 psContext[dwContextIndex].dwClientID, 00573 PCSCLITE_SERVER_ATTEMPTS); 00574 if (rv) 00575 Log1(PCSC_LOG_CRITICAL, "transmission failed"); 00576 } 00577 else 00578 { 00579 /* one block only */ 00580 memcpy(treStr->data, pbRecvBuffer, treStr->pcbRecvLength); 00581 00582 rv = SHMMessageSend(msgStruct, sizeof(*msgStruct), 00583 psContext[dwContextIndex].dwClientID, 00584 PCSCLITE_SERVER_ATTEMPTS); 00585 if (rv) 00586 Log1(PCSC_LOG_CRITICAL, "transmission failed"); 00587 } 00588 } 00589 break; 00590 00591 case SCARD_CONTROL_EXTENDED: 00592 { 00593 control_struct_extended *cteStr; 00594 unsigned char pbSendBuffer[MAX_BUFFER_SIZE_EXTENDED]; 00595 unsigned char pbRecvBuffer[MAX_BUFFER_SIZE_EXTENDED]; 00596 00597 cteStr = ((control_struct_extended *) msgStruct->data); 00598 rv = MSGCheckHandleAssociation(cteStr->hCard, dwContextIndex); 00599 if (rv != 0) return rv; 00600 00601 /* avoids buffer overflow */ 00602 if ((cteStr->size > sizeof(pbSendBuffer)) 00603 || (cteStr->cbSendLength > sizeof(pbSendBuffer)) 00604 || (cteStr->cbRecvLength > sizeof(pbRecvBuffer))) 00605 { 00606 cteStr->rv = SCARD_E_INSUFFICIENT_BUFFER; 00607 break; 00608 } 00609 00610 /* on more block to read? */ 00611 if (cteStr->size > PCSCLITE_MAX_MESSAGE_SIZE) 00612 { 00613 /* copy the first data part */ 00614 memcpy(pbSendBuffer, cteStr->data, 00615 PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*cteStr)); 00616 00617 /* receive the second block */ 00618 rv = SHMMessageReceive( 00619 pbSendBuffer+PCSCLITE_MAX_MESSAGE_SIZE-sizeof(*cteStr), 00620 cteStr->size - PCSCLITE_MAX_MESSAGE_SIZE, 00621 psContext[dwContextIndex].dwClientID, 00622 PCSCLITE_SERVER_ATTEMPTS); 00623 if (rv) 00624 Log1(PCSC_LOG_CRITICAL, "reception failed"); 00625 } 00626 else 00627 memcpy(pbSendBuffer, cteStr->data, cteStr->cbSendLength); 00628 00629 dwBytesReturned = cteStr->dwBytesReturned; 00630 00631 cteStr->rv = SCardControl(cteStr->hCard, cteStr->dwControlCode, 00632 pbSendBuffer, cteStr->cbSendLength, 00633 pbRecvBuffer, cteStr->cbRecvLength, 00634 &dwBytesReturned); 00635 00636 cteStr->dwBytesReturned = dwBytesReturned; 00637 00638 cteStr->size = sizeof(*cteStr) + cteStr->dwBytesReturned; 00639 if (cteStr->size > PCSCLITE_MAX_MESSAGE_SIZE) 00640 { 00641 /* two blocks */ 00642 memcpy(cteStr->data, pbRecvBuffer, PCSCLITE_MAX_MESSAGE_SIZE 00643 - sizeof(*cteStr)); 00644 00645 rv = SHMMessageSend(msgStruct, sizeof(*msgStruct), 00646 psContext[dwContextIndex].dwClientID, 00647 PCSCLITE_SERVER_ATTEMPTS); 00648 if (rv) 00649 Log1(PCSC_LOG_CRITICAL, "transmission failed"); 00650 00651 rv = SHMMessageSend(pbRecvBuffer + PCSCLITE_MAX_MESSAGE_SIZE 00652 - sizeof(*cteStr), 00653 cteStr->size - PCSCLITE_MAX_MESSAGE_SIZE, 00654 psContext[dwContextIndex].dwClientID, 00655 PCSCLITE_SERVER_ATTEMPTS); 00656 if (rv) 00657 Log1(PCSC_LOG_CRITICAL, "transmission failed"); 00658 } 00659 else 00660 { 00661 /* one block only */ 00662 memcpy(cteStr->data, pbRecvBuffer, cteStr->dwBytesReturned); 00663 00664 rv = SHMMessageSend(msgStruct, sizeof(*msgStruct), 00665 psContext[dwContextIndex].dwClientID, 00666 PCSCLITE_SERVER_ATTEMPTS); 00667 if (rv) 00668 Log1(PCSC_LOG_CRITICAL, "transmission failed"); 00669 } 00670 } 00671 break; 00672 00673 default: 00674 Log2(PCSC_LOG_CRITICAL, "Unknown command: %d", msgStruct->command); 00675 return -1; 00676 } 00677 00678 return 0; 00679 } 00680 00681 static LONG MSGAddContext(SCARDCONTEXT hContext, DWORD dwContextIndex) 00682 { 00683 psContext[dwContextIndex].hContext = hContext; 00684 return SCARD_S_SUCCESS; 00685 } 00686 00687 static LONG MSGRemoveContext(SCARDCONTEXT hContext, DWORD dwContextIndex) 00688 { 00689 int i; 00690 LONG rv; 00691 00692 if (psContext[dwContextIndex].hContext == hContext) 00693 { 00694 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++) 00695 { 00696 /* 00697 * Disconnect each of these just in case 00698 */ 00699 00700 if (psContext[dwContextIndex].hCard[i] != 0) 00701 { 00702 PREADER_CONTEXT rContext = NULL; 00703 DWORD dwLockId; 00704 00705 /* 00706 * Unlock the sharing 00707 */ 00708 rv = RFReaderInfoById(psContext[dwContextIndex].hCard[i], 00709 &rContext); 00710 if (rv != SCARD_S_SUCCESS) 00711 return rv; 00712 00713 dwLockId = rContext->dwLockId; 00714 rContext->dwLockId = 0; 00715 00716 if (psContext[dwContextIndex].hCard[i] != dwLockId) 00717 { 00718 /* 00719 * if the card is locked by someone else we do not reset it 00720 * and simulate a card removal 00721 */ 00722 rv = SCARD_W_REMOVED_CARD; 00723 } 00724 else 00725 { 00726 /* 00727 * We will use SCardStatus to see if the card has been 00728 * reset there is no need to reset each time 00729 * Disconnect is called 00730 */ 00731 rv = SCardStatus(psContext[dwContextIndex].hCard[i], NULL, 00732 NULL, NULL, NULL, NULL, NULL); 00733 } 00734 00735 if (rv == SCARD_W_RESET_CARD || rv == SCARD_W_REMOVED_CARD) 00736 (void)SCardDisconnect(psContext[dwContextIndex].hCard[i], 00737 SCARD_LEAVE_CARD); 00738 else 00739 (void)SCardDisconnect(psContext[dwContextIndex].hCard[i], 00740 SCARD_RESET_CARD); 00741 00742 psContext[dwContextIndex].hCard[i] = 0; 00743 } 00744 } 00745 00746 psContext[dwContextIndex].hContext = 0; 00747 return SCARD_S_SUCCESS; 00748 } 00749 00750 return SCARD_E_INVALID_VALUE; 00751 } 00752 00753 static LONG MSGAddHandle(SCARDCONTEXT hContext, SCARDHANDLE hCard, 00754 DWORD dwContextIndex) 00755 { 00756 int i; 00757 00758 if (psContext[dwContextIndex].hContext == hContext) 00759 { 00760 00761 /* 00762 * Find an empty spot to put the hCard value 00763 */ 00764 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++) 00765 { 00766 if (psContext[dwContextIndex].hCard[i] == 0) 00767 { 00768 psContext[dwContextIndex].hCard[i] = hCard; 00769 break; 00770 } 00771 } 00772 00773 if (i == PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS) 00774 { 00775 return SCARD_F_INTERNAL_ERROR; 00776 } else 00777 { 00778 return SCARD_S_SUCCESS; 00779 } 00780 00781 } 00782 00783 return SCARD_E_INVALID_VALUE; 00784 } 00785 00786 static LONG MSGRemoveHandle(SCARDHANDLE hCard, DWORD dwContextIndex) 00787 { 00788 int i; 00789 00790 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++) 00791 { 00792 if (psContext[dwContextIndex].hCard[i] == hCard) 00793 { 00794 psContext[dwContextIndex].hCard[i] = 0; 00795 return SCARD_S_SUCCESS; 00796 } 00797 } 00798 00799 return SCARD_E_INVALID_VALUE; 00800 } 00801 00802 00803 static LONG MSGCheckHandleAssociation(SCARDHANDLE hCard, DWORD dwContextIndex) 00804 { 00805 int i; 00806 00807 for (i = 0; i < PCSCLITE_MAX_APPLICATION_CONTEXT_CHANNELS; i++) 00808 { 00809 if (psContext[dwContextIndex].hCard[i] == hCard) 00810 { 00811 return 0; 00812 } 00813 } 00814 00815 /* Must be a rogue client, debug log and sleep a couple of seconds */ 00816 Log1(PCSC_LOG_ERROR, "Client failed to authenticate"); 00817 (void)SYS_Sleep(2); 00818 00819 return -1; 00820 } 00821 00822 static LONG MSGCleanupClient(DWORD dwContextIndex) 00823 { 00824 if (psContext[dwContextIndex].hContext != 0) 00825 { 00826 (void)SCardReleaseContext(psContext[dwContextIndex].hContext); 00827 (void)MSGRemoveContext(psContext[dwContextIndex].hContext, 00828 dwContextIndex); 00829 } 00830 00831 psContext[dwContextIndex].dwClientID = 0; 00832 psContext[dwContextIndex].protocol_major = 0; 00833 psContext[dwContextIndex].protocol_minor = 0; 00834 00835 return 0; 00836 }