pcsc-lite 1.7.2

winscard_msg_srv.c

Go to the documentation of this file.
00001 /*
00002  * MUSCLE SmartCard Development ( http://www.linuxnet.com )
00003  *
00004  * Copyright (C) 2001-2004
00005  *  David Corcoran <corcoran@linuxnet.com>
00006  * Copyright (C) 2003-2004
00007  *  Damien Sauveron <damien.sauveron@labri.fr>
00008  * Copyright (C) 2002-2010
00009  *  Ludovic Rousseau <ludovic.rousseau@free.fr>
00010  *
00011  * $Id: winscard_msg_srv.c 5391 2010-11-08 14:53:02Z rousseau $
00012  */
00013 
00023 #include "config.h"
00024 #include <fcntl.h>
00025 #include <unistd.h>
00026 #include <sys/types.h>
00027 #include <sys/stat.h>
00028 #include <sys/socket.h>
00029 #include <sys/time.h>
00030 #include <sys/un.h>
00031 #include <sys/ioctl.h>
00032 #include <errno.h>
00033 #include <stdio.h>
00034 #include <time.h>
00035 #include <string.h>
00036 #ifdef HAVE_SYS_FILIO_H
00037 #include <sys/filio.h>
00038 #endif
00039 
00040 #include "misc.h"
00041 #include "pcscd.h"
00042 #include "winscard.h"
00043 #include "debuglog.h"
00044 #include "winscard_msg.h"
00045 
00049 static int commonSocket = 0;
00050 extern char AraKiri;
00051 
00063 static int ProcessCommonChannelRequest(/*@out@*/ uint32_t *pdwClientID)
00064 {
00065     socklen_t clnt_len;
00066     int new_sock;
00067     struct sockaddr_un clnt_addr;
00068 
00069     clnt_len = sizeof(clnt_addr);
00070 
00071     if ((new_sock = accept(commonSocket, (struct sockaddr *) &clnt_addr,
00072                 &clnt_len)) < 0)
00073     {
00074         Log2(PCSC_LOG_CRITICAL, "Accept on common socket: %s",
00075             strerror(errno));
00076         return -1;
00077     }
00078 
00079     *pdwClientID = new_sock;
00080 
00081     return 0;
00082 }
00083 
00098 INTERNAL int32_t InitializeSocket(void)
00099 {
00100     struct sockaddr_un serv_adr;
00101 
00102     /*
00103      * Create the common shared connection socket
00104      */
00105     if ((commonSocket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
00106     {
00107         Log2(PCSC_LOG_CRITICAL, "Unable to create common socket: %s",
00108             strerror(errno));
00109         return -1;
00110     }
00111 
00112     serv_adr.sun_family = AF_UNIX;
00113     strncpy(serv_adr.sun_path, PCSCLITE_CSOCK_NAME,
00114         sizeof(serv_adr.sun_path));
00115     (void)remove(PCSCLITE_CSOCK_NAME);
00116 
00117     if (bind(commonSocket, (struct sockaddr *) &serv_adr,
00118             sizeof(serv_adr.sun_family) + strlen(serv_adr.sun_path) + 1) < 0)
00119     {
00120         Log2(PCSC_LOG_CRITICAL, "Unable to bind common socket: %s",
00121             strerror(errno));
00122         return -1;
00123     }
00124 
00125     if (listen(commonSocket, 1) < 0)
00126     {
00127         Log2(PCSC_LOG_CRITICAL, "Unable to listen common socket: %s",
00128             strerror(errno));
00129         return -1;
00130     }
00131 
00132     /*
00133      * Chmod the public entry channel
00134      */
00135     (void)chmod(PCSCLITE_CSOCK_NAME, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
00136 
00137     return 0;
00138 }
00139 
00153 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
00154 #define DO_TIMEOUT
00155 #endif
00156 INTERNAL int32_t ProcessEventsServer(uint32_t *pdwClientID)
00157 {
00158     fd_set read_fd;
00159     int selret;
00160 #ifdef DO_TIMEOUT
00161     struct timeval tv;
00162 
00163     tv.tv_sec = 1;
00164     tv.tv_usec = 0;
00165 #endif
00166 
00167     FD_ZERO(&read_fd);
00168 
00169     /*
00170      * Set up the bit masks for select
00171      */
00172     FD_SET(commonSocket, &read_fd);
00173 
00174     selret = select(commonSocket + 1, &read_fd, (fd_set *) NULL,
00175         (fd_set *) NULL,
00176 #ifdef DO_TIMEOUT
00177         &tv
00178 #else
00179         NULL
00180 #endif
00181         );
00182 
00183     if (selret < 0)
00184     {
00185         if (EINTR == errno)
00186             return -2;
00187 
00188         Log2(PCSC_LOG_CRITICAL, "Select returns with failure: %s",
00189             strerror(errno));
00190         return -1;
00191     }
00192 
00193     if (selret == 0)
00194         /* timeout. On *BSD only */
00195         return 2;
00196 
00197     /*
00198      * A common pipe packet has arrived - it could be a new application
00199      */
00200     if (FD_ISSET(commonSocket, &read_fd))
00201     {
00202         Log1(PCSC_LOG_DEBUG, "Common channel packet arrival");
00203         if (ProcessCommonChannelRequest(pdwClientID) == -1)
00204         {
00205             Log2(PCSC_LOG_ERROR,
00206                 "error in ProcessCommonChannelRequest: %d", *pdwClientID);
00207             return -1;
00208         }
00209     }
00210     else
00211         return -1;
00212 
00213     Log2(PCSC_LOG_DEBUG,
00214         "ProcessCommonChannelRequest detects: %d", *pdwClientID);
00215 
00216     return 0;
00217 }
00218