* Re: [Bluez-devel] Bluetooth device name database
[not found] ` <5.1.0.14.2.20020919094030.07a2c388@mail1.qualcomm.com>
@ 2002-09-24 2:38 ` Takashi Sasai
0 siblings, 0 replies; only message in thread
From: Takashi Sasai @ 2002-09-24 2:38 UTC (permalink / raw)
To: Maksim (Max) Krasnyanskiy; +Cc: David LIBAULT, bluez-devel
[-- Attachment #1: Type: text/plain, Size: 653 bytes --]
Hi Max and David,
> >libbluetooth ? Do you mean that libbluetooth should provide a way to read
> >from the name database ? In that case, it should also provide methods to
> >access the link_key database (to remove a subscription), doesn't it ?
> Something like that.
>
> >An other question : if an application (link key managment software) wants to
> >modify the link_key file, and hcid receives a connection at the same time...
> >Is there some kind of lock so that the link key file is always consistent ?
> Currently no. But writes to a file are almost guarantied to be atomic.
I wrote such a code before. How about this pache?
Regards,
Takashi
[-- Attachment #2: bluez-libs-2.0-rmkey.patch --]
[-- Type: application/octet-stream, Size: 4118 bytes --]
diff -uNr bluez-libs-2.0.orig/include/hci_lib.h bluez-libs-2.0/include/hci_lib.h
--- bluez-libs-2.0.orig/include/hci_lib.h Mon Aug 26 08:55:00 2002
+++ bluez-libs-2.0/include/hci_lib.h Thu Sep 5 11:10:41 2002
@@ -161,6 +161,10 @@
return (f->opcode == opcode);
}
+/* for HCId */
+int remove_link_key(int dev_id, bdaddr_t *dba);
+int show_link_keys(void);
+
#ifdef __cplusplus
}
#endif
diff -uNr bluez-libs-2.0.orig/src/hci.c bluez-libs-2.0/src/hci.c
--- bluez-libs-2.0.orig/src/hci.c Mon Aug 26 08:55:00 2002
+++ bluez-libs-2.0/src/hci.c Thu Sep 5 11:12:44 2002
@@ -47,6 +47,8 @@
#include <hci.h>
#include <hci_lib.h>
+#include <sys/file.h>
+
typedef struct {
char *str; unsigned int val;
} hci_map;
@@ -1000,3 +1002,164 @@
return -1;
return 0;
}
+
+/* for HCId */
+
+#define HCID_KEY_FILE "/etc/bluetooth/link_key"
+
+struct link_key {
+ bdaddr_t sba;
+ bdaddr_t dba;
+ uint8_t key[16];
+ uint8_t type;
+ time_t time;
+};
+
+/* Read exactly len bytes */
+static inline int read_n(int fd, void *buf, int len)
+{
+ register int t = 0, w;
+
+ while (len > 0) {
+ if ((w = read(fd, buf, len)) < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ return -1;
+ }
+ if (!w)
+ return 0;
+ len -= w;
+ buf += w;
+ t += w;
+ }
+
+ return t;
+}
+
+/* Write exactly len bytes */
+static inline int write_n(int fd, void *buf, int len)
+{
+ register int t = 0, w;
+
+ while (len > 0) {
+ if ((w = write(fd, buf, len)) < 0) {
+ if (errno == EINTR || errno == EAGAIN)
+ continue;
+ return -1;
+ }
+ if (!w)
+ return 0;
+ len -= w;
+ buf += w;
+ t += w;
+ }
+
+ return t;
+}
+
+int remove_link_key(int dev_id, bdaddr_t *dba)
+{
+ char sa[40], da[40];
+ bdaddr_t sba;
+ static struct link_key k;
+ struct link_key *key = NULL;
+ struct link_key *keydb = NULL;
+ int i, r, f, exist, err, size, keynum;
+
+ if ((dev_id < 0) && (dev_id = hci_get_route(dba)) < 0) {
+ return -1;
+ }
+
+ if (hci_devba(dev_id, &sba) < 0) {
+ return -1;
+ }
+
+ ba2str(&sba, sa); ba2str(dba, da);
+
+ f = open(HCID_KEY_FILE, O_RDWR, 0);
+ if (f < 0) {
+ syslog(LOG_ERR, "Link key database open failed. %s(%d)",
+ strerror(errno), errno);
+ return -1;
+ }
+
+ flock(f, LOCK_EX);
+ err = 0;
+ exist = 0;
+
+ size = lseek(f, 0, SEEK_END);
+ if ((size > 0) && (size%sizeof(k) == 0)) {
+ keydb = (struct link_key *)malloc(size);
+ if (keydb == NULL) {
+ err = -1;
+ goto done;
+ }
+ keynum = size/sizeof(k);
+ } else {
+ syslog(LOG_INFO, "%s link key %s %s", exist ? "Remove" : "Not found",
+ sa, da);
+ err = -1;
+ goto done;
+ }
+
+ key = keydb;
+ lseek(f, 0, SEEK_SET);
+ while ((r = read_n(f, &k, sizeof(k)))) {
+ if (!bacmp(&k.sba, &sba) && !bacmp(&k.dba, dba)) {
+ exist = 1;
+ } else {
+ *key = k; key++;
+ }
+ }
+
+ if (exist) {
+ key = keydb;
+ lseek(f, 0, SEEK_SET);
+ ftruncate(f, 0);
+ lseek(f, 0, SEEK_SET);
+ for (i = 0; i < keynum-1; i++) {
+ if ((write_n(f, key, sizeof(*key)) < 0)) {
+ syslog(LOG_ERR, "Link key database write failed. %s(%d)",
+ strerror(errno), errno);
+ err = -1;
+ goto done;
+ }
+ key++;
+ }
+ }
+
+ ba2str(&sba, sa); ba2str(dba, da);
+ syslog(LOG_INFO, "%s link key %s %s", exist ? "Remove" : "Not found",
+ sa, da);
+
+done:
+ free(keydb);
+ flock(f, LOCK_UN);
+ close(f);
+ return err;
+}
+
+int show_link_keys()
+{
+ char sa[40], da[40];
+ static struct link_key k;
+ int r, f;
+
+ f = open(HCID_KEY_FILE, O_RDONLY, 0);
+ if (f < 0) {
+ syslog(LOG_ERR, "Link key database open failed. %s(%d)",
+ strerror(errno), errno);
+ return -1;
+ }
+
+ flock(f, LOCK_EX);
+
+ while ((r = read_n(f, &k, sizeof(k)))) {
+ ba2str(&k.sba, sa); ba2str(&k.dba, da);
+ printf("\t%s - %s\n", sa, da);
+ }
+
+ flock(f, LOCK_UN);
+ close(f);
+ return 0;
+}
[-- Attachment #3: bluez-utils-2.0-rmkey.patch --]
[-- Type: application/octet-stream, Size: 3098 bytes --]
diff -uNr bluez-utils-2.0.orig/hcid/security.c bluez-utils-2.0/hcid/security.c
--- bluez-utils-2.0.orig/hcid/security.c Fri Jul 19 03:12:46 2002
+++ bluez-utils-2.0/hcid/security.c Thu Aug 8 17:09:58 2002
@@ -51,6 +51,8 @@
#include "hcid.h"
#include "lib.h"
+#include <sys/file.h>
+
static GIOChannel *io_chan[HCI_MAX_DEV];
static int pairing;
@@ -95,8 +97,11 @@
int f;
f = open(hcid.key_file, O_RDONLY);
- if (f >= 0)
+ if (f >= 0) {
+ flock(f, LOCK_EX);
key = __get_link_key(f, sba, dba);
+ flock(f, LOCK_UN);
+ }
else if (errno != ENOENT)
syslog(LOG_ERR, "Link key database open failed. %s(%d)",
strerror(errno), errno);
@@ -135,6 +140,8 @@
return;
}
+ flock(f, LOCK_EX);
+
/* Check if key already exist */
exist = __get_link_key(f, &key->sba, &key->dba);
@@ -149,6 +156,7 @@
if (err < 0) {
syslog(LOG_ERR, "Link key database seek failed. %s(%d)",
strerror(errno), errno);
+ flock(f, LOCK_UN);
goto failed;
}
@@ -159,6 +167,7 @@
ba2str(&key->sba, sa); ba2str(&key->dba, da);
syslog(LOG_INFO, "%s link key %s %s", exist ? "Replacing" : "Saving", sa, da);
+ flock(f, LOCK_UN);
failed:
close(f);
diff -uNr bluez-utils-2.0.orig/tools/hcitool.c bluez-utils-2.0/tools/hcitool.c
--- bluez-utils-2.0.orig/tools/hcitool.c Tue Jun 25 13:36:09 2002
+++ bluez-utils-2.0/tools/hcitool.c Fri Aug 9 17:21:38 2002
@@ -865,6 +865,78 @@
free(cr);
}
+/* Remove link key */
+
+static struct option rmkey_options[] = {
+ {"help", 0,0, 'h'},
+ {0, 0, 0, 0}
+};
+
+static char *rmkey_help =
+ "Usage:\n"
+ "\trmkey <bdaddr>\n";
+
+static void cmd_rmkey(int dev_id, int argc, char **argv)
+{
+ bdaddr_t bdaddr;
+ int opt, dd;
+
+ for_each_opt(opt, rmkey_options, NULL) {
+ switch(opt) {
+ default:
+ printf(rmkey_help);
+ return;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc < 1) {
+ printf(rmkey_help);
+ return;
+ }
+
+ baswap(&bdaddr, strtoba(argv[0]));
+
+ if (dev_id < 0) {
+ dev_id = hci_get_route(&bdaddr);
+ if (dev_id < 0) {
+ fprintf(stderr, "Device is not available.\n");
+ exit(1);
+ }
+ }
+
+ if (remove_link_key(dev_id, &bdaddr) == 0)
+ printf("ok\n");
+
+}
+
+/* Display link keys */
+
+static struct option keys_options[] = {
+ {"help", 0,0, 'h'},
+ {0, 0, 0, 0}
+};
+
+static char *keys_help =
+ "Usage:\n"
+ "\tkeys\n";
+
+static void cmd_keys(int dev_id, int argc, char **argv)
+{
+ int opt;
+ for_each_opt(opt, keys_options, NULL) {
+ switch(opt) {
+ default:
+ printf(keys_help);
+ return;
+ }
+ }
+
+ printf("Keys:\n");
+ show_link_keys();
+}
+
struct {
char *cmd;
@@ -882,6 +954,10 @@
{ "dc", cmd_dc, "Disconnect from remote device" },
{ "cpt", cmd_cpt, "Change connection packet type" },
{ "rssi", cmd_rssi, "Display connection RSSI" },
+
+ { "rmkey", cmd_rmkey, "Remove link key" },
+ { "keys", cmd_keys, "Show link keys" },
+
{ NULL, NULL, 0}
};
^ permalink raw reply [flat|nested] only message in thread