Commit fd9ec7d3 authored by David S. Miller's avatar David S. Miller
parents 82a28c79 e7c29cb1
...@@ -325,7 +325,8 @@ int hci_conn_del(struct hci_conn *conn); ...@@ -325,7 +325,8 @@ int hci_conn_del(struct hci_conn *conn);
void hci_conn_hash_flush(struct hci_dev *hdev); void hci_conn_hash_flush(struct hci_dev *hdev);
void hci_conn_check_pending(struct hci_dev *hdev); void hci_conn_check_pending(struct hci_dev *hdev);
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *src); struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type);
int hci_conn_check_link_mode(struct hci_conn *conn);
int hci_conn_auth(struct hci_conn *conn); int hci_conn_auth(struct hci_conn *conn);
int hci_conn_encrypt(struct hci_conn *conn); int hci_conn_encrypt(struct hci_conn *conn);
int hci_conn_change_link_key(struct hci_conn *conn); int hci_conn_change_link_key(struct hci_conn *conn);
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
#define BT_DBG(D...) #define BT_DBG(D...)
#endif #endif
#define VERSION "2.12" #define VERSION "2.13"
/* Bluetooth sockets */ /* Bluetooth sockets */
#define BT_MAX_PROTO 8 #define BT_MAX_PROTO 8
......
...@@ -330,7 +330,7 @@ EXPORT_SYMBOL(hci_get_route); ...@@ -330,7 +330,7 @@ EXPORT_SYMBOL(hci_get_route);
/* Create SCO or ACL connection. /* Create SCO or ACL connection.
* Device _must_ be locked */ * Device _must_ be locked */
struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type)
{ {
struct hci_conn *acl; struct hci_conn *acl;
struct hci_conn *sco; struct hci_conn *sco;
...@@ -344,8 +344,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) ...@@ -344,8 +344,10 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
hci_conn_hold(acl); hci_conn_hold(acl);
if (acl->state == BT_OPEN || acl->state == BT_CLOSED) if (acl->state == BT_OPEN || acl->state == BT_CLOSED) {
acl->auth_type = auth_type;
hci_acl_connect(acl); hci_acl_connect(acl);
}
if (type == ACL_LINK) if (type == ACL_LINK)
return acl; return acl;
...@@ -374,6 +376,19 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst) ...@@ -374,6 +376,19 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst)
} }
EXPORT_SYMBOL(hci_connect); EXPORT_SYMBOL(hci_connect);
/* Check link security requirement */
int hci_conn_check_link_mode(struct hci_conn *conn)
{
BT_DBG("conn %p", conn);
if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0 &&
!(conn->link_mode & HCI_LM_ENCRYPT))
return 0;
return 1;
}
EXPORT_SYMBOL(hci_conn_check_link_mode);
/* Authenticate remote device */ /* Authenticate remote device */
int hci_conn_auth(struct hci_conn *conn) int hci_conn_auth(struct hci_conn *conn)
{ {
...@@ -381,7 +396,7 @@ int hci_conn_auth(struct hci_conn *conn) ...@@ -381,7 +396,7 @@ int hci_conn_auth(struct hci_conn *conn)
if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) {
if (!(conn->auth_type & 0x01)) { if (!(conn->auth_type & 0x01)) {
conn->auth_type = HCI_AT_GENERAL_BONDING_MITM; conn->auth_type |= 0x01;
conn->link_mode &= ~HCI_LM_AUTH; conn->link_mode &= ~HCI_LM_AUTH;
} }
} }
......
...@@ -1605,14 +1605,11 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b ...@@ -1605,14 +1605,11 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
if (conn->state == BT_CONFIG) { if (conn->state == BT_CONFIG) {
if (!ev->status && hdev->ssp_mode > 0 && if (!ev->status && hdev->ssp_mode > 0 &&
conn->ssp_mode > 0) { conn->ssp_mode > 0 && conn->out) {
if (conn->out) {
struct hci_cp_auth_requested cp; struct hci_cp_auth_requested cp;
cp.handle = ev->handle; cp.handle = ev->handle;
hci_send_cmd(hdev, hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED,
HCI_OP_AUTH_REQUESTED,
sizeof(cp), &cp); sizeof(cp), &cp);
}
} else { } else {
conn->state = BT_CONNECTED; conn->state = BT_CONNECTED;
hci_proto_connect_cfm(conn, ev->status); hci_proto_connect_cfm(conn, ev->status);
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
#define BT_DBG(D...) #define BT_DBG(D...)
#endif #endif
#define VERSION "2.10" #define VERSION "2.11"
static u32 l2cap_feat_mask = 0x0000; static u32 l2cap_feat_mask = 0x0000;
...@@ -778,6 +778,7 @@ static int l2cap_do_connect(struct sock *sk) ...@@ -778,6 +778,7 @@ static int l2cap_do_connect(struct sock *sk)
struct l2cap_conn *conn; struct l2cap_conn *conn;
struct hci_conn *hcon; struct hci_conn *hcon;
struct hci_dev *hdev; struct hci_dev *hdev;
__u8 auth_type;
int err = 0; int err = 0;
BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm); BT_DBG("%s -> %s psm 0x%2.2x", batostr(src), batostr(dst), l2cap_pi(sk)->psm);
...@@ -789,7 +790,21 @@ static int l2cap_do_connect(struct sock *sk) ...@@ -789,7 +790,21 @@ static int l2cap_do_connect(struct sock *sk)
err = -ENOMEM; err = -ENOMEM;
hcon = hci_connect(hdev, ACL_LINK, dst); if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH ||
l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT ||
l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) {
if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001))
auth_type = HCI_AT_NO_BONDING_MITM;
else
auth_type = HCI_AT_GENERAL_BONDING_MITM;
} else {
if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001))
auth_type = HCI_AT_NO_BONDING;
else
auth_type = HCI_AT_GENERAL_BONDING;
}
hcon = hci_connect(hdev, ACL_LINK, dst, auth_type);
if (!hcon) if (!hcon)
goto done; goto done;
...@@ -1553,7 +1568,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd ...@@ -1553,7 +1568,7 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
struct l2cap_conn_req *req = (struct l2cap_conn_req *) data; struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
struct l2cap_conn_rsp rsp; struct l2cap_conn_rsp rsp;
struct sock *sk, *parent; struct sock *sk, *parent;
int result, status = 0; int result, status = L2CAP_CS_NO_INFO;
u16 dcid = 0, scid = __le16_to_cpu(req->scid); u16 dcid = 0, scid = __le16_to_cpu(req->scid);
__le16 psm = req->psm; __le16 psm = req->psm;
...@@ -1567,6 +1582,13 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd ...@@ -1567,6 +1582,13 @@ static inline int l2cap_connect_req(struct l2cap_conn *conn, struct l2cap_cmd_hd
goto sendresp; goto sendresp;
} }
/* Check if the ACL is secure enough (if not SDP) */
if (psm != cpu_to_le16(0x0001) &&
!hci_conn_check_link_mode(conn->hcon)) {
result = L2CAP_CR_SEC_BLOCK;
goto response;
}
result = L2CAP_CR_NO_MEM; result = L2CAP_CR_NO_MEM;
/* Check for backlog size */ /* Check for backlog size */
...@@ -2224,7 +2246,7 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) ...@@ -2224,7 +2246,7 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status)
rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.result = cpu_to_le16(result); rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(0); rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
l2cap_send_cmd(conn, l2cap_pi(sk)->ident, l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
L2CAP_CONN_RSP, sizeof(rsp), &rsp); L2CAP_CONN_RSP, sizeof(rsp), &rsp);
} }
...@@ -2296,7 +2318,7 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) ...@@ -2296,7 +2318,7 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid);
rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid);
rsp.result = cpu_to_le16(result); rsp.result = cpu_to_le16(result);
rsp.status = cpu_to_le16(0); rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO);
l2cap_send_cmd(conn, l2cap_pi(sk)->ident, l2cap_send_cmd(conn, l2cap_pi(sk)->ident,
L2CAP_CONN_RSP, sizeof(rsp), &rsp); L2CAP_CONN_RSP, sizeof(rsp), &rsp);
} }
......
...@@ -200,7 +200,7 @@ static int sco_connect(struct sock *sk) ...@@ -200,7 +200,7 @@ static int sco_connect(struct sock *sk)
else else
type = SCO_LINK; type = SCO_LINK;
hcon = hci_connect(hdev, type, dst); hcon = hci_connect(hdev, type, dst, HCI_AT_NO_BONDING);
if (!hcon) if (!hcon)
goto done; goto done;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment