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 *
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
43
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
70static int commonSocket = 0;
71
83static 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
119INTERNAL 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
177INTERNAL 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
206INTERNAL 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
This handles debugging.
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.