Index: src/ifdhandler.c =================================================================== --- src/ifdhandler.c (révision 5108) +++ src/ifdhandler.c (copie de travail) @@ -27,6 +27,7 @@ #include "config.h" #include #include +#define SKIP_SCARDCONTROL_WRAP #include #include "ccid.h" @@ -479,6 +480,8 @@ EXTERNAL RESPONSECODE IFDHGetCapabilitie #endif case TAG_IFD_SLOTS_NUMBER: + /* length is 0 on Mac OS X Tiger */ + *Length = 1; if (*Length >= 1) { *Length = 1; @@ -1098,6 +1101,10 @@ end: /* store used protocol for use by the secure commands (verify/change PIN) */ ccid_desc->cardProtocol = Protocol; +#ifdef IFDHANDLERv2 + get_ccid_slot(reader_index)->SetParametersCalled = TRUE; +#endif + return IFD_SUCCESS; } /* IFDHSetProtocolParameters */ @@ -1158,6 +1165,10 @@ EXTERNAL RESPONSECODE IFDHPowerICC(DWORD DEBUG_INFO4("action: %s, %s (lun: %X)", actions[Action-IFD_POWER_UP], CcidSlots[reader_index].readerName, Lun); +#ifdef IFDHANDLERv2 + /* recall SetProtocolParameter next time */ + get_ccid_slot(reader_index) -> SetParametersCalled = FALSE; +#endif switch (Action) { case IFD_POWER_DOWN: @@ -1180,8 +1191,25 @@ EXTERNAL RESPONSECODE IFDHPowerICC(DWORD t1_release(&(get_ccid_slot(reader_index) -> t1)); break; - case IFD_POWER_UP: case IFD_RESET: +#ifdef FAKE_CARD_CHANGED + /* send the command */ + if (IFD_SUCCESS != CmdPowerOff(reader_index)) + { + DEBUG_CRITICAL("PowerDown failed"); + return_value = IFD_ERROR_POWER_ACTION; + goto end; + } + + /* clear T=1 context */ + t1_release(&(get_ccid_slot(reader_index) -> t1)); + + get_ccid_slot(reader_index)->FakeCardChanged = TRUE; + DEBUG_INFO("Card movement faked"); + break; +#endif + + case IFD_POWER_UP: /* save the current read timeout computed from card capabilities */ ccid_descriptor = get_ccid_descriptor(reader_index); oldReadTimeout = ccid_descriptor->readTimeout; @@ -1287,6 +1315,46 @@ EXTERNAL RESPONSECODE IFDHTransmitToICC( DEBUG_INFO3("%s (lun: %X)", CcidSlots[reader_index].readerName, Lun); + /* Mac OS X (pre Leopard) pcsc-lite is too old (version 1.1.2) to call + * IFDHSetProtocolParameters() correctly. + * Some problem occurs when SCardConnect is used with default protocol + * parameters (SCARD_PROTOCOL_T0 or SCARD_PROTOCOL_T1). In this case + * the daemon do not call IFDHSetProtocolParameters(). So we decide, + * in this case only, to configure the smart card reader with the + * default protocol defined in ATR and without PPS. + */ + +#ifdef IFDHANDLERv2 + { + CcidDesc *ccid_slot; + + /* Get ccid params */ + ccid_slot = get_ccid_slot(reader_index); + + if(! ccid_slot->SetParametersCalled) + { + ATR_t atr; + int default_protocol; + + memset(&atr, 0, sizeof(atr)); + + /* Get ATR of the card */ + ATR_InitFromArray(&atr, ccid_slot->pcATRBuffer, + ccid_slot->nATRLength); + + ATR_GetDefaultProtocol(&atr, &default_protocol); + + DEBUG_INFO2("The default protocol is: T=%d", default_protocol); + + return_value = IFDHSetProtocolParameters(Lun, + (DWORD)(default_protocol+1), 0, 0, 0, 0); + + if (return_value != IFD_SUCCESS) + return return_value; + } + } +#endif + rx_length = *RxLength; return_value = CmdXfrBlock(reader_index, TxLength, TxBuffer, &rx_length, RxBuffer, SendPci.Protocol); @@ -1299,9 +1367,15 @@ EXTERNAL RESPONSECODE IFDHTransmitToICC( } /* IFDHTransmitToICC */ -EXTERNAL RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode, +#ifdef IFDHANDLERv2 + +EXTERNAL RESPONSECODE IFDHControl_v3(DWORD Lun, DWORD dwControlCode, PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, - PDWORD pdwBytesReturned) + PDWORD pdwBytesReturned); + +EXTERNAL RESPONSECODE IFDHControl(DWORD Lun, + PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, + PDWORD pdwBytesReturnedpdwBytesReturned) { /* * This function performs a data exchange with the reader (not the @@ -1317,6 +1391,23 @@ EXTERNAL RESPONSECODE IFDHControl(DWORD * * Notes: RxLength should be zero on error. */ + DWORD dwControlCode; + + dwControlCode = *((uint32_t *)TxBuffer); + return IFDHControl_v3(Lun, dwControlCode, TxBuffer+sizeof(dwControlCode), + TxLength-sizeof(dwControlCode), RxBuffer, + *pdwBytesReturnedpdwBytesReturned, pdwBytesReturnedpdwBytesReturned); +} + +/* rename the real IFDHControl so we can use it in the old IFDHControl */ +#define IFDHControl IFDHControl_v3 + +#endif + +EXTERNAL RESPONSECODE IFDHControl(DWORD Lun, DWORD dwControlCode, + PUCHAR TxBuffer, DWORD TxLength, PUCHAR RxBuffer, DWORD RxLength, + PDWORD pdwBytesReturned) +{ RESPONSECODE return_value = IFD_ERROR_NOT_SUPPORTED; int reader_index; _ccid_descriptor *ccid_descriptor; @@ -1597,8 +1688,22 @@ EXTERNAL RESPONSECODE IFDHICCPresence(DW _ccid_descriptor *ccid_descriptor; unsigned int oldReadTimeout; - if (-1 == (reader_index = LunToReaderIndex(Lun))) - return IFD_COMMUNICATION_ERROR; + reader_index = LunToReaderIndex(Lun); + /* On Mac OS X Tiger pcsc-lite does not call IFDHCreateChannel() + * for the other slots of a multi-slot device. Instead it starts + * the polling thread immediatly on the other slots. */ + if (-1 == reader_index) + { + /* pcscd may try to poll the second "slot" of a composite device + * so we try to open it first */ + return_value = IFDHCreateChannel(Lun, 0); + if (IFD_SUCCESS != return_value) + return return_value; + + /* get the reader_index associated to our newly opened device */ + if (-1 == (reader_index = LunToReaderIndex(Lun))) + return IFD_COMMUNICATION_ERROR; + } DEBUG_PERIODIC3("%s (lun: %X)", CcidSlots[reader_index].readerName, Lun); @@ -1641,6 +1746,17 @@ EXTERNAL RESPONSECODE IFDHICCPresence(DW break; case CCID_ICC_PRESENT_INACTIVE: +#ifdef FAKE_CARD_CHANGED + if (get_ccid_slot(reader_index)->FakeCardChanged) + { + DEBUG_INFO("Card movement faked"); + + get_ccid_slot(reader_index)->FakeCardChanged = FALSE; + CcidSlots[reader_index].bPowerFlags = POWERFLAGS_RAZ; + return_value = IFD_ICC_NOT_PRESENT; + } + else +#endif if ((CcidSlots[reader_index].bPowerFlags == POWERFLAGS_RAZ) || (CcidSlots[reader_index].bPowerFlags & MASK_POWERFLAGS_PDWN)) /* the card was previously absent */ Index: src/commands.c =================================================================== --- src/commands.c (révision 5108) +++ src/commands.c (copie de travail) @@ -27,6 +27,8 @@ #include #include #include +/* do not redefine SCardControl_wrap() in reader.h */ +#define SKIP_SCARDCONTROL_WRAP #include #include "misc.h" Index: src/ccid.c =================================================================== --- src/ccid.c (révision 5108) +++ src/ccid.c (copie de travail) @@ -24,6 +24,7 @@ #include #include #include +#include #include #include Index: src/create_Info_plist.pl =================================================================== --- src/create_Info_plist.pl (révision 5108) +++ src/create_Info_plist.pl (copie de travail) @@ -20,6 +20,10 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301 USA. +# This version is designed for an old pcscd that does not support the +# extension for describing readers. +# only one reader must be present in supported_readers.txt + use warnings; use strict; use Getopt::Long; @@ -57,6 +61,9 @@ while () next if (m/^$/); chomp; + + die "\033[31mOnly one reader must be present in $ARGV[0]\033[0m\n" if (defined($manuf)); + ($manuf, $product, $name) = split /:/; # print "m: $manuf, p: $product, n: $name\n"; push @manuf, $manuf; @@ -73,6 +80,9 @@ open IN, "< $ARGV[1]" or die "Can't open while () { + # skip the array lines + next if (m/array/); + if (m/MAGIC_VENDOR/) { print @manuf; Index: src/defs.h =================================================================== --- src/defs.h (révision 5108) +++ src/defs.h (copie de travail) @@ -37,6 +37,10 @@ typedef struct CCID_DESC * Card state */ UCHAR bPowerFlags; + UCHAR SetParametersCalled; +#ifdef FAKE_CARD_CHANGED + UCHAR FakeCardChanged; +#endif /* * T=1 Protocol context Index: src/Info.plist.src =================================================================== --- src/Info.plist.src (révision 5108) +++ src/Info.plist.src (copie de travail) @@ -35,7 +35,7 @@ 0x00000001 ifdLogLevel - 0x0003 + 0x000f