pcsc-lite  2.5.0
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-2023
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 USE_LIBSYSTEMD
58 #include <systemd/sd-daemon.h>
59 #endif
60 
61 #include "misc.h"
62 #include "pcscd.h"
63 #include "winscard.h"
64 #include "debuglog.h"
65 #include "winscard_msg.h"
66 
70 static int commonSocket = 0;
71 
83 static int ProcessCommonChannelRequest(/*@out@*/ uint32_t *pdwClientID)
84 {
85  socklen_t clnt_len;
86  int new_sock;
87  struct sockaddr_un clnt_addr;
88 
89  clnt_len = sizeof(clnt_addr);
90 
91  if ((new_sock = accept(commonSocket, (struct sockaddr *) &clnt_addr,
92  &clnt_len)) < 0)
93  {
94  Log2(PCSC_LOG_CRITICAL, "Accept on common socket: %s",
95  strerror(errno));
96  return -1;
97  }
98 
99  *pdwClientID = new_sock;
100 
101  return 0;
102 }
103 
119 INTERNAL int32_t InitializeSocket(void)
120 {
121  union
122  {
123  struct sockaddr sa;
124  struct sockaddr_un un;
125  } sa;
126 
127  /*
128  * Create the common shared connection socket
129  */
130  if ((commonSocket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
131  {
132  Log2(PCSC_LOG_CRITICAL, "Unable to create common socket: %s",
133  strerror(errno));
134  return -1;
135  }
136 
137  memset(&sa, 0, sizeof sa);
138  sa.un.sun_family = AF_UNIX;
139  strncpy(sa.un.sun_path, PCSCLITE_CSOCK_NAME, sizeof sa.un.sun_path);
140  (void)remove(PCSCLITE_CSOCK_NAME);
141 
142  if (bind(commonSocket, &sa.sa, sizeof sa) < 0)
143  {
144  Log2(PCSC_LOG_CRITICAL, "Unable to bind common socket: %s",
145  strerror(errno));
146  return -1;
147  }
148 
149  if (listen(commonSocket, 1) < 0)
150  {
151  Log2(PCSC_LOG_CRITICAL, "Unable to listen common socket: %s",
152  strerror(errno));
153  return -1;
154  }
155 
156  /*
157  * Chmod the public entry channel
158  */
159  (void)chmod(PCSCLITE_CSOCK_NAME, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
160 
161  return 0;
162 }
163 
164 #ifdef USE_LIBSYSTEMD
165 
177 INTERNAL int32_t ListenExistingSocket(int fd)
178 {
179  if (!sd_is_socket(fd, AF_UNIX, SOCK_STREAM, -1))
180  {
181  Log1(PCSC_LOG_CRITICAL, "Passed FD is not an UNIX socket");
182  return -1;
183  }
184 
185  commonSocket = fd;
186  return 0;
187 }
188 #endif
189 
203 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
204 #define DO_TIMEOUT
205 #endif
206 INTERNAL int32_t ProcessEventsServer(uint32_t *pdwClientID)
207 {
208  fd_set read_fd;
209  int selret;
210 #ifdef DO_TIMEOUT
211  struct timeval tv;
212 
213  tv.tv_sec = 1;
214  tv.tv_usec = 0;
215 #endif
216 
217  FD_ZERO(&read_fd);
218 
219  /*
220  * Set up the bit masks for select
221  */
222  FD_SET(commonSocket, &read_fd);
223 
224  selret = select(commonSocket + 1, &read_fd, (fd_set *) NULL,
225  (fd_set *) NULL,
226 #ifdef DO_TIMEOUT
227  &tv
228 #else
229  NULL
230 #endif
231  );
232 
233  if (selret < 0)
234  {
235  if (EINTR == errno)
236  return -2;
237 
238  Log2(PCSC_LOG_CRITICAL, "Select returns with failure: %s",
239  strerror(errno));
240  return -1;
241  }
242 
243  if (selret == 0)
244  /* timeout. On *BSD only */
245  return 2;
246 
247  /*
248  * A common pipe packet has arrived - it could be a new application
249  */
250  if (FD_ISSET(commonSocket, &read_fd))
251  {
252  Log1(PCSC_LOG_DEBUG, "Common channel packet arrival");
253  if (ProcessCommonChannelRequest(pdwClientID) == -1)
254  {
255  Log2(PCSC_LOG_ERROR,
256  "error in ProcessCommonChannelRequest: %d", *pdwClientID);
257  return -1;
258  }
259  }
260  else
261  return -1;
262 
263  Log2(PCSC_LOG_DEBUG,
264  "ProcessCommonChannelRequest detects: %d", *pdwClientID);
265 
266  return 0;
267 }
268 
static int ProcessCommonChannelRequest(uint32_t *pdwClientID)
Accepts a Client connection.
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.
static int commonSocket
Socket to a file, used for clients-server communication.
INTERNAL int32_t ProcessEventsServer(uint32_t *pdwClientID)
Looks for messages sent by clients.
This handles smart card reader communications.
This handles debugging.