pcsc-lite 2.3.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
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;
71extern char AraKiri;
72
84static 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
120INTERNAL 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
178INTERNAL 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
207INTERNAL 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
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.