summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-02-09 02:48:38 +0100
committerMarcel Holtmann <marcel@holtmann.org>2009-02-27 06:14:40 +0100
commit0684e5f9fb9e3f7e168ab831dfca693bcb44805b (patch)
tree1fb1315dff64ef2ebaa24729988b2c3b7c77d578 /net
parentefc7688b557dd1be10eead7399b315efcb1dbc74 (diff)
Bluetooth: Use general bonding whenever possible
When receiving incoming connection to specific services, always use general bonding. This ensures that the link key gets stored and can be used for further authentications. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_conn.c23
-rw-r--r--net/bluetooth/l2cap.c16
-rw-r--r--net/bluetooth/rfcomm/core.c16
3 files changed, 39 insertions, 16 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 2435e830ba6..7fc4c048b57 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -391,19 +391,14 @@ int hci_conn_check_link_mode(struct hci_conn *conn)
EXPORT_SYMBOL(hci_conn_check_link_mode);
/* Authenticate remote device */
-static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level)
+static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
{
BT_DBG("conn %p", conn);
- if (sec_level > conn->sec_level)
- conn->link_mode &= ~HCI_LM_AUTH;
-
- conn->sec_level = sec_level;
-
- if (sec_level == BT_SECURITY_HIGH)
- conn->auth_type |= 0x01;
-
- if (conn->link_mode & HCI_LM_AUTH)
+ if (sec_level > conn->sec_level) {
+ conn->sec_level = sec_level;
+ conn->auth_type = auth_type;
+ } else if (conn->link_mode & HCI_LM_AUTH)
return 1;
if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
@@ -417,7 +412,7 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level)
}
/* Enable security */
-int hci_conn_security(struct hci_conn *conn, __u8 sec_level)
+int hci_conn_security(struct hci_conn *conn, __u8 sec_level, __u8 auth_type)
{
BT_DBG("conn %p", conn);
@@ -426,18 +421,18 @@ int hci_conn_security(struct hci_conn *conn, __u8 sec_level)
if (sec_level == BT_SECURITY_LOW) {
if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0)
- return hci_conn_auth(conn, sec_level);
+ return hci_conn_auth(conn, sec_level, auth_type);
else
return 1;
}
if (conn->link_mode & HCI_LM_ENCRYPT)
- return hci_conn_auth(conn, sec_level);
+ return hci_conn_auth(conn, sec_level, auth_type);
if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
return 0;
- if (hci_conn_auth(conn, sec_level)) {
+ if (hci_conn_auth(conn, sec_level, auth_type)) {
struct hci_cp_set_conn_encrypt cp;
cp.handle = cpu_to_le16(conn->handle);
cp.encrypt = 1;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index b677af671f3..8a93dde4095 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -263,8 +263,22 @@ static void l2cap_chan_del(struct sock *sk, int err)
static inline int l2cap_check_security(struct sock *sk)
{
struct l2cap_conn *conn = l2cap_pi(sk)->conn;
+ __u8 auth_type;
+
+ switch (l2cap_pi(sk)->sec_level) {
+ case BT_SECURITY_HIGH:
+ auth_type = HCI_AT_GENERAL_BONDING_MITM;
+ break;
+ case BT_SECURITY_MEDIUM:
+ auth_type = HCI_AT_GENERAL_BONDING;
+ break;
+ default:
+ auth_type = HCI_AT_NO_BONDING;
+ break;
+ }
- return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level);
+ return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level,
+ auth_type);
}
static inline u8 l2cap_get_ident(struct l2cap_conn *conn)
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 3717c25ba33..1828ec06ad1 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -226,8 +226,22 @@ static int rfcomm_l2sock_create(struct socket **sock)
static inline int rfcomm_check_security(struct rfcomm_dlc *d)
{
struct sock *sk = d->session->sock->sk;
+ __u8 auth_type;
- return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level);
+ switch (d->sec_level) {
+ case BT_SECURITY_HIGH:
+ auth_type = HCI_AT_GENERAL_BONDING_MITM;
+ break;
+ case BT_SECURITY_MEDIUM:
+ auth_type = HCI_AT_GENERAL_BONDING;
+ break;
+ default:
+ auth_type = HCI_AT_NO_BONDING;
+ break;
+ }
+
+ return hci_conn_security(l2cap_pi(sk)->conn->hcon, d->sec_level,
+ auth_type);
}
/* ---- RFCOMM DLCs ---- */