pcsc-lite
1.8.3
|
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 6043 2011-10-15 16:44:08Z 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 "sd-daemon.h" 00043 #include "winscard.h" 00044 #include "debuglog.h" 00045 #include "winscard_msg.h" 00046 00050 static int commonSocket = 0; 00051 extern char AraKiri; 00052 00064 static int ProcessCommonChannelRequest(/*@out@*/ uint32_t *pdwClientID) 00065 { 00066 socklen_t clnt_len; 00067 int new_sock; 00068 struct sockaddr_un clnt_addr; 00069 00070 clnt_len = sizeof(clnt_addr); 00071 00072 if ((new_sock = accept(commonSocket, (struct sockaddr *) &clnt_addr, 00073 &clnt_len)) < 0) 00074 { 00075 Log2(PCSC_LOG_CRITICAL, "Accept on common socket: %s", 00076 strerror(errno)); 00077 return -1; 00078 } 00079 00080 *pdwClientID = new_sock; 00081 00082 return 0; 00083 } 00084 00099 INTERNAL int32_t InitializeSocket(void) 00100 { 00101 union 00102 { 00103 struct sockaddr sa; 00104 struct sockaddr_un un; 00105 } sa; 00106 00107 /* 00108 * Create the common shared connection socket 00109 */ 00110 if ((commonSocket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) 00111 { 00112 Log2(PCSC_LOG_CRITICAL, "Unable to create common socket: %s", 00113 strerror(errno)); 00114 return -1; 00115 } 00116 00117 memset(&sa, 0, sizeof sa); 00118 sa.un.sun_family = AF_UNIX; 00119 strncpy(sa.un.sun_path, PCSCLITE_CSOCK_NAME, sizeof sa.un.sun_path); 00120 (void)remove(PCSCLITE_CSOCK_NAME); 00121 00122 if (bind(commonSocket, &sa.sa, sizeof sa) < 0) 00123 { 00124 Log2(PCSC_LOG_CRITICAL, "Unable to bind common socket: %s", 00125 strerror(errno)); 00126 return -1; 00127 } 00128 00129 if (listen(commonSocket, 1) < 0) 00130 { 00131 Log2(PCSC_LOG_CRITICAL, "Unable to listen common socket: %s", 00132 strerror(errno)); 00133 return -1; 00134 } 00135 00136 /* 00137 * Chmod the public entry channel 00138 */ 00139 (void)chmod(PCSCLITE_CSOCK_NAME, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 00140 00141 return 0; 00142 } 00143 00156 INTERNAL int32_t ListenExistingSocket(int fd) 00157 { 00158 if (!sd_is_socket(fd, AF_UNIX, SOCK_STREAM, -1)) 00159 { 00160 Log1(PCSC_LOG_CRITICAL, "Passed FD is not an UNIX socket"); 00161 return -1; 00162 } 00163 00164 commonSocket = fd; 00165 return 0; 00166 } 00167 00181 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) 00182 #define DO_TIMEOUT 00183 #endif 00184 INTERNAL int32_t ProcessEventsServer(uint32_t *pdwClientID) 00185 { 00186 fd_set read_fd; 00187 int selret; 00188 #ifdef DO_TIMEOUT 00189 struct timeval tv; 00190 00191 tv.tv_sec = 1; 00192 tv.tv_usec = 0; 00193 #endif 00194 00195 FD_ZERO(&read_fd); 00196 00197 /* 00198 * Set up the bit masks for select 00199 */ 00200 FD_SET(commonSocket, &read_fd); 00201 00202 selret = select(commonSocket + 1, &read_fd, (fd_set *) NULL, 00203 (fd_set *) NULL, 00204 #ifdef DO_TIMEOUT 00205 &tv 00206 #else 00207 NULL 00208 #endif 00209 ); 00210 00211 if (selret < 0) 00212 { 00213 if (EINTR == errno) 00214 return -2; 00215 00216 Log2(PCSC_LOG_CRITICAL, "Select returns with failure: %s", 00217 strerror(errno)); 00218 return -1; 00219 } 00220 00221 if (selret == 0) 00222 /* timeout. On *BSD only */ 00223 return 2; 00224 00225 /* 00226 * A common pipe packet has arrived - it could be a new application 00227 */ 00228 if (FD_ISSET(commonSocket, &read_fd)) 00229 { 00230 Log1(PCSC_LOG_DEBUG, "Common channel packet arrival"); 00231 if (ProcessCommonChannelRequest(pdwClientID) == -1) 00232 { 00233 Log2(PCSC_LOG_ERROR, 00234 "error in ProcessCommonChannelRequest: %d", *pdwClientID); 00235 return -1; 00236 } 00237 } 00238 else 00239 return -1; 00240 00241 Log2(PCSC_LOG_DEBUG, 00242 "ProcessCommonChannelRequest detects: %d", *pdwClientID); 00243 00244 return 0; 00245 } 00246