summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2009-01-12 15:01:50 +0200
committerJohan Hedberg <johan.hedberg@nokia.com>2009-01-12 15:01:50 +0200
commitdd10ec5d830d2e2187f93bd2d7e60be947335f0b (patch)
treee91c559960faeb964967defe2dfdecf1af5e1df7
parent7d76a4c7336d3694ec259bd409a725c3e3b9edd0 (diff)
Add support for dedicated bonding using BT_SECURITY
-rw-r--r--src/dbus-common.c6
-rw-r--r--src/dbus-common.h3
-rw-r--r--src/device.c27
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,