pcsc-lite 1.6.4
|
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 4951 2010-05-18 09:35:09Z 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 static 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 CleanupSharedSegment(commonSocket, PCSCLITE_CSOCK_NAME); 00123 return -1; 00124 } 00125 00126 if (listen(commonSocket, 1) < 0) 00127 { 00128 Log2(PCSC_LOG_CRITICAL, "Unable to listen common socket: %s", 00129 strerror(errno)); 00130 CleanupSharedSegment(commonSocket, PCSCLITE_CSOCK_NAME); 00131 return -1; 00132 } 00133 00134 /* 00135 * Chmod the public entry channel 00136 */ 00137 (void)chmod(PCSCLITE_CSOCK_NAME, S_IRWXO | S_IRWXG | S_IRWXU); 00138 00139 return 0; 00140 } 00141 00155 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) 00156 #define DO_TIMEOUT 00157 #endif 00158 INTERNAL int32_t ProcessEventsServer(uint32_t *pdwClientID) 00159 { 00160 fd_set read_fd; 00161 int selret; 00162 #ifdef DO_TIMEOUT 00163 struct timeval tv; 00164 00165 tv.tv_sec = 1; 00166 tv.tv_usec = 0; 00167 #endif 00168 00169 FD_ZERO(&read_fd); 00170 00171 /* 00172 * Set up the bit masks for select 00173 */ 00174 FD_SET(commonSocket, &read_fd); 00175 00176 selret = select(commonSocket + 1, &read_fd, (fd_set *) NULL, 00177 (fd_set *) NULL, 00178 #ifdef DO_TIMEOUT 00179 &tv 00180 #else 00181 NULL 00182 #endif 00183 ); 00184 00185 if (selret < 0) 00186 { 00187 if (EINTR == errno) 00188 return -2; 00189 00190 Log2(PCSC_LOG_CRITICAL, "Select returns with failure: %s", 00191 strerror(errno)); 00192 return -1; 00193 } 00194 00195 if (selret == 0) 00196 /* timeout. On *BSD only */ 00197 return 2; 00198 00199 /* 00200 * A common pipe packet has arrived - it could be a new application 00201 */ 00202 if (FD_ISSET(commonSocket, &read_fd)) 00203 { 00204 Log1(PCSC_LOG_DEBUG, "Common channel packet arrival"); 00205 if (ProcessCommonChannelRequest(pdwClientID) == -1) 00206 { 00207 Log2(PCSC_LOG_ERROR, 00208 "error in ProcessCommonChannelRequest: %d", *pdwClientID); 00209 return -1; 00210 } 00211 } 00212 else 00213 return -1; 00214 00215 Log2(PCSC_LOG_DEBUG, 00216 "ProcessCommonChannelRequest detects: %d", *pdwClientID); 00217 00218 return 0; 00219 } 00220