diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2010-06-07 11:32:22 +0800 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2010-06-12 18:37:10 +0800 |
commit | a30b7569ba6867f58f62634a894d0aabde01280d (patch) | |
tree | 0c229ee81b001dccf84182d4af1516c3cd0bbaa8 /src | |
parent | e5e25c761845284c6aca75599bc75c8e0d901311 (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.c | 37 | ||||
-rw-r--r-- | src/dbus-hci.h | 5 | ||||
-rw-r--r-- | src/device.c | 27 | ||||
-rw-r--r-- | src/device.h | 2 | ||||
-rw-r--r-- | src/hcid.h | 1 | ||||
-rw-r--r-- | src/main.c | 7 | ||||
-rw-r--r-- | src/main.conf | 5 | ||||
-rw-r--r-- | src/security.c | 38 |
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, @@ -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; @@ -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); } } |