diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2009-01-12 15:01:50 +0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2009-01-12 15:01:50 +0200 |
commit | dd10ec5d830d2e2187f93bd2d7e60be947335f0b (patch) | |
tree | e91c559960faeb964967defe2dfdecf1af5e1df7 | |
parent | 7d76a4c7336d3694ec259bd409a725c3e3b9edd0 (diff) |
Add support for dedicated bonding using BT_SECURITY
-rw-r--r-- | src/dbus-common.c | 6 | ||||
-rw-r--r-- | src/dbus-common.h | 3 | ||||
-rw-r--r-- | src/device.c | 27 |
3 files changed, 29 insertions, 7 deletions
diff --git a/src/dbus-common.c b/src/dbus-common.c index d430e408..7c26a8f7 100644 --- a/src/dbus-common.c +++ b/src/dbus-common.c @@ -54,7 +54,8 @@ #define RECONNECT_RETRY_TIMEOUT 5000 -int l2raw_connect(const bdaddr_t *src, const bdaddr_t *dst) +int l2raw_connect(const bdaddr_t *src, const bdaddr_t *dst, + struct bt_security *sec) { struct sockaddr_l2 addr; long arg; @@ -75,6 +76,9 @@ int l2raw_connect(const bdaddr_t *src, const bdaddr_t *dst) goto failed; } + if (sec) + setsockopt(sk, SOL_BLUETOOTH, BT_SECURITY, sec, sizeof(*sec)); + arg = fcntl(sk, F_GETFL); if (arg < 0) { error("Can't get file flags: %s (%d)", strerror(errno), errno); diff --git a/src/dbus-common.h b/src/dbus-common.h index 35aa6157..e6b6117d 100644 --- a/src/dbus-common.h +++ b/src/dbus-common.h @@ -23,7 +23,8 @@ #define MAX_PATH_LENGTH 64 -int l2raw_connect(const bdaddr_t *src, const bdaddr_t *dst); +int l2raw_connect(const bdaddr_t *src, const bdaddr_t *dst, + struct bt_security *sec); void hcid_dbus_exit(void); int hcid_dbus_init(void); diff --git a/src/device.c b/src/device.c index 8317dcb9..ad78be2d 100644 --- a/src/device.c +++ b/src/device.c @@ -72,6 +72,7 @@ struct bonding_req { GIOChannel *io; guint io_id; guint listener_id; + gboolean auth_required; struct btd_device *device; }; @@ -1545,9 +1546,7 @@ static gboolean create_bonding_io_cb(GIOChannel *io, GIOCondition cond, socklen_t len; int sk, dd, ret; - if (!device->bonding) { - /* If we come here it implies a bug somewhere */ - debug("create_bonding_io_cb: no pending bonding!"); + if (!device->bonding || !device->bonding->auth_required) { g_io_channel_close(io); return FALSE; } @@ -1687,8 +1686,10 @@ DBusMessage *device_create_bonding(struct btd_device *device, char *str, srcaddr[18], dstaddr[18]; struct btd_adapter *adapter = device->adapter; struct bonding_req *bonding; + struct bt_security sec; bdaddr_t src; - int sk; + int sk, err; + socklen_t len; adapter_get_address(adapter, &src); ba2str(&src, srcaddr); @@ -1709,7 +1710,10 @@ DBusMessage *device_create_bonding(struct btd_device *device, "Bonding already exists"); } - sk = l2raw_connect(&src, &device->bdaddr); + memset(&sec, 0, sizeof(sec)); + sec.level = BT_SECURITY_HIGH; + + sk = l2raw_connect(&src, &device->bdaddr, &sec); if (sk < 0) return g_dbus_create_error(msg, ERROR_INTERFACE ".ConnectionAttemptFailed", @@ -1722,6 +1726,19 @@ DBusMessage *device_create_bonding(struct btd_device *device, return NULL; } + memset(&sec, 0, sizeof(sec)); + len = sizeof(sec); + + err = getsockopt(sk, SOL_BLUETOOTH, BT_SECURITY, &sec, &len); + if (err < 0) { + debug("BT_SECURITY failed: %s (%s), probably an old kernel", + strerror(errno), errno); + bonding->auth_required = TRUE; + } else if (sec.level == BT_SECURITY_HIGH) + bonding->auth_required = FALSE; + else + bonding->auth_required = TRUE; + bonding->io = g_io_channel_unix_new(sk); bonding->io_id = g_io_add_watch(bonding->io, G_IO_OUT | G_IO_NVAL | G_IO_HUP | G_IO_ERR, |