pcsc-lite 2.0.1
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 *
11Redistribution and use in source and binary forms, with or without
12modification, are permitted provided that the following conditions
13are met:
14
151. Redistributions of source code must retain the above copyright
16 notice, this list of conditions and the following disclaimer.
172. 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.
203. 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
23THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32THIS 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
73static int commonSocket = 0;
74extern char AraKiri;
75
87static 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
123INTERNAL 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
181INTERNAL 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
210INTERNAL 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 communication.