From b509da915a937dc34d37d12ff1e45c1b3105aeb2 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 16 Jun 2008 01:49:07 +0000 Subject: Improve the auth requirement handling --- hcid/dbus-hci.c | 75 +++++++++++++++++++++++++++++++++++---------------------- hcid/dbus-hci.h | 8 ------ hcid/security.c | 8 +++--- 3 files changed, 51 insertions(+), 40 deletions(-) diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c index 8700f4d1..8b9aff86 100644 --- a/hcid/dbus-hci.c +++ b/hcid/dbus-hci.c @@ -1016,7 +1016,8 @@ static void passkey_cb(struct agent *agent, DBusError *err, uint32_t passkey, hci_close_dev(dd); } -static uint8_t get_auth_requirements(bdaddr_t *local, bdaddr_t *remote) +static int get_auth_requirements(bdaddr_t *local, bdaddr_t *remote, + uint8_t *auth) { struct hci_auth_info_req req; char addr[18]; @@ -1026,24 +1027,29 @@ static uint8_t get_auth_requirements(bdaddr_t *local, bdaddr_t *remote) dev_id = hci_devid(addr); if (dev_id < 0) - return 0xff; + return dev_id; dd = hci_open_dev(dev_id); if (dd < 0) - return 0xff; + return dd; memset(&req, 0, sizeof(req)); bacpy(&req.bdaddr, remote); - req.type = 0xff; err = ioctl(dd, HCIGETAUTHINFO, (unsigned long) &req); - if (err < 0) - debug("HCIGETAUTHINFO failed: %s (%d)", strerror(errno), - errno); + if (err < 0) { + debug("HCIGETAUTHINFO failed: %s (%d)", + strerror(errno), errno); + hci_close_dev(dd); + return err; + } hci_close_dev(dd); - return req.type; + if (auth) + *auth = req.type; + + return 0; } int hcid_dbus_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) @@ -1061,13 +1067,7 @@ int hcid_dbus_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) return -1; } - type = get_auth_requirements(sba, dba); - - debug("kernel authentication requirement = 0x%02x", type); - - /* If no MITM protection reqiured, auto-accept */ - if (type != 0xff && !(type & 0x01)) { - user_confirm_reply_cp cp; + if (get_auth_requirements(sba, dba, &type) < 0) { int dd; dd = hci_open_dev(adapter->dev_id); @@ -1076,11 +1076,8 @@ int hcid_dbus_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) return -1; } - memset(&cp, 0, sizeof(cp)); - bacpy(&cp.bdaddr, dba); - - hci_send_cmd(dd, OGF_LINK_CTL, OCF_USER_CONFIRM_REPLY, - USER_CONFIRM_REPLY_CP_SIZE, &cp); + hci_send_cmd(dd, OGF_LINK_CTL, + OCF_USER_CONFIRM_NEG_REPLY, 6, dba); hci_close_dev(dd); @@ -1090,7 +1087,30 @@ int hcid_dbus_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) ba2str(dba, addr); device = adapter_get_device(connection, adapter, addr); - if (device && device->agent) + if (!device) { + error("Device creation failed"); + return -1; + } + + /* If no MITM protection required, auto-accept */ + if (!(device->auth & 0x01) && !(type & 0x01)) { + int dd; + + dd = hci_open_dev(adapter->dev_id); + if (dd < 0) { + error("Unable to open hci%d", adapter->dev_id); + return -1; + } + + hci_send_cmd(dd, OGF_LINK_CTL, + OCF_USER_CONFIRM_REPLY, 6, dba); + + hci_close_dev(dd); + + return 0; + } + + if (device->agent) agent = device->agent; else agent = adapter->agent; @@ -1101,7 +1121,7 @@ int hcid_dbus_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) } if (agent_request_confirmation(agent, device, passkey, - confirm_cb, device) < 0) { + confirm_cb, device) < 0) { error("Requesting passkey failed"); return -1; } @@ -2433,7 +2453,6 @@ int hcid_dbus_get_io_cap(bdaddr_t *local, bdaddr_t *remote, struct device *device; struct agent *agent; char addr[18]; - uint8_t type; adapter = manager_find_adapter(local); if (!adapter) { @@ -2441,11 +2460,8 @@ int hcid_dbus_get_io_cap(bdaddr_t *local, bdaddr_t *remote, return -1; } - type = get_auth_requirements(local, remote); - - debug("kernel authentication requirement = 0x%02x", type); - - *auth = (type == 0xff) ? 0x00 : type; + if (get_auth_requirements(local, remote, auth) < 0) + return -1; ba2str(remote, addr); @@ -2457,7 +2473,8 @@ int hcid_dbus_get_io_cap(bdaddr_t *local, bdaddr_t *remote, agent = adapter->agent; if (!agent) { - if (!(type & 0x01)) { + if (!(*auth & 0x01)) { + /* No input, no output */ *cap = 0x03; return 0; } diff --git a/hcid/dbus-hci.h b/hcid/dbus-hci.h index 9f53957a..cb618816 100644 --- a/hcid/dbus-hci.h +++ b/hcid/dbus-hci.h @@ -22,14 +22,6 @@ * */ -#ifndef HCIGETAUTHINFO -#define HCIGETAUTHINFO _IOR('H', 215, int) -struct hci_auth_info_req { - bdaddr_t bdaddr; - uint8_t type; -}; -#endif - void hcid_dbus_set_experimental(); int hcid_dbus_use_experimental(); int hcid_dbus_register_device(uint16_t id); diff --git a/hcid/security.c b/hcid/security.c index bc807377..71cd5e4e 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -287,13 +287,15 @@ static void link_key_request(int dev, bdaddr_t *sba, bdaddr_t *dba) memset(&req, 0, sizeof(req)); bacpy(&req.bdaddr, dba); - req.type = 0xff; err = ioctl(dev, HCIGETAUTHINFO, (unsigned long) &req); if (err < 0) - debug("HCIGETAUTHINFO failed (%d)", errno); + debug("HCIGETAUTHINFO failed (%d)", + strerror(errno), errno); + else + req.type = 0x00; - debug("kernel authentication requirement = 0x%02x", req.type); + debug("kernel auth requirements = 0x%02x", req.type); err = read_link_key(sba, dba, key, &type); if (err < 0) { -- cgit