rfcommd.c - rfcommd - RFCOMM daemon to run filters on clients.
(HTM) git clone git://bitreich.org/rfcommd/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/rfcommd/
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Tags
(DIR) README
(DIR) LICENSE
---
rfcommd.c (12906B)
---
1 /*
2 * See LICENSE for copyright details.
3 *
4 * Logic copied from rfcomm.c in bluez.
5 * SDP code from pybluez.
6 *
7 * Copy me if you can.
8 * by 20h
9 */
10
11 #include <stdio.h>
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <getopt.h>
18 #include <signal.h>
19 #include <libgen.h>
20 #include <termios.h>
21 #include <stdint.h>
22 #include <poll.h>
23 #include <stdarg.h>
24 #include <sys/poll.h>
25 #include <sys/param.h>
26 #include <sys/ioctl.h>
27 #include <sys/socket.h>
28 #include <sys/wait.h>
29
30 #include <bluetooth/bluetooth.h>
31 #include <bluetooth/hci.h>
32 #include <bluetooth/hci_lib.h>
33 #include <bluetooth/rfcomm.h>
34 #include <bluetooth/sdp.h>
35 #include <bluetooth/sdp_lib.h>
36
37 #include "arg.h"
38
39 volatile sig_atomic_t __io_canceled = 0;
40
41 int dodebug = 0;
42
43 void
44 debug(char *fmt, ...)
45 {
46 va_list fmtargs;
47
48 if (!dodebug)
49 return;
50
51 va_start(fmtargs, fmt);
52 vfprintf(stderr, fmt, fmtargs);
53 va_end(fmtargs);
54 }
55
56 void
57 sig_hup(int sig)
58 {
59 return;
60 }
61
62 void
63 sig_term(int sig)
64 {
65 __io_canceled = 1;
66 }
67
68 void
69 setup_signals(void)
70 {
71 struct sigaction sa;
72
73 memset(&sa, 0, sizeof(sa));
74 sa.sa_flags = SA_NOCLDSTOP;
75 sa.sa_handler = SIG_IGN;
76 sigaction(SIGCHLD, &sa, NULL);
77 sigaction(SIGPIPE, &sa, NULL);
78
79 sa.sa_handler = sig_term;
80 sigaction(SIGTERM, &sa, NULL);
81 sigaction(SIGINT, &sa, NULL);
82
83 sa.sa_handler = sig_hup;
84 sigaction(SIGHUP, &sa, NULL);
85 }
86
87 int
88 _adv_available(struct hci_dev_info *di)
89 {
90 uint32_t *flags = &di->flags;
91 int dd;
92
93 if (hci_test_bit(HCI_RAW, &flags) && !bacmp(&di->bdaddr, BDADDR_ANY)) {
94 dd = hci_open_dev(di->dev_id);
95
96 if (dd < 0)
97 return -1;
98 hci_read_bd_addr(dd, &di->bdaddr, 1000);
99 hci_close_dev(dd);
100 }
101
102 return (hci_test_bit(HCI_UP, flags) &&
103 hci_test_bit(HCI_RUNNING, flags) &&
104 hci_test_bit(HCI_PSCAN, flags) &&
105 hci_test_bit(HCI_ISCAN, flags)) != 0 ? 0 : -1;
106 }
107
108 int
109 _any_adv_available(void)
110 {
111 struct hci_dev_list_req *dl = NULL;
112 struct hci_dev_req *dr = NULL;
113 struct hci_dev_info di = {0, };
114 int result = -1;
115 int ctl = -1;
116 int i;
117
118 if ((ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0)
119 return -1;
120
121 if (!(dl = malloc(HCI_MAX_DEV * sizeof(struct hci_dev_req) +
122 sizeof(uint16_t)))) {
123 goto CLEAN_UP_RETURN;
124 }
125 dl->dev_num = HCI_MAX_DEV;
126 dr = dl->dev_req;
127
128 if (ioctl(ctl, HCIGETDEVLIST, (void *)dl) < 0)
129 goto CLEAN_UP_RETURN;
130
131 for (i = 0; i < dl->dev_num; i++) {
132 di.dev_id = (dr+i)->dev_id;
133 if (ioctl(ctl, HCIGETDEVINFO, (void *)&di) < 0)
134 continue;
135
136 if (_adv_available(&di) == 0) {
137 result = 0;
138 goto CLEAN_UP_RETURN;
139 }
140 }
141
142 CLEAN_UP_RETURN:
143 close(ctl);
144 free(dl);
145
146 return result;
147 }
148
149 int
150 adv_available(int sock)
151 {
152 bdaddr_t ba = {{0, }};
153 struct sockaddr addr = {0, };
154 int dev_id = -1;
155 socklen_t alen = sizeof(addr);
156 struct sockaddr_rc const *addr_rc = (struct sockaddr_rc const *)&addr;
157 struct hci_dev_info di;
158
159 if (getsockname(sock, &addr, &alen) < 0)
160 return -1;
161
162 ba = addr_rc->rc_bdaddr;
163
164 if (bacmp(&ba, BDADDR_ANY) == 0) {
165 dev_id = -1;
166 } else {
167 dev_id = hci_get_route(&ba);
168 }
169
170 if (dev_id == -1) {
171 return _any_adv_available();
172 } else {
173 if (hci_devinfo(dev_id, &di))
174 return -1;
175 return _adv_available(&di);
176 }
177 }
178
179 int
180 str2uuid(char *uuidstr, uuid_t *uuid)
181 {
182 uint32_t uuid_int[4];
183 int i;
184 char *endptr, buf[9] = { 0 };
185
186 if (strlen(uuidstr) == 36) {
187 if (uuidstr[8] != '-' && uuidstr[13] != '-' &&
188 uuidstr[18] != '-' && uuidstr[23] != '-') {
189 return 1;
190 }
191
192 strncpy(buf, uuidstr, 8);
193 uuid_int[0] = htonl(strtoul(buf, &endptr, 16));
194 if (endptr != buf+8)
195 return 1;
196
197 strncpy(buf, uuidstr+9, 4);
198 strncpy(buf+4, uuidstr+14, 4);
199 uuid_int[1] = htonl(strtoul(buf, &endptr, 16));
200 if (endptr != buf+8)
201 return 1;
202
203 strncpy(buf, uuidstr+19, 4);
204 strncpy(buf+4, uuidstr+24, 4);
205 uuid_int[2] = htonl(strtoul(buf, &endptr, 16));
206 if (endptr != buf+8)
207 return 1;
208
209 strncpy(buf, uuidstr+28, 4);
210 uuid_int[3] = htonl(strtoul(buf, &endptr, 16));
211 if (endptr != buf+8)
212 return 1;
213
214 if (uuid != NULL)
215 sdp_uuid128_create(uuid, uuid_int);
216 } else if (strlen(uuidstr) == 8) {
217 uuid_int[0] = strtoul(uuidstr, &endptr, 16);
218 if (endptr != uuidstr+8)
219 return 1;
220 if (uuid != NULL)
221 sdp_uuid32_create(uuid, uuid_int[0]);
222 } else if (strlen(uuidstr) == 4) {
223 i = strtol(uuidstr, &endptr, 16);
224 if (endptr != uuidstr+4)
225 return 1;
226 if (uuid != NULL)
227 sdp_uuid16_create(uuid, i);
228 } else {
229 return 1;
230 }
231
232 return 0;
233 }
234
235 int
236 sdp_advertise_service(int sock, char *svcname,
237 char *svcid, int svc_class, int profiles,
238 char *svcprovider, char *svcdescription)
239 {
240 char addrbuf[256];
241 int res, err = 0;
242 struct sockaddr *sockaddr;
243 uuid_t root_uuid, l2cap_uuid, rfcomm_uuid, svc_class_uuid,
244 svc_uuid;
245 sdp_profile_desc_t *profile_desc;
246 sdp_list_t *l2cap_list = NULL, *rfcomm_list = NULL, *root_list = NULL,
247 *proto_list = NULL, *profile_list = NULL,
248 *svc_class_list = NULL, *access_proto_list = NULL;
249 sdp_data_t *channel = 0;
250 sdp_record_t record;
251 sdp_session_t *session = 0;
252 uint8_t rfcomm_channel;
253 socklen_t addrlen = sizeof(struct sockaddr_rc);
254
255 str2uuid(svcid, &svc_uuid);
256 sdp_uuid16_create(&svc_class_uuid, svc_class);
257
258 memset(addrbuf, 0, sizeof(addrbuf));
259
260 if (adv_available(sock) < 0)
261 return -1;
262
263 res = getsockname(sock, (struct sockaddr *)addrbuf, &addrlen);
264 if (res < 0)
265 return -1;
266 sockaddr = (struct sockaddr *)addrbuf;
267
268 memset(&record, 0, sizeof(record));
269 memset(&record.handle, 0xff, sizeof(record.handle));
270
271 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
272 root_list = sdp_list_append(0, &root_uuid);
273 sdp_set_browse_groups(&record, root_list);
274 sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
275 l2cap_list = sdp_list_append(0, &l2cap_uuid);
276 proto_list = sdp_list_append(0, l2cap_list);
277 rfcomm_channel = ((struct sockaddr_rc *)sockaddr)->rc_channel;
278 sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
279 channel = sdp_data_alloc(SDP_UINT8, &rfcomm_channel);
280 rfcomm_list = sdp_list_append(0, &rfcomm_uuid);
281 sdp_list_append(rfcomm_list, channel);
282 sdp_list_append(proto_list, rfcomm_list);
283 access_proto_list = sdp_list_append(0, proto_list);
284 sdp_set_access_protos(&record, access_proto_list);
285 svc_class_list = sdp_list_append(svc_class_list, &svc_class_uuid);
286 sdp_set_service_classes(&record, svc_class_list);
287
288 profile_desc = (sdp_profile_desc_t *)malloc(sizeof(sdp_profile_desc_t));
289 if (profile_desc == NULL)
290 return -1;
291 sdp_uuid16_create(&profile_desc->uuid, profiles);
292 profile_list = sdp_list_append(profile_list, profile_desc);
293 sdp_set_profile_descs(&record, profile_list);
294
295 sdp_set_info_attr(&record, svcname, svcprovider, svcdescription);
296 sdp_set_service_id(&record, svc_uuid);
297
298 session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, 0);
299 if (!session)
300 return -1;
301 err = sdp_record_register(session, &record, 0);
302
303 if (channel)
304 sdp_data_free(channel);
305 sdp_list_free(l2cap_list, 0);
306 sdp_list_free(rfcomm_list, 0);
307 sdp_list_free(root_list, 0);
308 sdp_list_free(access_proto_list, 0);
309 sdp_list_free(svc_class_list, 0);
310 sdp_list_free(profile_list, free);
311
312 if (err)
313 return -1;
314
315 return 0;
316 }
317
318 void
319 usage(char *argv0)
320 {
321 fprintf(stderr, "%s [-dhrAESM] [-i hciX|bdaddr] [-L linger] [-c channel] [-f filter cmd] [cmd]\n",
322 basename(argv0));
323 exit(1);
324 }
325
326 int
327 main(int argc, char *argv[])
328 {
329 int rfcomm_raw_tty = 0, auth = 0, encryption = 0,
330 secure = 0, master = 0, linger = 0, sk, nsk, fd, lm , try = 30,
331 ctl, rc_channel = 1, filteri, dev;
332 char *argv0, *optarg, dst[18], devname[MAXPATHLEN], *replace,
333 *cmd, *oldcmd, *defaultcmd = NULL, *runcmd;
334 struct sockaddr_rc laddr, raddr;
335 struct rfcomm_dev_req req;
336 struct termios ti;
337 socklen_t alen;
338 bdaddr_t bdaddr;
339 struct linger l;
340
341 char **cmds = NULL;
342 char **filteraddrs = NULL;
343 bdaddr_t **filterbds = NULL;
344 int filtern = 0;
345
346 bacpy(&bdaddr, BDADDR_ANY);
347
348 ARGBEGIN(argv0) {
349 case 'c':
350 rc_channel = atoi(EARGF(usage(argv0)));
351 break;
352 case 'd':
353 dodebug = 1;
354 break;
355 case 'i':
356 optarg = EARGF(usage(argv0));
357 if (strncmp(optarg, "hci", 3) == 0) {
358 hci_devba(atoi(optarg + 3), &bdaddr);
359 } else {
360 str2ba(optarg, &bdaddr);
361 }
362 break;
363 case 'f':
364 ++filtern;
365 filteraddrs = realloc(filteraddrs,
366 filtern * sizeof(*filteraddrs));
367 if (filteraddrs == NULL)
368 exit(1);
369
370 cmds = realloc(cmds, filtern * sizeof(*cmds));
371 if (cmds == NULL)
372 exit(1);
373
374 filterbds = realloc(filterbds, filtern * sizeof(*filterbds));
375 if (filterbds == NULL)
376 exit(1);
377
378 filteraddrs[filtern-1] = EARGF(usage(argv0));
379 argv++, argc--;
380 if (argc <= 0)
381 usage(argv0);
382 cmds[filtern-1] = argv[0];
383
384 filterbds[filtern-1] = malloc(sizeof(*filterbds));
385 if (filterbds[filtern-1] == NULL)
386 exit(1);
387 str2ba(filteraddrs[filtern-1], filterbds[filtern-1]);
388 break;
389 case 'r':
390 rfcomm_raw_tty = 1;
391 break;
392 case 'A':
393 auth = 1;
394 break;
395 case 'E':
396 encryption = 1;
397 break;
398 case 'S':
399 secure = 1;
400 break;
401 case 'M':
402 master = 1;
403 break;
404 case 'L':
405 linger = atoi(EARGF(usage(argv0)));
406 break;
407 case 'h':
408 default:
409 usage(argv0);
410 } ARGEND;
411
412 if (argc > 0)
413 defaultcmd = argv[0];
414 if (defaultcmd == NULL && filtern < 0)
415 usage(argv[0]);
416
417 for (filteri = 0; filteri < filtern; filteri++) {
418 ba2str(filterbds[filteri], dst);
419 debug("filter: %s (%s) -> %s\n",
420 filteraddrs[filteri], dst, cmds[filteri]);
421 }
422 debug("defaultcmd: %s\n", defaultcmd);
423
424 setup_signals();
425
426 ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_RFCOMM);
427 if (ctl < 0) {
428 perror("Can't open RFCOMM control socket");
429 return 1;
430 }
431
432 laddr.rc_family = AF_BLUETOOTH;
433 bacpy(&laddr.rc_bdaddr, &bdaddr);
434 laddr.rc_channel = rc_channel;
435
436 sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
437 if (sk < 0) {
438 perror("Can't create RFCOMM socket");
439 return 1;
440 }
441
442 lm = 0;
443 if (master)
444 lm |= RFCOMM_LM_MASTER;
445 if (auth)
446 lm |= RFCOMM_LM_AUTH;
447 if (encryption)
448 lm |= RFCOMM_LM_ENCRYPT;
449 if (secure)
450 lm |= RFCOMM_LM_SECURE;
451
452 if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
453 perror("Can't set RFCOMM link mode");
454 close(sk);
455 return 1;
456 }
457
458 if (bind(sk, (struct sockaddr *)&laddr, sizeof(laddr)) < 0) {
459 perror("Can't bind RFCOMM socket");
460 close(sk);
461 return 1;
462 }
463
464 debug("Waiting for connection on channel %d\n", laddr.rc_channel);
465
466 listen(sk, 10);
467
468 sdp_advertise_service(sk,
469 "SPP Printer",
470 "00001101-0000-1000-8000-00805F9B34FB",
471 SERIAL_PORT_SVCLASS_ID,
472 SERIAL_PORT_PROFILE_ID,
473 "SPP Printer Emulation",
474 "rfcommd");
475
476 while (!__io_canceled) {
477 alen = sizeof(raddr);
478 nsk = accept(sk, (struct sockaddr *)&raddr, &alen);
479
480 if (fork() != 0)
481 continue;
482
483 ba2str(&raddr.rc_bdaddr, dst);
484 debug("Accept from %s\n", dst);
485
486 for (filteri = 0; filteri < filtern; filteri++) {
487 if (!bacmp(filterbds[filteri], &raddr.rc_bdaddr)) {
488 runcmd = cmds[filteri];
489 debug("filter found: %s -> %s\n",
490 filteraddrs[filteri],
491 runcmd);
492 break;
493 }
494 }
495 if (filteri >= filtern) {
496 if (defaultcmd != NULL) {
497 debug("running defaultcmd = %s\n",
498 defaultcmd);
499 runcmd = defaultcmd;
500 } else {
501 close(nsk);
502 continue;
503 }
504 }
505
506 alen = sizeof(laddr);
507 if (getsockname(nsk, (struct sockaddr *)&laddr, &alen) < 0) {
508 perror("Can't get RFCOMM socket name");
509 close(nsk);
510 continue;
511 }
512
513 if (linger) {
514 l.l_onoff = 1;
515 l.l_linger = linger;
516
517 if (setsockopt(nsk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)) < 0) {
518 perror("Can't set linger option");
519 close(nsk);
520 continue;
521 }
522 }
523
524 memset(&req, 0, sizeof(req));
525 req.dev_id = -1;
526 req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP);
527
528 bacpy(&req.src, &laddr.rc_bdaddr);
529 bacpy(&req.dst, &raddr.rc_bdaddr);
530 req.channel = raddr.rc_channel;
531
532 dev = ioctl(nsk, RFCOMMCREATEDEV, &req);
533 if (dev < 0) {
534 perror("Can't create RFCOMM TTY");
535 close(sk);
536 continue;
537 }
538
539 snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev);
540 while ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) {
541 if (errno == EACCES) {
542 perror("Can't open RFCOMM device");
543 goto release;
544 }
545
546 snprintf(devname, MAXPATHLEN - 1, "/dev/bluetooth/rfcomm/%d", dev);
547 if ((fd = open(devname, O_RDONLY | O_NOCTTY)) < 0) {
548 if (try--) {
549 snprintf(devname, MAXPATHLEN - 1, "/dev/rfcomm%d", dev);
550 usleep(100 * 1000);
551 continue;
552 }
553 perror("Can't open RFCOMM device");
554 goto release;
555 }
556 }
557
558 if (rfcomm_raw_tty) {
559 tcflush(fd, TCIOFLUSH);
560
561 cfmakeraw(&ti);
562 tcsetattr(fd, TCSANOW, &ti);
563 }
564
565 ba2str(&req.dst, dst);
566 debug("Connection from %s to %s\n", dst, devname);
567
568 /* Replace all occurences of '{}' with the rfcomm device path. */
569 asprintf(&oldcmd, "%s", runcmd);
570 while ((replace = strstr(oldcmd, "{}"))) {
571 replace[0] = '%';
572 replace[1] = 's';
573 asprintf(&cmd, oldcmd, devname);
574 free(oldcmd);
575 oldcmd = cmd;
576 }
577
578 debug("Executing %s\n", cmd);
579
580 system(cmd);
581 free(cmd);
582
583 close(fd);
584 close(nsk);
585 release:
586 memset(&req, 0, sizeof(req));
587 req.dev_id = dev;
588 req.flags = (1 << RFCOMM_HANGUP_NOW);
589 ioctl(ctl, RFCOMMRELEASEDEV, &req);
590 }
591
592 close(sk);
593
594 return 0;
595 }
596