Add a new utility 'btkey' for managment of Bluetooth Link Keys stored

in the NetBSD key cache (/var/db/bthcid.keys) and Bluetooth controller
memory.
This commit is contained in:
plunky 2007-11-09 21:18:22 +00:00
parent 985d6fdf0b
commit e5a7441d16
12 changed files with 978 additions and 20 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.725 2007/11/08 20:14:07 drochner Exp $
# $NetBSD: mi,v 1.726 2007/11/09 21:18:22 plunky Exp $
. base-sys-root
./altroot base-sys-root
./bin base-sys-root
@ -421,6 +421,7 @@
./usr/bin/bdes base-crypto-bin crypto
./usr/bin/biff base-mail-bin
./usr/bin/bthset base-util-bin
./usr/bin/btkey base-util-bin
./usr/bin/btpin base-util-bin
./usr/bin/bunzip2 base-util-bin
./usr/bin/bzcat base-util-bin

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1077 2007/11/06 23:39:25 ad Exp $
# $NetBSD: mi,v 1.1078 2007/11/09 21:18:23 plunky Exp $
./etc/mtree/set.comp comp-sys-root
./usr/bin/addr2line comp-debug-bin bfd
./usr/bin/ar comp-util-bin bfd
@ -2388,6 +2388,7 @@
./usr/libdata/debug/usr/bin/bdes.debug comp-crypto-debug crypto,debug
./usr/libdata/debug/usr/bin/biff.debug comp-mail-debug debug
./usr/libdata/debug/usr/bin/bthset.debug comp-util-debug debug
./usr/libdata/debug/usr/bin/btkey.debug comp-util-debug debug
./usr/libdata/debug/usr/bin/btpin.debug comp-util-debug debug
./usr/libdata/debug/usr/bin/bzip2.debug comp-util-debug debug
./usr/libdata/debug/usr/bin/bzip2recover.debug comp-util-debug debug

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1032 2007/10/29 00:54:18 xtraeme Exp $
# $NetBSD: mi,v 1.1033 2007/11/09 21:18:24 plunky Exp $
./etc/mtree/set.man man-sys-root
./usr/share/info/am-utils.info man-amd-info info
./usr/share/info/as.info man-computil-info bfd,info
@ -62,6 +62,7 @@
./usr/share/man/cat1/biff.0 man-mail-catman .cat
./usr/share/man/cat1/bpm.0 man-pkgutil-catman .cat
./usr/share/man/cat1/bthset.0 man-util-catman .cat
./usr/share/man/cat1/btkey.0 man-util-catman .cat
./usr/share/man/cat1/btpin.0 man-util-catman .cat
./usr/share/man/cat1/bunzip2.0 man-util-catman .cat
./usr/share/man/cat1/bzcat.0 man-util-catman .cat
@ -2559,6 +2560,7 @@
./usr/share/man/man1/biff.1 man-mail-man .man
./usr/share/man/man1/bpm.1 man-pkgutil-man .man
./usr/share/man/man1/bthset.1 man-util-man .man
./usr/share/man/man1/btkey.1 man-util-man .man
./usr/share/man/man1/btpin.1 man-util-man .man
./usr/share/man/man1/bunzip2.1 man-util-man .man
./usr/share/man/man1/bzcat.1 man-util-man .man

View File

@ -1,9 +1,10 @@
# $NetBSD: Makefile,v 1.158 2007/06/21 14:09:23 ginsbach Exp $
# $NetBSD: Makefile,v 1.159 2007/11/09 21:18:24 plunky Exp $
# from: @(#)Makefile 8.3 (Berkeley) 1/7/94
.include <bsd.own.mk>
SUBDIR= apply apropos asa at audio awk banner basename biff bthset btpin \
SUBDIR= apply apropos asa at audio awk \
banner basename biff bthset btkey btpin \
bzip2 bzip2recover cal calendar cap_mkdb cdplay \
checknr chflags chpass cksum cmp col colcrt colrm \
column comm compress config crontab crunch csplit ctags cut \

10
usr.bin/btkey/Makefile Normal file
View File

@ -0,0 +1,10 @@
# $NetBSD: Makefile,v 1.1 2007/11/09 21:18:24 plunky Exp $
PROG= btkey
SRCS= btkey.c device.c file.c
MAN= btkey.1
DPADD+= ${LIBBLUETOOTH} ${LIBPROP}
LDADD+= -lbluetooth -lprop
.include <bsd.prog.mk>

130
usr.bin/btkey/btkey.1 Normal file
View File

@ -0,0 +1,130 @@
.\" $NetBSD: btkey.1,v 1.1 2007/11/09 21:18:25 plunky Exp $
.\"
.\" Copyright (c) 2007 Iain Hibbert
.\" 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.
.\" 3. The name of the author may not be used to endorse or promote products
.\" derived from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
.\"
.Dd November 8, 2007
.Dt BTKEY 1
.Os
.Sh NAME
.Nm btkey
.Nd Bluetooth Link Key management utility
.Sh SYNOPSIS
.Nm
.Op Fl cCrRwW
.Op Fl k Ar key
.Fl a Ar address
.Fl d Ar device
.Nm
.Fl lL
.Op Fl d Ar device
.Sh DESCRIPTION
The
.Nm
program is used to manage Bluetooth Link Key storage.
Keys are normally handled by the
.Xr bthcid 8
daemon which caches them in the
.Pa /var/db/bthcid.keys
file and provides them as required when Bluetooth connections
need to be authenticated.
.Pp
These keys are required for connections between remote
devices and the specific controller
.Pq not the Operating System
and so for multi-boot systems where it may not always be possible to
specify the same key across all OS's it can be better to have the
Bluetooth controller provide the keys directly from its semi-permanent
memory once devices are paired.
.Nm
will read, write or clear keys in device memory or the key cache
as required.
.Pp
Note that without the
.Xr bthcid 8
daemon running users will be unable to supply PINs, and Link Keys
resulting from new pairings will not be stored.
If no new pairings are expected and the keys are stored in
the controller then
.Xr bthcid 8
is not required.
.Pp
The options are as follows:
.Bl -tag -width ".Fl a Ar address"
.It Fl a Ar address
Specify the remote device address.
May be given as a BDADDR or a name.
.It Fl c
Clear key from file.
.It Fl C
Clear key from device.
.It Fl d Ar device
Specify the local device address.
May be given as a BDADDR or a name.
.It Fl k Ar key
Supply a Link Key as a string of hexadecimal digits.
Up to 32 digits will be processed and the resulting key
will be zero padded to 16 octets.
.It Fl l
List keys stored in file.
.It Fl L
List keys stored in device.
.It Fl r
Read key from file.
.It Fl R
Read key from device.
.It Fl w
Write key to file.
.It Fl W
Write key to device.
.El
.Pp
Super-user privileges are required to read or write link keys.
.Sh EXAMPLES
.Pp
Read key for mouse at ubt0 from file and write to device
.Pp
.Dl btkey -d ubt0 -a mouse -rW
.Pp
Write new key for keyboard at ubt0 to file
.Pp
.Dl btkey -d ubt0 -a keyboard -k 92beda6cd8b8f66ebd2af270d55d70ec -w
.Pp
Clear key for phone at bt3c0 from file and device
.Pp
.Dl btkey -d bt3c0 -a phone -cC
.Pp
.Sh EXIT STATUS
.Ex -std
.Sh FILES
.Bl -tag -compact
.Pa /var/db/bthcid.keys
.El
.Sh SEE ALSO
.Xr btpin 1 ,
.Xr btconfig 8 ,
.Xr bthcid 8
.Sh AUTHORS
.An Iain Hibbert

300
usr.bin/btkey/btkey.c Normal file
View File

@ -0,0 +1,300 @@
/* $NetBSD: btkey.c,v 1.1 2007/11/09 21:18:25 plunky Exp $ */
/*-
* Copyright (c) 2007 Iain Hibbert
* 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
*/
#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 2007 Iain Hibbert\n"
"All rights reserved.\n");
__RCSID("$NetBSD: btkey.c,v 1.1 2007/11/09 21:18:25 plunky Exp $");
#include <bluetooth.h>
#include <err.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "btkey.h"
static void usage(void);
static bool scan_key(const char *);
bdaddr_t laddr;
bdaddr_t raddr;
uint8_t key[HCI_KEY_SIZE];
int
main(int ac, char *av[])
{
struct hostent *he;
int ch;
bool cf, cd, lf, ld, rf, rd, wf, wd, nk;
memset(&laddr, 0, sizeof(laddr));
memset(&raddr, 0, sizeof(raddr));
memset(key, 0, sizeof(key));
cf = cd = lf = ld = rf = rd = wf = wd = nk = false;
while ((ch = getopt(ac, av, "a:cCd:k:lLrRwW")) != EOF) {
switch (ch) {
case 'a': /* remote device address */
if (!bt_aton(optarg, &raddr)) {
he = bt_gethostbyname(optarg);
if (he == NULL)
errx(EXIT_FAILURE, "%s: %s",
optarg, hstrerror(h_errno));
bdaddr_copy(&raddr, (bdaddr_t *)he->h_addr);
}
break;
case 'c': /* clear from file */
cf = true;
break;
case 'C': /* clear from device */
cd = true;
break;
case 'd': /* local device address */
if (!bt_devaddr(optarg, &laddr)
&& !bt_aton(optarg, &laddr)) {
he = bt_gethostbyname(optarg);
if (he == NULL)
errx(EXIT_FAILURE, "%s: %s",
optarg, hstrerror(h_errno));
bdaddr_copy(&laddr, (bdaddr_t *)he->h_addr);
}
break;
case 'k': /* new link key */
if (!scan_key(optarg))
errx(EXIT_FAILURE, "invalid key '%s'", optarg);
nk = true;
break;
case 'l': /* list from file */
lf = true;
break;
case 'L': /* list from device */
ld = true;
break;
case 'r': /* read from file */
rf = true;
break;
case 'R': /* read from device */
rd = true;
break;
case 'w': /* write to file */
wf = true;
break;
case 'W': /* write to device */
wd = true;
break;
default:
usage();
}
}
ac -= optind;
av += optind;
/*
* validate options
*/
if ((lf || ld) && (rf || rd || wf || wd || cf || cd || nk))
errx(EXIT_FAILURE, "list is exclusive of other options");
if (((rf && rd) || (rf && nk) || (rd && nk)) && (wf || wd))
errx(EXIT_FAILURE, "too many key sources");
if (((bdaddr_any(&laddr) || bdaddr_any(&raddr)) && !(lf || ld))
|| ((lf || ld) && (bdaddr_any(&laddr) || !bdaddr_any(&raddr)))
|| ac > 0)
usage();
/*
* do what we gotta do and be done
*/
if (!bdaddr_any(&laddr))
print_addr("device", &laddr);
if (!bdaddr_any(&raddr))
print_addr("bdaddr", &raddr);
if (lf && !list_file())
err(EXIT_FAILURE, "list file");
if (ld && !list_device())
err(EXIT_FAILURE, "list device");
if (nk)
print_key("new key", key);
if (rf) {
if (!read_file())
err(EXIT_FAILURE, "file key");
print_key("file key", key);
}
if (rd) {
if (!read_device())
err(EXIT_FAILURE, "device key");
print_key("device key", key);
}
if (wf || wd || cf || cd)
printf("\n");
if (wf) {
if (!write_file())
err(EXIT_FAILURE, "write to file");
printf("written to file\n");
}
if (wd) {
if (!write_device())
err(EXIT_FAILURE, "write to device");
printf("written to device\n");
}
if (cf) {
if (!clear_file())
err(EXIT_FAILURE, "clear from file");
printf("cleared from file\n");
}
if (cd) {
if (!clear_device())
err(EXIT_FAILURE, "clear from device");
printf("cleared from device\n");
}
exit(EXIT_SUCCESS);
}
static void
usage(void)
{
fprintf(stderr,
"Usage: %s [-cCrRwW] [-k key] -a address -d device\n"
" %s -lL -d device\n"
"\n", getprogname(), getprogname());
fprintf(stderr,
"Where:\n"
"\t-a address remote device address\n"
"\t-c clear from file\n"
"\t-C clear from device\n"
"\t-d device local device address\n"
"\t-k key user specified link_key\n"
"\t-l list file keys\n"
"\t-L list device keys\n"
"\t-r read from file\n"
"\t-R read from device\n"
"\t-w write to file\n"
"\t-W write to device\n"
"\n");
exit(EXIT_FAILURE);
}
static bool
scan_key(const char *arg)
{
static const char digits[] = "0123456789abcdef";
const char *p;
int i, j;
memset(key, 0, sizeof(key));
for (i = 0 ; i < HCI_KEY_SIZE ; i++) {
for (j = 0 ; j < 2 ; j++) {
if (*arg == '\0')
return true;
for (p = digits ; *p != *arg ; p++)
if (*p == '\0')
return false;
arg++;
key[i] = (key[i] << 4) + (p - digits);
}
}
if (*arg != '\0')
return false;
return true;
}
void
print_key(const char *type, const uint8_t *src)
{
int i;
printf("%10s: ", type);
for (i = 0 ; i < HCI_KEY_SIZE ; i++)
printf("%2.2x", src[i]);
printf("\n");
}
void
print_addr(const char *type, const bdaddr_t *addr)
{
char name[HCI_DEVNAME_SIZE];
struct hostent *he;
printf("%10s: %s", type, bt_ntoa(addr, NULL));
if (bt_devname(name, addr))
printf(" (%s)", name);
else if ((he = bt_gethostbyaddr((const char *)addr,
sizeof(bdaddr_t), AF_BLUETOOTH)) != NULL)
printf(" (%s)", he->h_name);
printf("\n");
}

48
usr.bin/btkey/btkey.h Normal file
View File

@ -0,0 +1,48 @@
/* $NetBSD: btkey.h,v 1.1 2007/11/09 21:18:25 plunky Exp $ */
/*-
* Copyright (c) 2007 Iain Hibbert
* 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
*/
/* btkey.c */
extern bdaddr_t laddr;
extern bdaddr_t raddr;
extern uint8_t key[];
void print_key(const char *, const uint8_t *);
void print_addr(const char *, const bdaddr_t *);
/* device.c */
bool list_device(void);
bool read_device(void);
bool write_device(void);
bool clear_device(void);
/* file.c */
bool list_file(void);
bool read_file(void);
bool write_file(void);
bool clear_file(void);

265
usr.bin/btkey/device.c Normal file
View File

@ -0,0 +1,265 @@
/* $NetBSD: device.c,v 1.1 2007/11/09 21:18:25 plunky Exp $ */
/*-
* Copyright (c) 2007 Iain Hibbert
* 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: device.c,v 1.1 2007/11/09 21:18:25 plunky Exp $");
#include <bluetooth.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include "btkey.h"
/*
* read/write stored link keys packet, with space for one key
*/
struct stored_link_keys {
uint8_t num_keys;
struct {
bdaddr_t addr;
uint8_t key[HCI_KEY_SIZE];
} key[1];
} __attribute__ ((__packed__));
/*
* generic request
*
* send command 'opcode' with command packet 'cptr' of size 'clen'
* call 'func_cc' on command_complete event
* call 'func_ev' on event 'event'
* callbacks return -1 (failure), 0 (continue) or 1 (success)
*/
static bool
hci_req(uint16_t opcode, void *cptr, size_t clen, int (*func_cc)(void *),
uint8_t event, int (*func_ev)(void *))
{
uint8_t buf[sizeof(hci_cmd_hdr_t) + HCI_CMD_PKT_SIZE];
struct sockaddr_bt sa;
struct hci_filter f;
hci_cmd_hdr_t *hdr;
hci_event_hdr_t *ep;
int fd, rv;
memset(&f, 0, sizeof(f));
hci_filter_set(HCI_EVENT_COMMAND_COMPL, &f);
if (event != 0) hci_filter_set(event, &f);
memset(&sa, 0, sizeof(sa));
sa.bt_len = sizeof(sa);
sa.bt_family = AF_BLUETOOTH;
bdaddr_copy(&sa.bt_bdaddr, &laddr);
hdr = (hci_cmd_hdr_t *)buf;
hdr->type = HCI_CMD_PKT;
hdr->opcode = htole16(opcode);
hdr->length = clen;
memcpy(buf + sizeof(hci_cmd_hdr_t), cptr, clen);
rv = -1;
if ((fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI)) < 0
|| setsockopt(fd, BTPROTO_HCI, SO_HCI_EVT_FILTER, &f, sizeof(f)) < 0
|| bind(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0
|| connect(fd, (struct sockaddr *)&sa, sizeof(sa)) < 0
|| send(fd, buf, sizeof(hci_cmd_hdr_t) + clen, 0) < 0)
goto done;
ep = (hci_event_hdr_t *)buf;
for (;;) {
if (recv(fd, buf, sizeof(buf), 0) < 0)
goto done;
if (ep->event == HCI_EVENT_COMMAND_COMPL) {
hci_command_compl_ep *cc;
cc = (hci_command_compl_ep *)(ep + 1);
if (opcode != le16toh(cc->opcode))
continue;
rv = func_cc(cc + 1);
if (rv == 0)
continue;
goto done;
}
if (event != 0 && event == ep->event) {
rv = func_ev(ep + 1);
if (rv == 0)
continue;
goto done;
}
}
done:
if (fd >= 0) close(fd);
return rv > 0 ? true : false;
}
/*
* List keys on device
*/
static int
list_device_cc(void *arg)
{
hci_read_stored_link_key_rp *rp = arg;
if (rp->status)
return -1;
printf("\n");
printf("read %d keys (max %d)\n", rp->num_keys_read, rp->max_num_keys);
return 1;
}
static int
list_device_ev(void *arg)
{
struct stored_link_keys *ep = arg;
int i;
for (i = 0 ; i < ep->num_keys ; i++) {
printf("\n");
print_addr("bdaddr", &ep->key[i].addr);
print_key("device key", ep->key[i].key);
}
return 0;
}
bool
list_device(void)
{
hci_read_stored_link_key_cp cp;
bdaddr_copy(&cp.bdaddr, BDADDR_ANY);
cp.read_all = 0x01;
return hci_req(HCI_CMD_READ_STORED_LINK_KEY,
&cp, sizeof(cp), list_device_cc,
HCI_EVENT_RETURN_LINK_KEYS, list_device_ev);
}
/*
* Read key from device
*/
static int
read_device_cc(void *arg)
{
/* if we got here, no key was found */
return -1;
}
static int
read_device_ev(void *arg)
{
struct stored_link_keys *ep = arg;
if (ep->num_keys != 1
|| !bdaddr_same(&ep->key[0].addr, &raddr))
return 0;
memcpy(key, ep->key[0].key, HCI_KEY_SIZE);
return 1;
}
bool
read_device(void)
{
hci_read_stored_link_key_cp cp;
bdaddr_copy(&cp.bdaddr, &raddr);
cp.read_all = 0x00;
return hci_req(HCI_CMD_READ_STORED_LINK_KEY,
&cp, sizeof(cp), read_device_cc,
HCI_EVENT_RETURN_LINK_KEYS, read_device_ev);
}
/*
* Write key to device
*/
static int
write_device_cc(void *arg)
{
hci_write_stored_link_key_rp *rp = arg;
if (rp->status || rp->num_keys_written != 1)
return -1;
return 1;
}
bool
write_device(void)
{
struct stored_link_keys cp;
cp.num_keys = 1;
bdaddr_copy(&cp.key[0].addr, &raddr);
memcpy(cp.key[0].key, key, HCI_KEY_SIZE);
return hci_req(HCI_CMD_WRITE_STORED_LINK_KEY,
&cp, sizeof(cp), write_device_cc,
0, NULL);
}
/*
* Clear key from device
*/
static int
clear_device_cc(void *arg)
{
hci_delete_stored_link_key_rp *rp = arg;
if (rp->status || rp->num_keys_deleted != 1)
return -1;
return 1;
}
bool
clear_device(void)
{
hci_delete_stored_link_key_cp cp;
cp.delete_all = 0x00;
bdaddr_copy(&cp.bdaddr, &raddr);
return hci_req(HCI_CMD_DELETE_STORED_LINK_KEY,
&cp, sizeof(cp), clear_device_cc,
0, NULL);
}

202
usr.bin/btkey/file.c Normal file
View File

@ -0,0 +1,202 @@
/* $NetBSD: file.c,v 1.1 2007/11/09 21:18:25 plunky Exp $ */
/*-
* Copyright (c) 2007 Iain Hibbert
* 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.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: file.c,v 1.1 2007/11/09 21:18:25 plunky Exp $");
#include <sys/stat.h>
#include <prop/proplib.h>
#include <bluetooth.h>
#include <stdbool.h>
#include <string.h>
#include "btkey.h"
static const char *key_file = "/var/db/bthcid.keys";
/*
* List keys file.
*/
bool
list_file(void)
{
prop_dictionary_t db, dev;
prop_object_iterator_t iter;
prop_dictionary_keysym_t sym;
prop_object_t dat;
bdaddr_t bdaddr;
bool rv = false;
db = prop_dictionary_internalize_from_file(key_file);
if (db == NULL)
return false;
dev = prop_dictionary_get(db, bt_ntoa(&laddr, NULL));
if (prop_object_type(dev) != PROP_TYPE_DICTIONARY)
goto done;
iter = prop_dictionary_iterator(dev);
if (iter == NULL)
goto done;
while ((sym = prop_object_iterator_next(iter)) != NULL) {
memset(&bdaddr, 0, sizeof(bdaddr));
bt_aton(prop_dictionary_keysym_cstring_nocopy(sym), &bdaddr);
if (bdaddr_any(&bdaddr))
continue;
dat = prop_dictionary_get_keysym(dev, sym);
if (prop_data_size(dat) != HCI_KEY_SIZE)
continue;
printf("\n");
print_addr("bdaddr", &bdaddr);
print_key("file key", prop_data_data_nocopy(dat));
}
prop_object_iterator_release(iter);
rv = true;
done:
prop_object_release(db);
return rv;
}
/*
* Read from keys file.
*/
bool
read_file(void)
{
prop_dictionary_t db, dev;
prop_object_t dat;
bool rv = false;
db = prop_dictionary_internalize_from_file(key_file);
if (db == NULL)
return false;
dev = prop_dictionary_get(db, bt_ntoa(&laddr, NULL));
if (prop_object_type(dev) != PROP_TYPE_DICTIONARY)
goto done;
dat = prop_dictionary_get(dev, bt_ntoa(&raddr, NULL));
if (prop_data_size(dat) != HCI_KEY_SIZE)
goto done;
memcpy(key, prop_data_data_nocopy(dat), HCI_KEY_SIZE);
rv = true;
done:
prop_object_release(db);
return rv;
}
/*
* Write to keys file.
*/
bool
write_file(void)
{
prop_dictionary_t db, dev;
prop_data_t dat;
mode_t mode;
bool rv = false;
db = prop_dictionary_internalize_from_file(key_file);
if (db == NULL) {
db = prop_dictionary_create();
if (db == NULL)
return false;
}
dev = prop_dictionary_get(db, bt_ntoa(&laddr, NULL));
if (dev == NULL) {
dev = prop_dictionary_create();
if (dev == NULL)
goto done;
rv = prop_dictionary_set(db, bt_ntoa(&laddr, NULL), dev);
prop_object_release(dev);
if (rv == false)
goto done;
}
dat = prop_data_create_data_nocopy(key, HCI_KEY_SIZE);
if (dat == NULL)
goto done;
rv = prop_dictionary_set(dev, bt_ntoa(&raddr, NULL), dat);
prop_object_release(dat);
if (rv == false)
goto done;
mode = umask(S_IRWXG | S_IRWXO);
rv = prop_dictionary_externalize_to_file(db, key_file);
umask(mode);
done:
prop_object_release(db);
return rv;
}
/*
* Clear from keys file.
*/
bool
clear_file(void)
{
prop_dictionary_t db, dev;
prop_data_t dat;
mode_t mode;
bool rv = false;
db = prop_dictionary_internalize_from_file(key_file);
if (db == NULL)
return false;
dev = prop_dictionary_get(db, bt_ntoa(&laddr, NULL));
if (dev == NULL)
goto done;
dat = prop_dictionary_get(dev, bt_ntoa(&raddr, NULL));
if (prop_data_size(dat) != HCI_KEY_SIZE)
goto done;
prop_dictionary_remove(dev, bt_ntoa(&raddr, NULL));
mode = umask(S_IRWXG | S_IRWXO);
rv = prop_dictionary_externalize_to_file(db, key_file);
umask(mode);
done:
prop_object_release(db);
return rv;
}

View File

@ -1,4 +1,4 @@
.\" $NetBSD: btpin.1,v 1.6 2007/09/24 19:29:01 plunky Exp $
.\" $NetBSD: btpin.1,v 1.7 2007/11/09 21:18:24 plunky Exp $
.\"
.\" Copyright (c) 2006 Itronix Inc.
.\" All rights reserved.
@ -84,6 +84,7 @@ The default path is
.Pa /var/run/bthcid
.El
.Sh SEE ALSO
.Xr btkey 1 ,
.Xr btconfig 8 ,
.Xr bthcid 8
.Sh AUTHORS

View File

@ -1,4 +1,4 @@
.\" $NetBSD: bthcid.8,v 1.5 2006/10/03 02:04:42 wiz Exp $
.\" $NetBSD: bthcid.8,v 1.6 2007/11/09 21:18:24 plunky 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.5 2006/10/03 02:04:42 wiz Exp $
.\" $Id: bthcid.8,v 1.6 2007/11/09 21:18:24 plunky Exp $
.\" $FreeBSD: src/usr.sbin/bluetooth/hcsecd/hcsecd.8,v 1.6 2006/02/11 15:36:37 markus Exp $
.\"
.Dd September 29, 2006
@ -72,7 +72,7 @@
.Sh DESCRIPTION
The
.Nm
daemon manages link keys and PIN codes for Bluetooth devices.
daemon handles Link Key and PIN code requests for Bluetooth devices.
It opens a raw HCI socket and listens for the following HCI events.
.Pp
.Bl -tag -width XXXX -compact
@ -116,6 +116,13 @@ to the cache prior to pairing with the
utility.
.El
.Pp
Some of the functionality of
.Nm
can be handled by the Bluetooth controller directly, and cached Link
Keys may be examined, deleted or moved to device storage using the
.Xr btkey 1
program.
.Pp
The command line options are as follows:
.Bl -tag -width XXXX
.It Fl d Ar device
@ -143,6 +150,7 @@ The default path is
.El
.Sh SEE ALSO
.Xr btpin 1 ,
.Xr btkey 1 ,
.Xr bluetooth 4 ,
.Xr btconfig 8
.Sh HISTORY
@ -160,14 +168,3 @@ under the sponsorship of Itronix, Inc.
.Sh AUTHORS
.An Maksim Yevmenkin Aq m_evmenkin@yahoo.com
.An Iain Hibbert
.Sh BUGS
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.