1 /*
2 * Remote device access - debugging utility that allows to
3 * test smart card readers on remote hosts.
4 *
5 * Copyright (C) 2003, Olaf Kirch <okir@suse.de>
6 */
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <sys/poll.h>
14 #include <sys/socket.h>
15 #include <arpa/inet.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <errno.h>
22
23 #include <openct/socket.h>
24 #include <openct/server.h>
25 #include <openct/logging.h>
26 #include <openct/ifd.h>
27 #include "internal.h"
28 #include "ria.h"
29
30 static int ria_devsock_process(ct_socket_t *, header_t *,
31 ct_buf_t *, ct_buf_t *);
32 static void ria_devsock_close(ct_socket_t *);
33 static int ria_poll_device(ct_socket_t *, struct pollfd *);
34 static void ria_close_device(ct_socket_t *);
35
36 /*
37 * Handle device side of things
38 */
ria_export_device(const char * address,const char * device)39 ria_client_t *ria_export_device(const char *address, const char *device)
40 {
41 ifd_device_t *dev;
42 ria_client_t *ria;
43 ct_socket_t *sock;
44
45 /* Open device */
46 if (!(dev = ifd_device_open(device))) {
47 ct_error("Unable to open device %s\n", device);
48 exit(1);
49 }
50
51 if (dev->type != IFD_DEVICE_TYPE_SERIAL) {
52 ct_error("Unable to handle devices other that serial");
53 exit(1);
54 }
55
56 /* Connect to ifd proxy */
57 if (!(ria = ria_connect(address)))
58 exit(1);
59 ria->user_data = dev;
60 ria->sock->process = ria_devsock_process;
61 ria->sock->close = ria_devsock_close;
62 ria->sock->user_data = ria;
63
64 ct_mainloop_add_socket(ria->sock);
65
66 /* Set up the fake socket encapsulating the device */
67 sock = ct_socket_new(0);
68 sock->fd = 0x7FFFFFFF;
69 sock->user_data = ria;
70 sock->poll = ria_poll_device;
71 sock->close = ria_close_device;
72 sock->recv = NULL;
73 sock->send = NULL;
74 ct_mainloop_add_socket(sock);
75
76 return ria;
77 }
78
ria_register_device(ria_client_t * ria,const char * name)79 int ria_register_device(ria_client_t * ria, const char *name)
80 {
81 ifd_device_t *dev = (ifd_device_t *) ria->user_data;
82 ria_device_t devinfo;
83
84 memset(&devinfo, 0, sizeof(devinfo));
85 strncpy(devinfo.name, name, RIA_NAME_MAX - 1);
86 if (dev->type == IFD_DEVICE_TYPE_SERIAL)
87 strcpy(devinfo.type, "serial");
88 else if (dev->type == IFD_DEVICE_TYPE_USB)
89 strcpy(devinfo.type, "usb");
90 else
91 strcpy(devinfo.type, "other");
92
93 return ria_command(ria, RIA_MGR_REGISTER,
94 &devinfo, sizeof(devinfo), NULL, 0, -1);
95 }
96
ria_devsock_process(ct_socket_t * sock,header_t * hdr,ct_buf_t * args,ct_buf_t * resp)97 static int ria_devsock_process(ct_socket_t * sock, header_t * hdr,
98 ct_buf_t * args, ct_buf_t * resp)
99 {
100 ria_client_t *ria = (ria_client_t *) sock->user_data;
101 ifd_device_t *dev = (ifd_device_t *) ria->user_data;
102 unsigned char cmd;
103 int rc, count;
104
105 ria_print_packet(sock, 2, "ria_devsock_process", hdr, args);
106
107 /* Unexpected reply on this socket - simply drop */
108 if (hdr->dest != 0) {
109 hdr->xid = 0;
110 return 0;
111 }
112
113 if ((rc = ct_buf_get(args, &cmd, 1)) < 0)
114 return rc;
115
116 switch (cmd) {
117 case RIA_FLUSH_DEVICE:
118 ifd_device_flush(dev);
119 return 0;
120 case RIA_SEND_BREAK:
121 {
122 unsigned int usec;
123 if ((rc = ct_buf_get(args, &usec, sizeof(usec))) < 0)
124 return rc;
125 ifd_device_send_break(dev, ntohl(usec));
126 return 0;
127 }
128 case RIA_SERIAL_GET_CONFIG:
129 {
130 ifd_device_params_t parms;
131 ria_serial_conf_t conf;
132
133 if (dev->type != IFD_DEVICE_TYPE_SERIAL)
134 return IFD_ERROR_INCOMPATIBLE_DEVICE;
135 if ((rc = ifd_device_get_parameters(dev, &parms)) < 0)
136 return rc;
137 conf.speed = htonl(parms.serial.speed);
138 conf.bits = parms.serial.bits;
139 conf.stopbits = parms.serial.stopbits;
140 conf.parity = parms.serial.parity;
141 conf.check_parity = parms.serial.check_parity;
142 conf.rts = parms.serial.rts;
143 conf.dtr = parms.serial.dtr;
144 return ct_buf_put(resp, &conf, sizeof(conf));
145 }
146
147 case RIA_SERIAL_SET_CONFIG:
148 {
149 ifd_device_params_t parms;
150 ria_serial_conf_t conf;
151
152 if (dev->type != IFD_DEVICE_TYPE_SERIAL)
153 return IFD_ERROR_INCOMPATIBLE_DEVICE;
154 if ((rc = ct_buf_get(args, &conf, sizeof(conf))) < 0)
155 return rc;
156 parms.serial.speed = ntohl(conf.speed);
157 parms.serial.bits = conf.bits;
158 parms.serial.stopbits = conf.stopbits;
159 parms.serial.parity = conf.parity;
160 parms.serial.check_parity = conf.check_parity;
161 parms.serial.rts = conf.rts;
162 parms.serial.dtr = conf.dtr;
163 if ((rc = ifd_device_set_parameters(dev, &parms)) < 0)
164 return rc;
165 return 0;
166 }
167
168 case RIA_DATA:
169 hdr->xid = 0; /* no reponse */
170 count = ct_buf_avail(args);
171 rc = ct_buf_put(&ria->data, ct_buf_head(args), count);
172 if (rc < 0) {
173 ct_buf_compact(&ria->data);
174 rc = ct_buf_put(&ria->data, ct_buf_head(args), count);
175 }
176 if (rc < 0)
177 ifd_debug(1, "unable to queue %u bytes for device",
178 count);
179 return 0;
180 default:
181 ct_error("Unexpected command 0x02%x\n", cmd);
182 return IFD_ERROR_INVALID_CMD;
183 }
184
185 }
186
ria_devsock_close(ct_socket_t * sock)187 static void ria_devsock_close(ct_socket_t * sock)
188 {
189 ct_error("Network connection closed, exiting\n");
190 exit(0);
191 }
192
ria_poll_device(ct_socket_t * sock,struct pollfd * pfd)193 static int ria_poll_device(ct_socket_t * sock, struct pollfd *pfd)
194 {
195 unsigned char buffer[512];
196 ria_client_t *ria = (ria_client_t *) sock->user_data;
197 ifd_device_t *dev = (ifd_device_t *) ria->user_data;
198 int n, rc;
199
200 pfd->fd = dev->fd;
201 if (pfd->revents & POLLIN) {
202 n = read(dev->fd, buffer, sizeof(buffer));
203 if (n < 0) {
204 ct_error("error reading from device: %m");
205 return -1;
206 }
207
208 ifd_debug(2, "read%s", ct_hexdump(buffer, n));
209 if ((rc = ria_send(ria, RIA_DATA, buffer, n)) < 0)
210 return rc;
211 }
212 if (pfd->revents & POLLOUT) {
213 n = write(dev->fd, ct_buf_head(&ria->data),
214 ct_buf_avail(&ria->data));
215 if (n < 0) {
216 ct_error("error writing to device: %m");
217 return -1;
218 }
219
220 ifd_debug(2, "wrote%s", ct_hexdump(ct_buf_head(&ria->data), n));
221 ct_buf_get(&ria->data, NULL, n);
222 }
223
224 if (ifd_device_poll_presence(dev, pfd) == 0) {
225 ifd_debug(1, "Device detached, exiting");
226 exit(0);
227 }
228
229 pfd->events |= POLLIN;
230 if (ct_buf_avail(&ria->data))
231 pfd->events |= POLLOUT;
232
233 if (1 /* hotplug */ )
234 pfd->events |= POLLHUP;
235
236 return 1;
237 }
238
ria_close_device(ct_socket_t * sock)239 static void ria_close_device(ct_socket_t * sock)
240 {
241 ct_error("Dispatcher requests that device is closed, abort");
242 exit(1);
243 }
244