pcsc-lite 1.7.2
|
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