pcsc-lite  1.8.20
winscard_msg_srv.c
Go to the documentation of this file.
1 /*
2  * MUSCLE SmartCard Development ( http://pcsclite.alioth.debian.org/pcsclite.html )
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 
61 #include "misc.h"
62 #include "pcscd.h"
63 #include "sd-daemon.h"
64 #include "winscard.h"
65 #include "debuglog.h"
66 #include "winscard_msg.h"
67 
71 static int commonSocket = 0;
72 extern char AraKiri;
73 
85 static int ProcessCommonChannelRequest(/*@out@*/ uint32_t *pdwClientID)
86 {
87  socklen_t clnt_len;
88  int new_sock;
89  struct sockaddr_un clnt_addr;
90 
91  clnt_len = sizeof(clnt_addr);
92 
93  if ((new_sock = accept(commonSocket, (struct sockaddr *) &clnt_addr,
94  &clnt_len)) < 0)
95  {
96  Log2(PCSC_LOG_CRITICAL, "Accept on common socket: %s",
97  strerror(errno));
98  return -1;
99  }
100 
101  *pdwClientID = new_sock;
102 
103  return 0;
104 }
105 
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 
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 
202 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
203 #define DO_TIMEOUT
204 #endif
205 INTERNAL int32_t ProcessEventsServer(uint32_t *pdwClientID)
206 {
207  fd_set read_fd;
208  int selret;
209 #ifdef DO_TIMEOUT
210  struct timeval tv;
211 
212  tv.tv_sec = 1;
213  tv.tv_usec = 0;
214 #endif
215 
216  FD_ZERO(&read_fd);
217 
218  /*
219  * Set up the bit masks for select
220  */
221  FD_SET(commonSocket, &read_fd);
222 
223  selret = select(commonSocket + 1, &read_fd, (fd_set *) NULL,
224  (fd_set *) NULL,
225 #ifdef DO_TIMEOUT
226  &tv
227 #else
228  NULL
229 #endif
230  );
231 
232  if (selret < 0)
233  {
234  if (EINTR == errno)
235  return -2;
236 
237  Log2(PCSC_LOG_CRITICAL, "Select returns with failure: %s",
238  strerror(errno));
239  return -1;
240  }
241 
242  if (selret == 0)
243  /* timeout. On *BSD only */
244  return 2;
245 
246  /*
247  * A common pipe packet has arrived - it could be a new application
248  */
249  if (FD_ISSET(commonSocket, &read_fd))
250  {
251  Log1(PCSC_LOG_DEBUG, "Common channel packet arrival");
252  if (ProcessCommonChannelRequest(pdwClientID) == -1)
253  {
254  Log2(PCSC_LOG_ERROR,
255  "error in ProcessCommonChannelRequest: %d", *pdwClientID);
256  return -1;
257  }
258  }
259  else
260  return -1;
261 
262  Log2(PCSC_LOG_DEBUG,
263  "ProcessCommonChannelRequest detects: %d", *pdwClientID);
264 
265  return 0;
266 }
267 
static int ProcessCommonChannelRequest(uint32_t *pdwClientID)
Accepts a Client connection.
INTERNAL int32_t ListenExistingSocket(int fd)
Acquires a socket passed in from systemd.
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 comminication.
This keeps a list of defines for pcsc-lite.
INTERNAL int32_t ProcessEventsServer(uint32_t *pdwClientID)
Looks for messages sent by clients.
This handles smart card reader communications.
This handles debugging.