diff options
author | emax <emax@FreeBSD.org> | 2003-10-12 22:04:24 +0000 |
---|---|---|
committer | emax <emax@FreeBSD.org> | 2003-10-12 22:04:24 +0000 |
commit | 41bb0e8fd2568243020852e22a6d176bccfa60cd (patch) | |
tree | 0ae0c2be63f9f9161693789721b96beb9cabcc77 /usr.sbin/bluetooth/hcsecd | |
parent | 66feac7937e372f502539e7d443aee80a25abe16 (diff) | |
download | FreeBSD-src-41bb0e8fd2568243020852e22a6d176bccfa60cd.zip FreeBSD-src-41bb0e8fd2568243020852e22a6d176bccfa60cd.tar.gz |
Update Bluetooth code.
Reviewed by: M. Warner Losh <imp@bsdimp.com>; John Hay <jhay@freebsd.org>
Approved by: M. Warner Losh <imp@bsdimp.com> (mentor)
Diffstat (limited to 'usr.sbin/bluetooth/hcsecd')
-rw-r--r-- | usr.sbin/bluetooth/hcsecd/Makefile | 13 | ||||
-rw-r--r-- | usr.sbin/bluetooth/hcsecd/hcsecd.8 | 62 | ||||
-rw-r--r-- | usr.sbin/bluetooth/hcsecd/hcsecd.c | 150 | ||||
-rw-r--r-- | usr.sbin/bluetooth/hcsecd/hcsecd.conf.5 | 129 | ||||
-rw-r--r-- | usr.sbin/bluetooth/hcsecd/hcsecd.h | 12 | ||||
-rw-r--r-- | usr.sbin/bluetooth/hcsecd/parser.y | 145 |
6 files changed, 394 insertions, 117 deletions
diff --git a/usr.sbin/bluetooth/hcsecd/Makefile b/usr.sbin/bluetooth/hcsecd/Makefile index b39ac22..d9a106f 100644 --- a/usr.sbin/bluetooth/hcsecd/Makefile +++ b/usr.sbin/bluetooth/hcsecd/Makefile @@ -1,12 +1,13 @@ -# $Id: Makefile,v 1.2 2003/03/15 03:07:42 max Exp $ +# $Id: Makefile,v 1.8 2003/08/14 20:06:20 max Exp $ # $FreeBSD$ -DESTDIR= /usr/sbin/ -MANDIR= ../share/man/man PROG= hcsecd -MAN8= hcsecd.8 -WARNS?= 1 -CFLAGS+= -g -I${.CURDIR} -I${.CURDIR}/../../../sys/netgraph/bluetooth/include +MAN= hcsecd.8 hcsecd.conf.5 SRCS= hcsecd.c lexer.l parser.y +WARNS?= 1 +CFLAGS+= -I${.CURDIR} + +DPADD= ${LIBBLUETOOTH} +LDADD= -lbluetooth .include <bsd.prog.mk> diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.8 b/usr.sbin/bluetooth/hcsecd/hcsecd.8 index 71ffcb8..1a3bb09 100644 --- a/usr.sbin/bluetooth/hcsecd/hcsecd.8 +++ b/usr.sbin/bluetooth/hcsecd/hcsecd.8 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" $Id: hcsecd.8,v 1.3 2003/04/27 19:45:32 max Exp $ +.\" $Id: hcsecd.8,v 1.8 2003/09/08 18:54:20 max Exp $ .\" $FreeBSD$ .\" .Dd November 16, 2002 @@ -38,22 +38,28 @@ .Sh DESCRIPTION The .Nm -daemon controls link keys and PIN code for Bluetooth devices. +daemon controls link keys and PIN codes for Bluetooth devices. It opens raw HCI socket and listens for the -.Dv Link_Key_Request -and +.Dv Link_Key_Request , .Dv PIN_Code_Request +and +.Dv Link_Key_Notification HCI events. -Once appropriate HCI event has been received, the daemon will +.Pp +Once +.Dv Link_Key_Request +or +.Dv PIN_Code_Request +HCI event is received, the daemon will scan configuration file for matching entry. -The remove device BD_ADDR is used as a key. +The remote device BD_ADDR is used as a key. If no matching entry was found, the default entry will be used. -If no default entry was found then it is assumed that no link key and no PIN code -exist. +If no default entry was found then it is assumed that no link key and no +PIN code exists. For any given entry, link key takes precedence over PIN code. If link key was not specified, it means device must generate link key from PIN code. -If entry was found and has the link key (or PIN code) then the +If entry was found and the link key (or PIN code) exists then the .Dv Link_Key_Request_Reply (or .Dv PIN_Code_Request_Reply ) @@ -66,12 +72,28 @@ command will be sent back to the device. .Pp The .Nm -daemon currently does not handle HCI +daemon also handles HCI .Dv Link_Key_Notification -event and does not cache link keys created from the PIN codes. -It means that the link key only exists while connection is opened. -After the connection has been terminated, the user will have to enter PIN code -again. +event and caches link keys created from the PIN codes in the memory. +To preserve link keys between restarts the +.Nm +daemon dumps link keys for all entries in the +.Pa /var/db/hcsecd.keys +link keys file. +If exists, the link keys file gets processed by +.Nm +daemon after it processes its main configuration file. +The link keys file gets written every time +.Nm +daemon is gracefully shutdown. +It is possible to force +.Nm +daemon to re-read its main configuration file and dump link keys file by sending +.Dv HUP +signal to the +.Nm +process. +User is not expected to modify link keys file by hand. .Pp The command line options are as follows: .Bl -tag -width indent @@ -80,7 +102,7 @@ Do not detach from the controlling terminal. .It Fl f Ar configfile Specify name of the configuration file. The default is -.Pa /usr/local/etc/hcsecd.conf . +.Pa /etc/bluetooth/hcsecd.conf . .It Fl h Display usage message and exit. .El @@ -91,15 +113,15 @@ Everything is based on remote device BD_ADDR. Also might implement interface for external helpers to obtain link keys and PIN codes. .Sh FILES -.Bl -tag -width ".Pa /usr/local/etc/hcsecd.conf" -compact -.It Pa /usr/local/etc/hcsecd.conf -.It Pa /var/run/hcsecd.pid +.Bl -tag -width ".Pa /etc/bluetooth/hcsecd.conf" -compact +.It Pa /etc/bluetooth/hcsecd.conf +.It Pa /var/db/hcsecd.pid +.It Pa /var/run/hcsecd.keys .El .Sh SEE ALSO -.Xr netgraph 3 , -.Xr netgraph 4 , .Xr ng_btsocket 4 , .Xr ng_hci 4 , +.Xr hcsecd.conf 5 , .Xr hccontrol 8 , .Xr hcseriald 8 .Sh AUTHORS diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.c b/usr.sbin/bluetooth/hcsecd/hcsecd.c index 0f72eb7..ac7eacb 100644 --- a/usr.sbin/bluetooth/hcsecd/hcsecd.c +++ b/usr.sbin/bluetooth/hcsecd/hcsecd.c @@ -25,20 +25,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: hcsecd.c,v 1.3 2003/04/27 19:45:32 max Exp $ + * $Id: hcsecd.c,v 1.6 2003/08/18 19:19:55 max Exp $ * $FreeBSD$ */ -#include <sys/types.h> -#include <sys/endian.h> -#include <sys/socket.h> #include <sys/queue.h> -#include <bitstring.h> +#include <bluetooth.h> #include <err.h> #include <errno.h> -#include <ng_hci.h> -#include <ng_l2cap.h> -#include <ng_btsocket.h> #include <signal.h> #include <stdarg.h> #include <stdio.h> @@ -48,10 +42,6 @@ #include <unistd.h> #include "hcsecd.h" -#define HCSECD_BUFFER_SIZE 512 -#define HCSECD_IDENT "hcsecd" -#define HCSECD_PIDFILE "/var/run/" HCSECD_IDENT ".pid" - static int done = 0; static int process_pin_code_request_event @@ -62,6 +52,10 @@ static int send_pin_code_reply (int sock, struct sockaddr_hci *addr, bdaddr_p bdaddr, char const *pin); static int send_link_key_reply (int sock, struct sockaddr_hci *addr, bdaddr_p bdaddr, u_int8_t *key); +static int process_link_key_notification_event + (int sock, struct sockaddr_hci *addr, ng_hci_link_key_notification_ep *ep); +static void sighup + (int s); static void sigint (int s); static void usage @@ -115,7 +109,7 @@ main(int argc, char *argv[]) err(1, "Could not sigaction(SIGINT)"); memset(&sa, 0, sizeof(sa)); - sa.sa_handler = read_config_file; + sa.sa_handler = sighup; if (sigaction(SIGHUP, &sa, NULL) < 0) err(1, "Could not sigaction(SIGHUP)"); @@ -127,6 +121,7 @@ main(int argc, char *argv[]) memset(&filter, 0, sizeof(filter)); bit_set(filter.event_mask, NG_HCI_EVENT_PIN_CODE_REQ - 1); bit_set(filter.event_mask, NG_HCI_EVENT_LINK_KEY_REQ - 1); + bit_set(filter.event_mask, NG_HCI_EVENT_LINK_KEY_NOTIFICATION - 1); if (setsockopt(sock, SOL_HCI_RAW, SO_HCI_RAW_FILTER, (void * const) &filter, sizeof(filter)) < 0) @@ -138,7 +133,8 @@ main(int argc, char *argv[]) openlog(HCSECD_IDENT, LOG_NDELAY|LOG_PERROR|LOG_PID, LOG_DAEMON); - read_config_file(0); + read_config_file(); + read_keys_file(); if (detach) { FILE *pid = NULL; @@ -184,6 +180,11 @@ main(int argc, char *argv[]) (bdaddr_p)(event + 1)); break; + case NG_HCI_EVENT_LINK_KEY_NOTIFICATION: + process_link_key_notification_event(sock, &addr, + (ng_hci_link_key_notification_ep *)(event + 1)); + break; + default: syslog(LOG_ERR, "Received unexpected HCI event, " \ "event=%#x", event->event); @@ -196,6 +197,7 @@ main(int argc, char *argv[]) syslog(LOG_ERR, "Could not remove PID file %s. %s (%d)", HCSECD_PIDFILE, strerror(errno), errno); + dump_keys_file(); clean_config(); closelog(); close(sock); @@ -211,27 +213,21 @@ process_pin_code_request_event(int sock, struct sockaddr_hci *addr, link_key_p key = NULL; syslog(LOG_DEBUG, "Got PIN_Code_Request event from '%s', " \ - "remote bdaddr %x:%x:%x:%x:%x:%x", addr->hci_node, - bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], - bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + "remote bdaddr %s", addr->hci_node, + bt_ntoa(bdaddr, NULL)); if ((key = get_key(bdaddr, 0)) != NULL) { syslog(LOG_DEBUG, "Found matching entry, " \ - "remote bdaddr %x:%x:%x:%x:%x:%x, name '%s', " \ - "PIN code %s", - key->bdaddr.b[5], key->bdaddr.b[4], - key->bdaddr.b[3], key->bdaddr.b[2], - key->bdaddr.b[1], key->bdaddr.b[0], + "remote bdaddr %s, name '%s', PIN code %s", + bt_ntoa(&key->bdaddr, NULL), (key->name != NULL)? key->name : "No name", (key->pin != NULL)? "exists" : "doesn't exist"); return (send_pin_code_reply(sock, addr, bdaddr, key->pin)); } - syslog(LOG_DEBUG, "Could not PIN code for remote bdaddr " \ - "%x:%x:%x:%x:%x:%x", - bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], - bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + syslog(LOG_DEBUG, "Could not PIN code for remote bdaddr %s", + bt_ntoa(bdaddr, NULL)); return (send_pin_code_reply(sock, addr, bdaddr, NULL)); } @@ -244,27 +240,21 @@ process_link_key_request_event(int sock, struct sockaddr_hci *addr, link_key_p key = NULL; syslog(LOG_DEBUG, "Got Link_Key_Request event from '%s', " \ - "remote bdaddr %x:%x:%x:%x:%x:%x", addr->hci_node, - bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], - bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + "remote bdaddr %s", addr->hci_node, + bt_ntoa(bdaddr, NULL)); if ((key = get_key(bdaddr, 0)) != NULL) { syslog(LOG_DEBUG, "Found matching entry, " \ - "remote bdaddr %x:%x:%x:%x:%x:%x, name '%s', " \ - "link key %s", - key->bdaddr.b[5], key->bdaddr.b[4], - key->bdaddr.b[3], key->bdaddr.b[2], - key->bdaddr.b[1], key->bdaddr.b[0], + "remote bdaddr %s, name '%s', link key %s", + bt_ntoa(&key->bdaddr, NULL), (key->name != NULL)? key->name : "No name", (key->key != NULL)? "exists" : "doesn't exist"); return (send_link_key_reply(sock, addr, bdaddr, key->key)); } - syslog(LOG_DEBUG, "Could not find link key for remote bdaddr " \ - "%x:%x:%x:%x:%x:%x", - bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], - bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + syslog(LOG_DEBUG, "Could not find link key for remote bdaddr %s", + bt_ntoa(bdaddr, NULL)); return (send_link_key_reply(sock, addr, bdaddr, NULL)); } @@ -295,10 +285,8 @@ send_pin_code_reply(int sock, struct sockaddr_hci *addr, cp->pin_size = strlen(cp->pin); syslog(LOG_DEBUG, "Sending PIN_Code_Reply to '%s' " \ - "for remote bdaddr %x:%x:%x:%x:%x:%x", - addr->hci_node, - bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], - bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + "for remote bdaddr %s", + addr->hci_node, bt_ntoa(bdaddr, NULL)); } else { ng_hci_pin_code_neg_rep_cp *cp = NULL; @@ -310,10 +298,8 @@ send_pin_code_reply(int sock, struct sockaddr_hci *addr, memcpy(&cp->bdaddr, bdaddr, sizeof(cp->bdaddr)); syslog(LOG_DEBUG, "Sending PIN_Code_Negative_Reply to '%s' " \ - "for remote bdaddr %x:%x:%x:%x:%x:%x", - addr->hci_node, - bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], - bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + "for remote bdaddr %s", + addr->hci_node, bt_ntoa(bdaddr, NULL)); } again: @@ -323,10 +309,8 @@ again: goto again; syslog(LOG_ERR, "Could not send PIN code reply to '%s' " \ - "for remote bdaddr %x:%x:%x:%x:%x:%x. %s (%d)", - addr->hci_node, - bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], - bdaddr->b[2], bdaddr->b[1], bdaddr->b[0], + "for remote bdaddr %s. %s (%d)", + addr->hci_node, bt_ntoa(bdaddr, NULL), strerror(errno), errno); return (-1); } @@ -359,10 +343,8 @@ send_link_key_reply(int sock, struct sockaddr_hci *addr, memcpy(&cp->key, key, sizeof(cp->key)); syslog(LOG_DEBUG, "Sending Link_Key_Reply to '%s' " \ - "for remote bdaddr %x:%x:%x:%x:%x:%x", - addr->hci_node, - bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], - bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + "for remote bdaddr %s", + addr->hci_node, bt_ntoa(bdaddr, NULL)); } else { ng_hci_link_key_neg_rep_cp *cp = NULL; @@ -374,10 +356,8 @@ send_link_key_reply(int sock, struct sockaddr_hci *addr, memcpy(&cp->bdaddr, bdaddr, sizeof(cp->bdaddr)); syslog(LOG_DEBUG, "Sending Link_Key_Negative_Reply to '%s' " \ - "for remote bdaddr %x:%x:%x:%x:%x:%x", - addr->hci_node, - bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], - bdaddr->b[2], bdaddr->b[1], bdaddr->b[0]); + "for remote bdaddr %s", + addr->hci_node, bt_ntoa(bdaddr, NULL)); } again: @@ -387,10 +367,8 @@ again: goto again; syslog(LOG_ERR, "Could not send link key reply to '%s' " \ - "for remote bdaddr %x:%x:%x:%x:%x:%x. %s (%d)", - addr->hci_node, - bdaddr->b[5], bdaddr->b[4], bdaddr->b[3], - bdaddr->b[2], bdaddr->b[1], bdaddr->b[0], + "for remote bdaddr %s. %s (%d)", + addr->hci_node, bt_ntoa(bdaddr, NULL), strerror(errno), errno); return (-1); } @@ -398,7 +376,53 @@ again: return (0); } -/* Signal handler */ +/* Process Link_Key_Notification event */ +static int +process_link_key_notification_event(int sock, struct sockaddr_hci *addr, + ng_hci_link_key_notification_ep *ep) +{ + link_key_p key = NULL; + + syslog(LOG_DEBUG, "Got Link_Key_Notification event from '%s', " \ + "remote bdaddr %s", addr->hci_node, + bt_ntoa(&ep->bdaddr, NULL)); + + if ((key = get_key(&ep->bdaddr, 1)) == NULL) { + syslog(LOG_ERR, "Could not find entry for remote bdaddr %s", + bt_ntoa(&ep->bdaddr, NULL)); + return (-1); + } + + syslog(LOG_DEBUG, "Updating link key for the entry, " \ + "remote bdaddr %s, name '%s', link key %s", + bt_ntoa(&key->bdaddr, NULL), + (key->name != NULL)? key->name : "No name", + (key->key != NULL)? "exists" : "doesn't exist"); + + if (key->key == NULL) { + key->key = (u_int8_t *) malloc(NG_HCI_KEY_SIZE); + if (key->key == NULL) { + syslog(LOG_ERR, "Could not allocate link key"); + exit(1); + } + } + + memcpy(key->key, &ep->key, NG_HCI_KEY_SIZE); + + return (0); +} + +/* Signal handlers */ +static void +sighup(int s) +{ + syslog(LOG_DEBUG, "Got SIGHUP (%d)", s); + + dump_keys_file(); + read_config_file(); + read_keys_file(); +} + static void sigint(int s) { diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.conf.5 b/usr.sbin/bluetooth/hcsecd/hcsecd.conf.5 new file mode 100644 index 0000000..d27025f --- /dev/null +++ b/usr.sbin/bluetooth/hcsecd/hcsecd.conf.5 @@ -0,0 +1,129 @@ +.\" Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $Id: hcsecd.conf.5,v 1.1 2003/05/26 22:49:23 max Exp $ +.\" $FreeBSD$ +.\" +.Dd May 26, 2003 +.Dt HCSECD.CONF 5 +.Os +.Sh NAME +.Nm hcsecd.conf +.Nd +.Xr hcsecd 8 +configuration file +.Sh DESCRIPTION +The +.Nm +file is the configuration file for the +.Xr hcsecd 8 +Bluetooth link keys/PIN codes management daemon. +.Pp +The +.Nm +file is a free-form ASCII text file. +It is parsed by the recursive-descent parser built into +.Xr hcsecd 8 . +The file may contain extra tabs and newlines for formatting purposes. +Keywords in the file are case-sensitive. +Comments may be placed anywhere within the file (except within quotes). +Comments begin with the +.Dq # +character and end at the end of the line. +.Sh FILE FORMAT +The +.Nm +file consists of a list of +.Cm device +entries. +Each +.Cm device +entry defines a link key or PIN code for a remote Bluetooth device. +Each remote Bluetooth device is identified by its unique BD_ADDR. +.Pp +The +.Cm device +entry +.Pp +.Cm device +{ +.Cm option Ar argument ; +.Oo +.Cm option Ar argument ; +.Oc +} +.Pp +The following section describes all supported options and arguments +.Bl -tag -width indent +.It Cm bdaddr Ar BD_ADDR +Specify remote device BD_ADDR for the entry. +.It Cm name Ar device_name +Specify user friendly name for the entry. +Name is a string in a straight double quotes. +.It Cm key Ar link_key +Specify link key for the entry. +Link key is hexadecimal string upto 32 characters in length starting with +.Dq 0x . +.It Cm key nokey +Specify no link key for the entry. +.It Cm pin Ar PIN_code +Specify PIN code for the entry. +PIN code is a string upto 16 characters in length in a straight double quotes. +.It Cm pin nopin +Specify no PIN code for the entry. +.El +.Sh EXAMPLES +A sample +.Nm +file +.Bd -literal +# Default entry is applied if no better match found +# It MUST have 00:00:00:00:00:00 as bdaddr +device { + bdaddr 00:00:00:00:00:00; + name "Default entry"; + key nokey; + pin nopin; +} + +# Ericsson T68 phone +device { + bdaddr 00:80:37:5e:4d:d4; + name "Ericsson T68 phone"; + key nokey; + pin "0000"; # PIN code +} + +# Dummy device +device { + bdaddr 00:11:22:33:44:55; + name "Dummy"; + key 0x00112233445566778899aabbccddeeff; # 16 bytes key + pin nopin; +} +.Ed +.Sh SEE ALSO +.Xr hcsecd 8 +.Sh AUTHORS +.An Maksim Yevmenkin Aq m_evmenkin@yahoo.com diff --git a/usr.sbin/bluetooth/hcsecd/hcsecd.h b/usr.sbin/bluetooth/hcsecd/hcsecd.h index 65820ed..4f53e99 100644 --- a/usr.sbin/bluetooth/hcsecd/hcsecd.h +++ b/usr.sbin/bluetooth/hcsecd/hcsecd.h @@ -25,13 +25,18 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: hcsecd.h,v 1.1 2002/11/24 20:22:39 max Exp $ + * $Id: hcsecd.h,v 1.3 2003/09/08 18:54:21 max Exp $ * $FreeBSD$ */ #ifndef _HCSECD_H_ #define _HCSECD_H_ 1 +#define HCSECD_BUFFER_SIZE 512 +#define HCSECD_IDENT "hcsecd" +#define HCSECD_PIDFILE "/var/run/" HCSECD_IDENT ".pid" +#define HCSECD_KEYSFILE "/var/db/" HCSECD_IDENT ".keys" + struct link_key { bdaddr_t bdaddr; /* remote device BDADDR */ @@ -49,9 +54,12 @@ extern char *config_file; void dump_config (void); #endif -void read_config_file(int s); +void read_config_file(void); void clean_config (void); link_key_p get_key (bdaddr_p bdaddr, int exact_match); +int read_keys_file (void); +int dump_keys_file (void); + #endif /* ndef _HCSECD_H_ */ diff --git a/usr.sbin/bluetooth/hcsecd/parser.y b/usr.sbin/bluetooth/hcsecd/parser.y index 750c068..d2e3696 100644 --- a/usr.sbin/bluetooth/hcsecd/parser.y +++ b/usr.sbin/bluetooth/hcsecd/parser.y @@ -26,14 +26,15 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: parser.y,v 1.1 2002/11/24 20:22:39 max Exp $ + * $Id: parser.y,v 1.5 2003/06/07 21:22:30 max Exp $ * $FreeBSD$ */ -#include <sys/types.h> +#include <sys/fcntl.h> #include <sys/queue.h> +#include <bluetooth.h> #include <errno.h> -#include <ng_hci.h> +#include <limits.h> #include <stdio.h> #include <stdarg.h> #include <string.h> @@ -49,7 +50,7 @@ static int hexa2int8(char *a); extern int yylineno; static LIST_HEAD(, link_key) link_keys; - char *config_file = "/usr/local/etc/hcsecd.conf"; + char *config_file = "/etc/bluetooth/hcsecd.conf"; static link_key_p key = NULL; %} @@ -82,13 +83,8 @@ line: T_DEVICE { if (get_key(&key->bdaddr, 1) != NULL) { syslog(LOG_ERR, "Ignoring duplicated entry " \ - "for bdaddr %x:%x:%x:%x:%x:%x", - key->bdaddr.b[5], - key->bdaddr.b[4], - key->bdaddr.b[3], - key->bdaddr.b[2], - key->bdaddr.b[1], - key->bdaddr.b[0]); + "for bdaddr %s", + bt_ntoa(&key->bdaddr, NULL)); free_key(key); } else LIST_INSERT_HEAD(&link_keys, key, next); @@ -109,21 +105,11 @@ option: bdaddr bdaddr: T_BDADDR T_BDADDRSTRING { - int a0, a1, a2, a3, a4, a5; - - if (sscanf($2, "%x:%x:%x:%x:%x:%x", - &a5, &a4, &a3, &a2, &a1, &a0) != 6) { + if (!bt_aton($2, &key->bdaddr)) { syslog(LOG_ERR, "Cound not parse BDADDR " \ "'%s'", $2); exit(1); } - - key->bdaddr.b[0] = (a0 & 0xff); - key->bdaddr.b[1] = (a1 & 0xff); - key->bdaddr.b[2] = (a2 & 0xff); - key->bdaddr.b[3] = (a3 & 0xff); - key->bdaddr.b[4] = (a4 & 0xff); - key->bdaddr.b[5] = (a5 & 0xff); } ; @@ -205,7 +191,7 @@ yyerror(char const *message) /* Re-read config file */ void -read_config_file(int s) +read_config_file(void) { extern FILE *yyin; @@ -286,18 +272,125 @@ dump_config(void) syslog(LOG_DEBUG, "device %s " \ -"bdaddr %x:%x:%x:%x:%x:%x " \ +"bdaddr %s " \ "pin %s " \ "key %s", (key->name != NULL)? key->name : "noname", - key->bdaddr.b[5], key->bdaddr.b[4], key->bdaddr.b[3], - key->bdaddr.b[2], key->bdaddr.b[1], key->bdaddr.b[0], + bt_ntoa(&key->bdaddr, NULL), (key->pin != NULL)? key->pin : "nopin", (key->key != NULL)? buffer : "nokey"); } } #endif +/* Read keys file */ +int +read_keys_file(void) +{ + FILE *f = NULL; + link_key_t *key = NULL; + char buf[HCSECD_BUFFER_SIZE], *p = NULL, *cp = NULL; + bdaddr_t bdaddr; + int i, len; + + if ((f = fopen(HCSECD_KEYSFILE, "r")) == NULL) { + if (errno == ENOENT) + return (0); + + syslog(LOG_ERR, "Could not open keys file %s. %s (%d)\n", + HCSECD_KEYSFILE, strerror(errno), errno); + + return (-1); + } + + while ((p = fgets(buf, sizeof(buf), f)) != NULL) { + if (*p == '#') + continue; + if ((cp = strpbrk(p, " ")) == NULL) + continue; + + *cp++ = '\0'; + + if (!bt_aton(p, &bdaddr)) + continue; + + if ((key = get_key(&bdaddr, 1)) == NULL) + continue; + + if (key->key == NULL) { + key->key = (u_int8_t *) malloc(NG_HCI_KEY_SIZE); + if (key->key == NULL) { + syslog(LOG_ERR, "Could not allocate link key"); + exit(1); + } + } + + memset(key->key, 0, NG_HCI_KEY_SIZE); + + len = strlen(cp) / 2; + if (len > NG_HCI_KEY_SIZE) + len = NG_HCI_KEY_SIZE; + + for (i = 0; i < len; i ++) + key->key[i] = hexa2int8(cp + 2*i); + + syslog(LOG_DEBUG, "Restored link key for the entry, " \ + "remote bdaddr %s, name '%s'", + bt_ntoa(&key->bdaddr, NULL), + (key->name != NULL)? key->name : "No name"); + } + + fclose(f); + + return (0); +} + +/* Dump keys file */ +int +dump_keys_file(void) +{ + link_key_p key = NULL; + char tmp[PATH_MAX], buf[HCSECD_BUFFER_SIZE]; + int f; + + snprintf(tmp, sizeof(tmp), "%s.tmp", HCSECD_KEYSFILE); + if ((f = open(tmp, O_RDWR|O_CREAT|O_TRUNC|O_EXCL, 0600)) < 0) { + syslog(LOG_ERR, "Could not create temp keys file %s. %s (%d)\n", + tmp, strerror(errno), errno); + return (-1); + } + + LIST_FOREACH(key, &link_keys, next) { + if (key->key == NULL) + continue; + + snprintf(buf, sizeof(buf), +"%s %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", + bt_ntoa(&key->bdaddr, NULL), + key->key[0], key->key[1], key->key[2], key->key[3], + key->key[4], key->key[5], key->key[6], key->key[7], + key->key[8], key->key[9], key->key[10], key->key[11], + key->key[12], key->key[13], key->key[14], key->key[15]); + + if (write(f, buf, strlen(buf)) < 0) { + syslog(LOG_ERR, "Could not write temp keys file. " \ + "%s (%d)\n", strerror(errno), errno); + break; + } + } + + close(f); + + if (rename(tmp, HCSECD_KEYSFILE) < 0) { + syslog(LOG_ERR, "Could not rename(%s, %s). %s (%d)\n", + tmp, HCSECD_KEYSFILE, strerror(errno), errno); + unlink(tmp); + return (-1); + } + + return (0); +} + /* Free key entry */ static void free_key(link_key_p key) |