[Pcsclite-muscle] Fail to detect smartcard from reconnected reader

Ludovic Rousseau ludovic.rousseau at gmail.com
Fri Jul 21 12:20:08 UTC 2017


Hello,

Please generate a pcscd trace as described at
http://pcsclite.alioth.debian.org/pcsclite.html#support

bye

Dr. Ludovic Rousseau


Le 21 juil. 2017 13:47, "Thomas Bajer" <thomas.bajer at physec.de> a écrit :

Hello,



I would like to report an error, which occurs, when using PCSC-lite for
smartcard detection in C. It causes the smartcard to remain undetected,
when the reader is disconnected. The current workaround is to restart
the PCSC deamon at the beginning.

In my application the removal of the reader is unavoidable, since I am
using a USB token, which acts as a combination of a reader and a smartcard.



Please have a look at the attached minimal example code. The program
checks, whether a reader an a card are available, then connects to the
smartcard. Afterwards, the smartcard is diconnected and the program
waits until the smartcard is no longer physically connected. This
process is being looped until the programm is aborted.



The code was linked with the newest stable release, 1.8.22-1.

The code is compiled and linked on a FreeBSD system running FreeBSD 10.3
(AMD64), the executable is then copied to a pfsense Box which also runs
FreeBSD 10.3 with the same pcscd version.



It would be great if a developer could look at this and commit a fix for
this message.



Below is the exampleReconnect.c example and the build command. Feel free
to play around with it and to make use of the defines at the beginning
of the code



Regards,

Thomas Bajer



/*

 * exampleReconnect.c

 *

 *  Created on: 20.07.2017

 *      Author: T. Bajer

 */





#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

//#include <usb.h>

#include <errno.h>

#include <stdint.h>

#ifdef __APPLE__

#include <PCSC/winscard.h>

#include <PCSC/wintypes.h>

#else

#include <winscard.h>

#endif





/*
############################################################
################################

 * #### BUILD COMMAND:
                  ####

 * #### gcc -o example exampleReconnect.c -I/usr/local/include/PCSC
-lpcsclite -lusb -Wall ####

 *
############################################################
################################
*/



/* Uncomment me for more details */

//#define SC_DEBUG



/* Uncomment me to make it work */

//#define HOTFIX





/*

 * Prototypes

 */

int connectToSmartcard( SCARDCONTEXT *hContext,

                        SCARDHANDLE *hCard,

                        LPTSTR *mszReaders);



void disconnectSmartcard(   SCARDCONTEXT *hContext,

                            SCARDHANDLE *hCard,

                            LPTSTR *mszReaders);



void waitForSmartcardConnect();



void waitForSmartcardDisconnect();





/*

 * MAIN function

 */

int main(int argc, char **argv)

{

                SCARDCONTEXT hContext;

                SCARDHANDLE hCard;

                LPTSTR mszReaders;



                printf("Smartcard detection started.\n");

                for(;;)

                {

                        printf("Waiting for smartcard connect...\n");



#ifdef HOTFIX

                        system("service pcscd restart");

#endif

                        waitForSmartcardConnect();

                        printf("Smartcard found.\n");



                        printf("Connecting to smartcard...\n");

                        if(connectToSmartcard(&hContext, &hCard,
&mszReaders) == 0)

                        {

                                printf("Connecting successful!\n");



                                /*

                                 *  Do SC stuff here

                                 */



                                printf("Disconnecting...\n");

                                disconnectSmartcard(&hContext, &hCard,
&mszReaders);

                                printf("Disconnected!\n");

                        }

                        else

                        {

                                printf("CONNECT FAILED!\n");

                        }



                        printf("Waiting for smartcard disconnect...\n");

                        waitForSmartcardDisconnect();

                        printf("Smartcard lost!\n");

                }



                return 0;

}





/*

 * Implementations

 */



int connectToSmartcard( SCARDCONTEXT *hContext,

                        SCARDHANDLE *hCard,

                        LPTSTR *mszReaders)

{

        LONG rv = 0;



        DWORD dwReaders, dwActiveProtocol ;



        // Init context

        printf("Establish context\n");

        rv = SCardEstablishContext( SCARD_SCOPE_SYSTEM,

                                NULL,

                                NULL, hContext);

        if (SCARD_S_SUCCESS != rv)

        {

                return -1;

        }



        // Get available smartcard readers

#ifdef SCARD_AUTOALLOCATE

        dwReaders = SCARD_AUTOALLOCATE;

        printf("List readers\n");

        rv = SCardListReaders(  *hContext,

                            NULL,

                            (LPTSTR)mszReaders,

                            &dwReaders);



        if (SCARD_S_SUCCESS != rv)

        {

                SCardReleaseContext(*hContext);

                return -1;

        }



#else

        printf("List readers\n");

        rv = SCardListReaders(  *hContext,

                            NULL,

                            NULL,

                            &dwReaders);

        if (SCARD_S_SUCCESS != rv)

        {

                SCardReleaseContext(*hContext);

                return -1;

        }

        printf("Allocate readers\n");

        mszReaders = calloc(dwReaders, sizeof(char));

        rv = SCardListReaders(  *hContext,

                            NULL,

                            *mszReaders,

                            &dwReaders );

        if(SCARD_S_SUCCESS != rv)

        {

                SCardFreeMemory( *hContext, mszReaders );

                SCardReleaseContext( *hContext );

                return -1;

        }



#endif



        printf( "Connect to card\n" );

        // Connect to smartcard

        rv = SCardConnect(  *hContext,

                        *mszReaders,

                        SCARD_SHARE_SHARED,

                        SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,

                        hCard,

                        &dwActiveProtocol );

        if (SCARD_S_SUCCESS != rv)

        {

                SCardFreeMemory( *hContext, *mszReaders );

                SCardReleaseContext( *hContext );

                return -1;

        }



        printf( "Smartcard connected!\n" );

        return 0;

}



void disconnectSmartcard(   SCARDCONTEXT *hContext,

                            SCARDHANDLE *hCard,

                            LPTSTR *mszReaders)

{

        printf("Disconnect card...\n");

        SCardDisconnect( *hCard, SCARD_LEAVE_CARD );



        printf("Free reader...\n");

        #ifdef SCARD_AUTOALLOCATE



        SCardFreeMemory( *hContext, *mszReaders );



        #else

        free( *mszReaders );

        #endif



        printf( "Release context...\n" );

        SCardReleaseContext( *hContext );

}





int checkSmartcard( SCARDCONTEXT *hContext,

                    SCARDHANDLE *hCard,

                    LPTSTR *mszReaders)

{

        LONG rv = 0;



        DWORD dwReaders, dwActiveProtocol;



        // Init context

#ifdef SC_DEBUG

        printf("Establishing SC context...\n");

#endif

        rv = SCardEstablishContext( SCARD_SCOPE_SYSTEM,

                                NULL,

                                NULL,

                                hContext);

        if (SCARD_S_SUCCESS != rv)

        {

#ifdef SC_DEBUG

                printf("ERROR: Establishing SC context!\n");



#endif

        }



                // Get available smartcard readers

#ifdef SCARD_AUTOALLOCATE

        if (SCARD_S_SUCCESS == rv)

        {

                dwReaders = SCARD_AUTOALLOCATE;



#ifdef SC_DEBUG

                printf("Listing SC readers...\n");

#endif



                rv = SCardListReaders( *hContext,

                                NULL,

                                (LPTSTR)mszReaders,

                                &dwReaders );

                if (SCARD_S_SUCCESS != rv)

                {

#ifdef SC_DEBUG

                        printf("ERROR: Listing SC readers!\n");

#endif

                        /* Max: this has to be given by value, not by
pointer! (even if it
doesn't make sense..) */

                        SCardReleaseContext(*hContext);

                }

        }

                #else

        if (SCARD_S_SUCCESS == rv)

        {

#ifdef SC_DEBUG

                printf("Listing SC readers...\n");

#endif

                rv = SCardListReaders(  *hContext,

                                NULL,

                                NULL,

                                &dwReaders);

                if (SCARD_S_SUCCESS != rv)

                {

#ifdef SC_DEBUG

                        printf("ERROR: Listing SC readers!\n");

#endif

                        SCardReleaseContext( *hContext );

                }

        }

        if (SCARD_S_SUCCESS == rv)

        {



#ifdef SC_DEBUG

                printf( "Listing SC readers...\n" );

#endif

                mszReaders = calloc( dwReaders, sizeof(char) );

                rv = SCardListReaders( *hContext,

                                NULL,

                                *mszReaders,

                                &dwReaders );

                if(SCARD_S_SUCCESS != rv)

                {

#ifdef SC_DEBUG

                        printf( "ERROR: Listing SC readers!\n" );

#endif

                        SCardFreeMemory( *hContext, *mszReaders );

                        SCardReleaseContext( *hContext );

                }

        }

                #endif

        if (SCARD_S_SUCCESS == rv)

        {



#ifdef SC_DEBUG

                printf( "Connecting to SC...\n" );

#endif

                rv = SCardConnect(  *hContext,

                            *mszReaders,

                            SCARD_SHARE_SHARED,

                            SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1,

                            hCard,

                            &dwActiveProtocol);

                if (SCARD_S_SUCCESS != rv)

                {

#ifdef SC_DEBUG

                        printf("ERROR: Connecting to SC!\n");

#endif

                }

        }

        SCardFreeMemory(*hContext, *mszReaders);

        SCardReleaseContext(*hContext);



        fflush(stdout);

        return rv;

}



void waitForSmartcardConnect()

{

        SCARDCONTEXT hContext;

        SCARDHANDLE hCard;

        LPTSTR mszReaders;



        while(checkSmartcard(&hContext, &hCard, &mszReaders) != 0)

        {

                sleep(1);

        }

}



void waitForSmartcardDisconnect()

{

        SCARDCONTEXT hContext;

        SCARDHANDLE hCard;

        LPTSTR mszReaders;



        while(checkSmartcard(&hContext, &hCard, &mszReaders) == 0)

        {

                sleep(1);

        }

}

_______________________________________________
Pcsclite-muscle mailing list
Pcsclite-muscle at lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pcsclite-muscle
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.alioth.debian.org/pipermail/pcsclite-muscle/attachments/20170721/72767078/attachment-0001.html>


More information about the Pcsclite-muscle mailing list