summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2010-06-07 11:32:22 +0800
committerJohan Hedberg <johan.hedberg@nokia.com>2010-06-12 18:37:10 +0800
commita30b7569ba6867f58f62634a894d0aabde01280d (patch)
tree0c229ee81b001dccf84182d4af1516c3cd0bbaa8 /src
parente5e25c761845284c6aca75599bc75c8e0d901311 (diff)
Store debug keys in runtime memory
This patch adds the possibility of using debug keys for consequtive connections by storing them in runtime memory instead of discarding them after the connection. This functionality can be enabled using a new DebugKeys boolean parameter in main.conf.
Diffstat (limited to 'src')
-rw-r--r--src/dbus-hci.c37
-rw-r--r--src/dbus-hci.h5
-rw-r--r--src/device.c27
-rw-r--r--src/device.h2
-rw-r--r--src/hcid.h1
-rw-r--r--src/main.c7
-rw-r--r--src/main.conf5
-rw-r--r--src/security.c38
8 files changed, 96 insertions, 26 deletions
diff --git a/src/dbus-hci.c b/src/dbus-hci.c
index a1f51ea4..19748a73 100644
--- a/src/dbus-hci.c
+++ b/src/dbus-hci.c
@@ -61,7 +61,7 @@
static DBusConnection *connection = NULL;
-static gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst,
+gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst,
struct btd_adapter **adapter,
struct btd_device **device,
gboolean create)
@@ -669,15 +669,19 @@ int hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
struct btd_device *device;
struct btd_adapter *adapter;
uint8_t local_auth = 0xff, remote_auth, new_key_type;
- gboolean bonding, stored;
+ gboolean bonding, temporary = FALSE;
if (!get_adapter_and_device(local, peer, &adapter, &device, TRUE))
return -ENODEV;
- if (key_type == 0x06 && old_key_type != 0xff)
- new_key_type = old_key_type;
- else
- new_key_type = key_type;
+ new_key_type = key_type;
+
+ if (key_type == 0x06) {
+ if (device_get_debug_key(device, NULL))
+ old_key_type = 0x03;
+ if (old_key_type != 0xff)
+ new_key_type = old_key_type;
+ }
get_auth_requirements(local, peer, &local_auth);
remote_auth = device_get_auth(device);
@@ -686,7 +690,12 @@ int hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
DBG("local auth 0x%02x and remote auth 0x%02x",
local_auth, remote_auth);
- /* Only store the link key if one of the following is true:
+ /* Clear any previous debug key */
+ device_set_debug_key(device, NULL);
+
+ /* Store the link key only in runtime memory if it's a debug
+ * key, else store the link key persistently if one of the
+ * following is true:
* 1. this is a legacy link key
* 2. this is a changed combination key and there was a previously
* stored one
@@ -694,8 +703,14 @@ int hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
* 4. the local side had dedicated bonding as a requirement
* 5. the remote side is using dedicated bonding since in that case
* also the local requirements are set to dedicated bonding
+ * If none of the above match only keep the link key around for
+ * this connection and set the temporary flag for the device.
*/
- if (key_type < 0x03 || (key_type == 0x06 && old_key_type != 0xff) ||
+ if (new_key_type == 0x03) {
+ DBG("Storing debug key in runtime memory");
+ device_set_debug_key(device, key);
+ } else if (key_type < 0x03 ||
+ (key_type == 0x06 && old_key_type != 0xff) ||
(local_auth > 0x01 && remote_auth > 0x01) ||
(local_auth == 0x02 || local_auth == 0x03) ||
(remote_auth == 0x02 || remote_auth == 0x03)) {
@@ -709,10 +724,8 @@ int hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
error("write_link_key: %s (%d)", strerror(-err), -err);
return err;
}
-
- stored = TRUE;
} else
- stored = FALSE;
+ temporary = TRUE;
/* If this is not the first link key set a flag so a subsequent auth
* complete event doesn't trigger SDP */
@@ -724,7 +737,7 @@ int hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
else if (!bonding && old_key_type == 0xff)
hcid_dbus_bonding_process_complete(local, peer, 0);
- if (!stored)
+ if (temporary)
device_set_temporary(device, TRUE);
return 0;
diff --git a/src/dbus-hci.h b/src/dbus-hci.h
index 280f3908..a29dd533 100644
--- a/src/dbus-hci.h
+++ b/src/dbus-hci.h
@@ -45,6 +45,11 @@ int hcid_dbus_link_key_notify(bdaddr_t *local, bdaddr_t *peer,
uint8_t *key, uint8_t key_type,
int pin_length, uint8_t old_key_type);
+gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst,
+ struct btd_adapter **adapter,
+ struct btd_device **device,
+ gboolean create);
+
DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status);
const char *class_to_icon(uint32_t class);
diff --git a/src/device.c b/src/device.c
index de5e8e92..170902e0 100644
--- a/src/device.c
+++ b/src/device.c
@@ -143,6 +143,9 @@ struct btd_device {
gboolean authorizing;
gint ref;
+
+ gboolean has_debug_key;
+ uint8_t debug_key[16];
};
static uint16_t uuid_list[] = {
@@ -2430,6 +2433,30 @@ const sdp_record_t *btd_device_get_record(struct btd_device *device,
return find_record_in_list(device->tmp_records, uuid);
}
+gboolean device_set_debug_key(struct btd_device *device, uint8_t *key)
+{
+ if (key == NULL) {
+ device->has_debug_key = FALSE;
+ return TRUE;
+ }
+
+ memcpy(device->debug_key, key, 16);
+ device->has_debug_key = TRUE;
+
+ return TRUE;
+}
+
+gboolean device_get_debug_key(struct btd_device *device, uint8_t *key)
+{
+ if (!device->has_debug_key)
+ return FALSE;
+
+ if (key != NULL)
+ memcpy(key, device->debug_key, 16);
+
+ return TRUE;
+}
+
int btd_register_device_driver(struct btd_device_driver *driver)
{
device_drivers = g_slist_append(device_drivers, driver);
diff --git a/src/device.h b/src/device.h
index 79f44f85..5f75e61f 100644
--- a/src/device.h
+++ b/src/device.h
@@ -79,6 +79,8 @@ gboolean device_is_authenticating(struct btd_device *device);
gboolean device_is_authorizing(struct btd_device *device);
void device_set_authorizing(struct btd_device *device, gboolean auth);
void device_set_renewed_key(struct btd_device *device, gboolean renewed);
+gboolean device_set_debug_key(struct btd_device *device, uint8_t *key);
+gboolean device_get_debug_key(struct btd_device *device, uint8_t *key);
void device_add_connection(struct btd_device *device, DBusConnection *conn,
uint16_t handle);
void device_remove_connection(struct btd_device *device, DBusConnection *conn,
diff --git a/src/hcid.h b/src/hcid.h
index fd80309a..9c5f1d65 100644
--- a/src/hcid.h
+++ b/src/hcid.h
@@ -60,6 +60,7 @@ struct main_opts {
gboolean remember_powered;
gboolean reverse_sdp;
gboolean name_resolv;
+ gboolean debug_keys;
uint8_t scan;
uint8_t mode;
diff --git a/src/main.c b/src/main.c
index ba185236..b4e2219d 100644
--- a/src/main.c
+++ b/src/main.c
@@ -201,6 +201,13 @@ static void parse_config(GKeyFile *config)
else
main_opts.name_resolv = boolean;
+ boolean = g_key_file_get_boolean(config, "General",
+ "DebugKeys", &err);
+ if (err)
+ g_clear_error(&err);
+ else
+ main_opts.debug_keys = boolean;
+
main_opts.link_mode = HCI_LM_ACCEPT;
main_opts.link_policy = HCI_LP_RSWITCH | HCI_LP_SNIFF |
diff --git a/src/main.conf b/src/main.conf
index b252a824..59026dfa 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -50,3 +50,8 @@ ReverseServiceDiscovery = true
# Enable name resolving after inquiry. Set it to 'false' if you don't need
# remote devices name and want shorter discovery cycle. Defaults to 'true'.
NameResolving = true
+
+# Enable runtime persistency of debug link keys. Default is false which
+# makes debug link keys valid only for the duration of the connection
+# that they were created for.
+DebugKeys = false
diff --git a/src/security.c b/src/security.c
index 8eebb9bb..e8c463cd 100644
--- a/src/security.c
+++ b/src/security.c
@@ -51,6 +51,7 @@
#include "textfile.h"
#include "adapter.h"
+#include "device.h"
#include "dbus-hci.h"
#include "storage.h"
#include "manager.h"
@@ -301,12 +302,17 @@ static inline void update_lastused(bdaddr_t *sba, bdaddr_t *dba)
static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba)
{
+ struct btd_adapter *adapter;
+ struct btd_device *device;
struct hci_auth_info_req req;
unsigned char key[16];
char sa[18], da[18];
uint8_t type;
int err;
+ if (!get_adapter_and_device(sba, dba, &adapter, &device, FALSE))
+ device = NULL;
+
ba2str(sba, sa); ba2str(dba, da);
info("link_key_request (sba=%s, dba=%s)", sa, da);
@@ -323,26 +329,30 @@ static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba)
DBG("kernel auth requirements = 0x%02x", req.type);
- err = read_link_key(sba, dba, key, &type);
- if (err < 0) {
+ if (main_opts.debug_keys && device && device_get_debug_key(device, key))
+ type = 0x03;
+ else if (read_link_key(sba, dba, key, &type) < 0 || type == 0x03) {
/* Link key not found */
hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY, 6, dba);
- } else {
- /* Link key found */
+ return;
+ }
+
+ /* Link key found */
+
+ DBG("link key type = 0x%02x", type);
+
+ /* Don't use unauthenticated combination keys if MITM is
+ * required */
+ if (type == 0x04 && req.type != 0xff && (req.type & 0x01))
+ hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_NEG_REPLY,
+ 6, dba);
+ else {
link_key_reply_cp lr;
+
memcpy(lr.link_key, key, 16);
bacpy(&lr.bdaddr, dba);
- DBG("stored link key type = 0x%02x", type);
-
- /* Don't use debug link keys (0x03) and also don't use
- * unauthenticated combination keys if MITM is required */
- if (type == 0x03 || (type == 0x04 && req.type != 0xff &&
- (req.type & 0x01)))
- hci_send_cmd(dev, OGF_LINK_CTL,
- OCF_LINK_KEY_NEG_REPLY, 6, dba);
- else
- hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY,
+ hci_send_cmd(dev, OGF_LINK_CTL, OCF_LINK_KEY_REPLY,
LINK_KEY_REPLY_CP_SIZE, &lr);
}
}