pcsc-lite  1.9.5
winscard_msg_srv.c
Go to the documentation of this file.
1 /*
2  * MUSCLE SmartCard Development ( https://pcsclite.apdu.fr/ )
3  *
4  * Copyright (C) 2001-2004
5  * David Corcoran <corcoran@musclecard.com>
6  * Copyright (C) 2003-2004
7  * Damien Sauveron <damien.sauveron@labri.fr>
8  * Copyright (C) 2002-2010
9  * Ludovic Rousseau <ludovic.rousseau@free.fr>
10  *
11 Redistribution and use in source and binary forms, with or without
12 modification, are permitted provided that the following conditions
13 are met:
14 
15 1. Redistributions of source code must retain the above copyright
16  notice, this list of conditions and the following disclaimer.
17 2. Redistributions in binary form must reproduce the above copyright
18  notice, this list of conditions and the following disclaimer in the
19  documentation and/or other materials provided with the distribution.
20 3. The name of the author may not be used to endorse or promote products
21  derived from this software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
44 #include "config.h"
45 #include <fcntl.h>
46 #include <unistd.h>
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include <sys/socket.h>
50 #include <sys/time.h>
51 #include <sys/un.h>
52 #include <sys/ioctl.h>
53 #include <errno.h>
54 #include <stdio.h>
55 #include <time.h>
56 #include <string.h>
57 #ifdef HAVE_SYS_FILIO_H
58 #include <sys/filio.h>
59 #endif
60 #ifdef USE_LIBSYSTEMD
61 #include <systemd/sd-daemon.h>
62 #endif
63 
64 #include "misc.h"
65 #include "pcscd.h"
66 #include "winscard.h"
67 #include "debuglog.h"
68 #include "winscard_msg.h"
69 
73 static int commonSocket = 0;
74 extern char AraKiri;
75 
87 static int ProcessCommonChannelRequest(/*@out@*/ uint32_t *pdwClientID)
88 {
89  socklen_t clnt_len;
90  int new_sock;
91  struct sockaddr_un clnt_addr;
92 
93  clnt_len = sizeof(clnt_addr);
94 
95  if ((new_sock = accept(commonSocket, (struct sockaddr *) &clnt_addr,
96  &clnt_len)) < 0)
97  {
98  Log2(PCSC_LOG_CRITICAL, "Accept on common socket: %s",
99  strerror(errno));
100  return -1;
101  }
102 
103  *pdwClientID = new_sock;
104 
105  return 0;
106 }
107 
123 INTERNAL int32_t InitializeSocket(void)
124 {
125  union
126  {
127  struct sockaddr sa;
128  struct sockaddr_un un;
129  } sa;
130 
131  /*
132  * Create the common shared connection socket
133  */
134  if ((commonSocket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
135  {
136  Log2(PCSC_LOG_CRITICAL, "Unable to create common socket: %s",
137  strerror(errno));
138  return -1;
139  }
140 
141  memset(&sa, 0, sizeof sa);
142  sa.un.sun_family = AF_UNIX;
143  strncpy(sa.un.sun_path, PCSCLITE_CSOCK_NAME, sizeof sa.un.sun_path);
144  (void)remove(PCSCLITE_CSOCK_NAME);
145 
146  if (bind(commonSocket, &sa.sa, sizeof sa) < 0)
147  {
148  Log2(PCSC_LOG_CRITICAL, "Unable to bind common socket: %s",
149  strerror(errno));
150  return -1;
151  }
152 
153  if (listen(commonSocket, 1) < 0)
154  {
155  Log2(PCSC_LOG_CRITICAL, "Unable to listen common socket: %s",
156  strerror(errno));
157  return -1;
158  }
159 
160  /*
161  * Chmod the public entry channel
162  */
163  (void)chmod(PCSCLITE_CSOCK_NAME, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
164 
165  return 0;
166 }
167 
168 #ifdef USE_LIBSYSTEMD
181 INTERNAL int32_t ListenExistingSocket(int fd)
182 {
183  if (!sd_is_socket(fd, AF_UNIX, SOCK_STREAM, -1))
184  {
185  Log1(PCSC_LOG_CRITICAL, "Passed FD is not an UNIX socket");
186  return -1;
187  }
188 
189  commonSocket = fd;
190  return 0;
191 }
192 #endif
193 
207 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
208 #define DO_TIMEOUT
209 #endif
210 INTERNAL int32_t ProcessEventsServer(uint32_t *pdwClientID)
211 {
212  fd_set read_fd;
213  int selret;
214 #ifdef DO_TIMEOUT
215  struct timeval tv;
216 
217  tv.tv_sec = 1;
218  tv.tv_usec = 0;
219 #endif
220 
221  FD_ZERO(&read_fd);
222 
223  /*
224  * Set up the bit masks for select
225  */
226  FD_SET(commonSocket, &read_fd);
227 
228  selret = select(commonSocket + 1, &read_fd, (fd_set *) NULL,
229  (fd_set *) NULL,
230 #ifdef DO_TIMEOUT
231  &tv
232 #else
233  NULL
234 #endif
235  );
236 
237  if (selret < 0)
238  {
239  if (EINTR == errno)
240  return -2;
241 
242  Log2(PCSC_LOG_CRITICAL, "Select returns with failure: %s",
243  strerror(errno));
244  return -1;
245  }
246 
247  if (selret == 0)
248  /* timeout. On *BSD only */
249  return 2;
250 
251  /*
252  * A common pipe packet has arrived - it could be a new application
253  */
254  if (FD_ISSET(commonSocket, &read_fd))
255  {
256  Log1(PCSC_LOG_DEBUG, "Common channel packet arrival");
257  if (ProcessCommonChannelRequest(pdwClientID) == -1)
258  {
259  Log2(PCSC_LOG_ERROR,
260  "error in ProcessCommonChannelRequest: %d", *pdwClientID);
261  return -1;
262  }
263  }
264  else
265  return -1;
266 
267  Log2(PCSC_LOG_DEBUG,
268  "ProcessCommonChannelRequest detects: %d", *pdwClientID);
269 
270  return 0;
271 }
272 
This handles debugging.
This keeps a list of defines for pcsc-lite.
This handles smart card reader communications.
This defines some structures and #defines to be used over the transport layer.
INTERNAL int32_t InitializeSocket(void)
Prepares the communication channel used by the server to talk to the clients.
INTERNAL int32_t ProcessEventsServer(uint32_t *pdwClientID)
Looks for messages sent by clients.
static int ProcessCommonChannelRequest(uint32_t *pdwClientID)
Accepts a Client connection.
static int commonSocket
Socket to a file, used for clients-server comminication.