Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 255835
b: refs/heads/master
c: f1cb9af
h: refs/heads/master
i:
  255833: a099357
  255831: c5c289b
v: v3
  • Loading branch information
Vinicius Costa Gomes authored and Gustavo F. Padovan committed Jun 13, 2011
1 parent 68e57cb commit 1e16ae6
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 43 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9b3d67405b17d61ba8be9d824222fb410f487b8a
refs/heads/master: f1cb9af557dd8fb5d98fbcc4b5d3eb9d6d235af7
61 changes: 31 additions & 30 deletions trunk/net/bluetooth/l2cap_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,23 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
bh_unlock_sock(parent);
}

static void l2cap_chan_ready(struct sock *sk)
{
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct sock *parent = bt_sk(sk)->parent;

BT_DBG("sk %p, parent %p", sk, parent);

chan->conf_state = 0;
__clear_chan_timer(chan);

sk->sk_state = BT_CONNECTED;
sk->sk_state_change(sk);

if (parent)
parent->sk_data_ready(parent, 0);
}

static void l2cap_conn_ready(struct l2cap_conn *conn)
{
struct l2cap_chan *chan;
Expand All @@ -906,13 +923,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)

bh_lock_sock(sk);

if (conn->hcon->type == LE_LINK) {
__clear_chan_timer(chan);
l2cap_state_change(chan, BT_CONNECTED);
sk->sk_state_change(sk);
if (conn->hcon->type == LE_LINK)
if (smp_conn_security(conn, chan->sec_level))
BT_DBG("Insufficient security");
}
l2cap_chan_ready(sk);

if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
__clear_chan_timer(chan);
Expand Down Expand Up @@ -1675,30 +1688,6 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len)
return err;
}

static void l2cap_chan_ready(struct sock *sk)
{
struct sock *parent = bt_sk(sk)->parent;
struct l2cap_chan *chan = l2cap_pi(sk)->chan;

BT_DBG("sk %p, parent %p", sk, parent);

chan->conf_state = 0;
__clear_chan_timer(chan);

if (!parent) {
/* Outgoing channel.
* Wake up socket sleeping on connect.
*/
l2cap_state_change(chan, BT_CONNECTED);
sk->sk_state_change(sk);
} else {
/* Incoming channel.
* Wake up socket sleeping on accept.
*/
parent->sk_data_ready(parent, 0);
}
}

/* Copy frame to all raw sockets on that connection */
static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
{
Expand Down Expand Up @@ -4188,6 +4177,18 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)

bh_lock_sock(sk);

BT_DBG("chan->scid %d", chan->scid);

if (chan->scid == L2CAP_CID_LE_DATA) {
if (!status && encrypt) {
chan->sec_level = hcon->sec_level;
l2cap_chan_ready(sk);
}

bh_unlock_sock(sk);
continue;
}

if (chan->conf_state & L2CAP_CONF_CONNECT_PEND) {
bh_unlock_sock(sk);
continue;
Expand Down
16 changes: 16 additions & 0 deletions trunk/net/bluetooth/l2cap_sock.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/smp.h>

static const struct proto_ops l2cap_sock_ops;
static void l2cap_sock_init(struct sock *sk, struct sock *parent);
Expand Down Expand Up @@ -562,6 +563,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
struct l2cap_chan *chan = l2cap_pi(sk)->chan;
struct bt_security sec;
struct bt_power pwr;
struct l2cap_conn *conn;
int len, err = 0;
u32 opt;

Expand Down Expand Up @@ -598,6 +600,20 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, ch
}

chan->sec_level = sec.level;

conn = chan->conn;
if (conn && chan->scid == L2CAP_CID_LE_DATA) {
if (!conn->hcon->out) {
err = -EINVAL;
break;
}

if (smp_conn_security(conn, sec.level))
break;

err = 0;
sk->sk_state = BT_CONFIG;
}
break;

case BT_DEFER_SETUP:
Expand Down
40 changes: 28 additions & 12 deletions trunk/net/bluetooth/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,13 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
{
struct smp_cmd_security_req *rp = (void *) skb->data;
struct smp_cmd_pairing cp;
struct hci_conn *hcon = conn->hcon;

BT_DBG("conn %p", conn);

if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
return;

skb_pull(skb, sizeof(*rp));
memset(&cp, 0, sizeof(cp));

Expand All @@ -353,6 +357,20 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
memcpy(&conn->preq[1], &cp, sizeof(cp));

smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);

set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
}

static __u8 seclevel_to_authreq(__u8 level)
{
switch (level) {
case BT_SECURITY_HIGH:
/* For now we don't support bonding */
return SMP_AUTH_MITM;

default:
return SMP_AUTH_NONE;
}
}

int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
Expand All @@ -365,21 +383,16 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
if (IS_ERR(hcon->hdev->tfm))
return 1;

switch (sec_level) {
case BT_SECURITY_MEDIUM:
/* Encrypted, no MITM protection */
authreq = HCI_AT_NO_BONDING_MITM;
break;
if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
return 0;

case BT_SECURITY_HIGH:
/* Bonding, MITM protection */
authreq = HCI_AT_GENERAL_BONDING_MITM;
break;
if (sec_level == BT_SECURITY_LOW)
return 1;

case BT_SECURITY_LOW:
default:
if (hcon->sec_level >= sec_level)
return 1;
}

authreq = seclevel_to_authreq(sec_level);

if (hcon->link_mode & HCI_LM_MASTER) {
struct smp_cmd_pairing cp;
Expand All @@ -400,6 +413,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
}

hcon->pending_sec_level = sec_level;
set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);

return 0;
}

Expand Down

0 comments on commit 1e16ae6

Please sign in to comment.