summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-06-16 01:49:07 +0000
committerMarcel Holtmann <marcel@holtmann.org>2008-06-16 01:49:07 +0000
commitb509da915a937dc34d37d12ff1e45c1b3105aeb2 (patch)
tree1436bb99c5a80b8789d35d6778111f1b6f507ce6
parent48e457f024ec0ee3fdf00687a26c2ffdf11ec1ca (diff)
Improve the auth requirement handling
-rw-r--r--hcid/dbus-hci.c75
-rw-r--r--hcid/dbus-hci.h8
-rw-r--r--hcid/security.c8
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) {