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