Bluetooth fixes by Iain Hibbert:
Remove bluetooth.conf stuff from bthcid(8), and use XML with proplib(3) for keyfile. Also, associate keys with local and remote address.
This commit is contained in:
parent
1d78709e65
commit
7b1d74d73f
@ -1,4 +1,4 @@
|
||||
# $NetBSD: Makefile,v 1.1 2006/06/19 15:44:56 gdamore Exp $
|
||||
# $NetBSD: Makefile,v 1.2 2006/07/26 11:00:07 tron Exp $
|
||||
|
||||
PROG= bthcid
|
||||
MAN= bthcid.8
|
||||
@ -6,7 +6,7 @@ SRCS= bthcid.c hci.c client.c config.c
|
||||
|
||||
CPPFLAGS+= -D_BTHCID_
|
||||
|
||||
DPADD+= ${LIBBLUETOOTH} ${LIBEVENT} ${LIBUTIL}
|
||||
LDADD+= -lbluetooth -levent -lutil
|
||||
DPADD+= ${LIBBLUETOOTH} ${LIBEVENT} ${LIBPROP} ${LIBUTIL}
|
||||
LDADD+= -lbluetooth -levent -lprop -lutil
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" $NetBSD: bthcid.8,v 1.1 2006/06/19 15:44:56 gdamore Exp $
|
||||
.\" $NetBSD: bthcid.8,v 1.2 2006/07/26 11:00:07 tron Exp $
|
||||
.\"
|
||||
.\" Copyright (c) 2006 Itronix Inc.
|
||||
.\" All rights reserved.
|
||||
@ -52,7 +52,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $Id: bthcid.8,v 1.1 2006/06/19 15:44:56 gdamore Exp $
|
||||
.\" $Id: bthcid.8,v 1.2 2006/07/26 11:00:07 tron Exp $
|
||||
.\" $FreeBSD: src/usr.sbin/bluetooth/hcsecd/hcsecd.8,v 1.6 2006/02/11 15:36:37 markus Exp $
|
||||
.\"
|
||||
.Dd November 16, 2002
|
||||
@ -64,7 +64,6 @@
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl fn
|
||||
.Op Fl c Ar config_file
|
||||
.Op Fl d Ar device
|
||||
.Op Fl m Ar mode
|
||||
.Op Fl s Ar socket_name
|
||||
@ -74,18 +73,15 @@
|
||||
The
|
||||
.Nm
|
||||
daemon manages link keys and PIN codes for Bluetooth devices.
|
||||
It opens a raw HCI socket and listens for the following HCI events at the
|
||||
.Ar device
|
||||
address given, if any.
|
||||
It opens a raw HCI socket and listens for the following HCI events.
|
||||
.Pp
|
||||
.Bl -tag -width XXXX -compact
|
||||
.It Dv Link_Key_Request
|
||||
.Nm
|
||||
scans first the
|
||||
scans the
|
||||
.Pa /var/db/bthcid.keys
|
||||
file for a cached link key matching the remote device BD_ADDR and, if
|
||||
none is found, further scans the configuration file. When a link key
|
||||
has been found, the
|
||||
found, the
|
||||
.Dv Link_Key_Request_Reply
|
||||
will be sent back to the device, otherwise the
|
||||
.Dv Link_Key_Request_Negative_Reply
|
||||
@ -100,9 +96,8 @@ link keys file, which will be created if it does not already exist.
|
||||
.It Dv PIN_Code_Request
|
||||
The
|
||||
.Nm
|
||||
daemon first checks its cached PINs, then the configuration file
|
||||
for a matching remote device entry.
|
||||
When no PIN is found, the
|
||||
daemon checks its PIN cache for a matching remote device entry.
|
||||
If no PIN is found, the
|
||||
.Nm
|
||||
daemon will send a message to any PIN clients that have
|
||||
registered, with the device details and a timeout value.
|
||||
@ -123,10 +118,6 @@ utility.
|
||||
.Pp
|
||||
The command line options are as follows:
|
||||
.Bl -tag -width XXXX
|
||||
.It Fl c Ar config_file
|
||||
Specify the name of the configuration file.
|
||||
The default is
|
||||
.Pa /etc/bluetooth/bluetooth.conf .
|
||||
.It Fl d Ar device
|
||||
Specify the local Bluetooth device address. The default is BDADDR_ANY.
|
||||
.It Fl f
|
||||
@ -144,14 +135,12 @@ Specify the socket name to listen on for PIN clients. The default path is
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -compact
|
||||
.It Pa /etc/bluetooth/bluetooth.conf
|
||||
.It Pa /var/db/bthcid.keys
|
||||
.It Pa /var/run/bthcid
|
||||
.It Pa /var/run/bthcid.pid
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr bluetooth 4 ,
|
||||
.Xr bluetooth.conf 5 ,
|
||||
.Xr btconfig 8 ,
|
||||
.Xr btpin 1
|
||||
.Sh AUTHORS
|
||||
@ -171,13 +160,13 @@ with its present name and extended to support PIN clients by
|
||||
under the sponsorship of
|
||||
.An Itronix, Inc.
|
||||
.Sh BUGS
|
||||
Currently there is no way to select the link key based on
|
||||
which local device received the request.
|
||||
.Pp
|
||||
Everything is based on the remote device BD_ADDR.
|
||||
.Pp
|
||||
Currently the only way to make the
|
||||
The only way to make the
|
||||
.Nm
|
||||
daemon forget a link key is to edit the
|
||||
.Pa /var/db/bthcid.keys
|
||||
file by hand.
|
||||
.Pp
|
||||
The only way to specify link keys (useful when multiple operating
|
||||
systems are used on the same hardware), is to edit the
|
||||
.Pa /var/db/bthcid.keys
|
||||
file by hand.
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: bthcid.c,v 1.1 2006/06/19 15:44:56 gdamore Exp $ */
|
||||
/* $NetBSD: bthcid.c,v 1.2 2006/07/26 11:00:07 tron Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
@ -33,7 +33,7 @@
|
||||
__COPYRIGHT("@(#) Copyright (c) 2006 Itronix, Inc.\n"
|
||||
"@(#) Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>\n"
|
||||
"All rights reserved.\n");
|
||||
__RCSID("$NetBSD: bthcid.c,v 1.1 2006/06/19 15:44:56 gdamore Exp $");
|
||||
__RCSID("$NetBSD: bthcid.c,v 1.2 2006/07/26 11:00:07 tron Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
@ -49,8 +49,6 @@ __RCSID("$NetBSD: bthcid.c,v 1.1 2006/06/19 15:44:56 gdamore Exp $");
|
||||
|
||||
#include "bthcid.h"
|
||||
|
||||
const char *key_file = "/var/db/bthcid.keys";
|
||||
const char *config_file = NULL;
|
||||
const char *socket_name = BTHCID_SOCKET_NAME;
|
||||
int detach = 1;
|
||||
|
||||
@ -71,12 +69,8 @@ main(int argc, char *argv[])
|
||||
bdaddr_copy(&bdaddr, BDADDR_ANY);
|
||||
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
|
||||
|
||||
while ((ch = getopt(argc, argv, "c:d:fm:ns:h")) != -1) {
|
||||
while ((ch = getopt(argc, argv, "d:fm:ns:h")) != -1) {
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
config_file = optarg;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
if (!bt_devaddr(optarg, &bdaddr))
|
||||
err(EXIT_FAILURE, "%s", optarg);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: bthcid.h,v 1.1 2006/06/19 15:44:56 gdamore Exp $ */
|
||||
/* $NetBSD: bthcid.h,v 1.2 2006/07/26 11:00:07 tron Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
@ -61,18 +61,14 @@ typedef struct {
|
||||
|
||||
#ifdef _BTHCID_
|
||||
|
||||
extern const char *key_file;
|
||||
extern const char *config_file;
|
||||
|
||||
/* config.c */
|
||||
uint8_t *lookup_pin (bdaddr_t *, bdaddr_t *);
|
||||
uint8_t *lookup_key (bdaddr_t *, bdaddr_t *);
|
||||
void save_key (bdaddr_t *, bdaddr_t *, uint8_t *);
|
||||
|
||||
/* client.c */
|
||||
int init_control (const char *, mode_t);
|
||||
int send_client_request (bdaddr_t *, bdaddr_t *, int);
|
||||
uint8_t *lookup_item (bdaddr_t *, bdaddr_t *);
|
||||
uint8_t *lookup_pin (bdaddr_t *, bdaddr_t *);
|
||||
|
||||
/* hci.c */
|
||||
int init_hci (bdaddr_t *);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: client.c,v 1.1 2006/06/19 15:44:56 gdamore Exp $ */
|
||||
/* $NetBSD: client.c,v 1.2 2006/07/26 11:00:07 tron Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
@ -30,7 +30,7 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: client.c,v 1.1 2006/06/19 15:44:56 gdamore Exp $");
|
||||
__RCSID("$NetBSD: client.c,v 1.2 2006/07/26 11:00:07 tron Exp $");
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/queue.h>
|
||||
@ -313,7 +313,7 @@ process_item(int fd, short ev, void *arg)
|
||||
|
||||
/* lookup PIN in item cache */
|
||||
uint8_t *
|
||||
lookup_item(bdaddr_t *laddr, bdaddr_t *raddr)
|
||||
lookup_pin(bdaddr_t *laddr, bdaddr_t *raddr)
|
||||
{
|
||||
struct item *item;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: config.c,v 1.1 2006/06/19 15:44:56 gdamore Exp $ */
|
||||
/* $NetBSD: config.c,v 1.2 2006/07/26 11:00:07 tron Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2006 Itronix Inc.
|
||||
@ -30,104 +30,192 @@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__RCSID("$NetBSD: config.c,v 1.1 2006/06/19 15:44:56 gdamore Exp $");
|
||||
__RCSID("$NetBSD: config.c,v 1.2 2006/07/26 11:00:07 tron Exp $");
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <prop/proplib.h>
|
||||
#include <bluetooth.h>
|
||||
#include <errno.h>
|
||||
#include <event.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bthcid.h"
|
||||
|
||||
static bt_cfgentry_t *cfg = NULL;
|
||||
static const char *key_file = "/var/db/bthcid.keys";
|
||||
static const char *new_key_file = "/var/db/bthcid.keys.new";
|
||||
|
||||
static prop_dictionary_t
|
||||
load_keys(void)
|
||||
{
|
||||
prop_dictionary_t dict;
|
||||
char *xml;
|
||||
off_t len;
|
||||
int fd;
|
||||
|
||||
fd = open(key_file, O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
return NULL;
|
||||
|
||||
len = lseek(fd, 0, SEEK_END);
|
||||
if (len == 0) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
xml = malloc(len);
|
||||
if (xml == NULL) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)lseek(fd, 0, SEEK_SET);
|
||||
if (read(fd, xml, len) != len) {
|
||||
free(xml);
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
dict = prop_dictionary_internalize(xml);
|
||||
free(xml);
|
||||
close(fd);
|
||||
return dict;
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up key in keys file. We store a dictionary for each
|
||||
* remote address, and inside that we have a data object for
|
||||
* each local address containing the key.
|
||||
*/
|
||||
uint8_t *
|
||||
lookup_key(bdaddr_t *laddr, bdaddr_t *raddr)
|
||||
{
|
||||
bt_handle_t handle;
|
||||
static uint8_t key[HCI_KEY_SIZE];
|
||||
prop_dictionary_t cfg;
|
||||
prop_object_t obj;
|
||||
|
||||
if (cfg != NULL) {
|
||||
bt_freeconfig(cfg);
|
||||
cfg = NULL;
|
||||
}
|
||||
|
||||
handle = bt_openconfig(key_file);
|
||||
if (handle == NULL)
|
||||
cfg = load_keys();
|
||||
if (cfg == NULL)
|
||||
return NULL;
|
||||
|
||||
cfg = bt_getconfig(handle, raddr);
|
||||
bt_closeconfig(handle);
|
||||
|
||||
if (cfg == NULL) {
|
||||
handle = bt_openconfig(config_file);
|
||||
if (handle == NULL)
|
||||
return NULL;
|
||||
|
||||
cfg = bt_getconfig(handle, raddr);
|
||||
bt_closeconfig(handle);
|
||||
obj = prop_dictionary_get(cfg, bt_ntoa(laddr, NULL));
|
||||
if (obj == NULL || prop_object_type(obj) != PROP_TYPE_DICTIONARY) {
|
||||
prop_object_release(cfg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cfg != NULL)
|
||||
return cfg->key;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
lookup_pin(bdaddr_t *laddr, bdaddr_t *raddr)
|
||||
{
|
||||
bt_handle_t handle;
|
||||
|
||||
if (cfg != NULL) {
|
||||
bt_freeconfig(cfg);
|
||||
cfg = NULL;
|
||||
obj = prop_dictionary_get(obj, bt_ntoa(raddr, NULL));
|
||||
if (obj == NULL || prop_object_type(obj) != PROP_TYPE_DATA
|
||||
|| prop_data_size(obj) != sizeof(key)) {
|
||||
prop_object_release(cfg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
handle = bt_openconfig(config_file);
|
||||
if (handle != NULL) {
|
||||
cfg = bt_getconfig(handle, raddr);
|
||||
bt_closeconfig(handle);
|
||||
|
||||
if (cfg != NULL && cfg->pin != NULL)
|
||||
return cfg->pin;
|
||||
}
|
||||
|
||||
return lookup_item(laddr, raddr);
|
||||
memcpy(key, prop_data_data_nocopy(obj), sizeof(key));
|
||||
prop_object_release(cfg);
|
||||
return key;
|
||||
}
|
||||
|
||||
void
|
||||
save_key(bdaddr_t *laddr, bdaddr_t *raddr, uint8_t *key)
|
||||
{
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
char buffer[100], keybuf[HCI_KEY_SIZE * 2 + 1];
|
||||
int fd, n, i;
|
||||
prop_dictionary_t cfg, dev;
|
||||
prop_data_t dat;
|
||||
char *xml;
|
||||
int fd;
|
||||
size_t len;
|
||||
|
||||
fd = open(key_file, O_WRONLY|O_APPEND|O_CREAT|O_EXLOCK, 0600);
|
||||
if (fd < 0) {
|
||||
syslog(LOG_ERR, "Cannot open keyfile %s. %s (%d)",
|
||||
key_file, strerror(errno), errno);
|
||||
cfg = load_keys();
|
||||
if (cfg == NULL) {
|
||||
cfg = prop_dictionary_create();
|
||||
if (cfg == NULL) {
|
||||
syslog(LOG_ERR, "prop_dictionary_create() failed. %s (%d)",
|
||||
strerror(errno), errno);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dev = prop_dictionary_get(cfg, bt_ntoa(laddr, NULL));
|
||||
if (dev == NULL) {
|
||||
dev = prop_dictionary_create();
|
||||
if (dev == NULL) {
|
||||
syslog(LOG_ERR, "prop_dictionary_create() failed. %s (%d)",
|
||||
strerror(errno), errno);
|
||||
|
||||
prop_object_release(cfg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!prop_dictionary_set(cfg, bt_ntoa(laddr, NULL), dev)) {
|
||||
syslog(LOG_ERR, "prop_dictionary_set() failed. %s (%d)",
|
||||
strerror(errno), errno);
|
||||
|
||||
prop_object_release(dev);
|
||||
prop_object_release(cfg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
dat = prop_data_create_data_nocopy(key, HCI_KEY_SIZE);
|
||||
if (dat == NULL) {
|
||||
syslog(LOG_ERR, "Cannot create data object. %s (%d)",
|
||||
strerror(errno), errno);
|
||||
|
||||
prop_object_release(cfg);
|
||||
return;
|
||||
}
|
||||
|
||||
for (n = i = 0 ; i < HCI_KEY_SIZE ; i++) {
|
||||
keybuf[n++] = hex[(key[i] >> 4) & 0xf];
|
||||
keybuf[n++] = hex[key[i] & 0xf];
|
||||
if (!prop_dictionary_set(dev, bt_ntoa(raddr, NULL), dat)) {
|
||||
syslog(LOG_ERR, "prop_dictionary_set() failed. %s (%d)",
|
||||
strerror(errno), errno);
|
||||
|
||||
prop_object_release(dat);
|
||||
prop_object_release(cfg);
|
||||
return;
|
||||
}
|
||||
keybuf[n] = '\0';
|
||||
|
||||
n = snprintf(buffer, sizeof(buffer),
|
||||
"\ndevice {\n"
|
||||
"\tbdaddr %s;\n"
|
||||
"\tkey 0x%s;\n"
|
||||
"}\n",
|
||||
bt_ntoa(raddr, NULL),
|
||||
keybuf);
|
||||
xml = prop_dictionary_externalize(cfg);
|
||||
if (xml == NULL) {
|
||||
syslog(LOG_ERR, "prop_dictionary_externalize() failed. %s (%d)",
|
||||
strerror(errno), errno);
|
||||
|
||||
write(fd, buffer, (size_t)n);
|
||||
prop_object_release(cfg);
|
||||
return;
|
||||
}
|
||||
|
||||
prop_object_release(cfg);
|
||||
|
||||
fd = open(new_key_file, O_WRONLY|O_TRUNC|O_CREAT|O_EXLOCK, 0600);
|
||||
if (fd < 0) {
|
||||
syslog(LOG_ERR, "Cannot open new keyfile %s. %s (%d)",
|
||||
key_file, strerror(errno), errno);
|
||||
|
||||
free(xml);
|
||||
return;
|
||||
}
|
||||
|
||||
len = strlen(xml);
|
||||
if (write(fd, xml, len) != len) {
|
||||
syslog(LOG_ERR, "Write of keyfile failed. %s (%d)",
|
||||
strerror(errno), errno);
|
||||
|
||||
free(xml);
|
||||
close(fd);
|
||||
unlink(new_key_file);
|
||||
return;
|
||||
}
|
||||
|
||||
free(xml);
|
||||
close(fd);
|
||||
|
||||
if (rename(new_key_file, key_file) < 0) {
|
||||
syslog(LOG_ERR, "rename(%s, %s) failed. %s (%d)",
|
||||
new_key_file, key_file, strerror(errno), errno);
|
||||
|
||||
unlink(new_key_file);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user