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