Commit 03b555e1 authored by Johan Hedberg's avatar Johan Hedberg Committed by Gustavo F. Padovan

Bluetooth: Reject pairing requests when in non-pairable mode

This patch adds the necessary logic to act accordingly when the
HCI_PAIRABLE flag is not set. In that case PIN code replies as well as
Secure Simple Pairing requests without a NoBonding requirement need to
be rejected.
Signed-off-by: default avatarJohan Hedberg <johan.hedberg@nokia.com>
Signed-off-by: default avatarGustavo F. Padovan <padovan@profusion.mobi>
parent 930e1336
...@@ -384,6 +384,12 @@ struct hci_cp_reject_sync_conn_req { ...@@ -384,6 +384,12 @@ struct hci_cp_reject_sync_conn_req {
__u8 reason; __u8 reason;
} __packed; } __packed;
#define HCI_OP_IO_CAPABILITY_NEG_REPLY 0x0434
struct hci_cp_io_capability_neg_reply {
bdaddr_t bdaddr;
__u8 reason;
} __packed;
#define HCI_OP_SNIFF_MODE 0x0803 #define HCI_OP_SNIFF_MODE 0x0803
struct hci_cp_sniff_mode { struct hci_cp_sniff_mode {
__le16 handle; __le16 handle;
...@@ -840,6 +846,14 @@ struct hci_ev_io_capa_request { ...@@ -840,6 +846,14 @@ struct hci_ev_io_capa_request {
bdaddr_t bdaddr; bdaddr_t bdaddr;
} __packed; } __packed;
#define HCI_EV_IO_CAPA_REPLY 0x32
struct hci_ev_io_capa_reply {
bdaddr_t bdaddr;
__u8 capability;
__u8 oob_data;
__u8 authentication;
} __packed;
#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36
struct hci_ev_simple_pair_complete { struct hci_ev_simple_pair_complete {
__u8 status; __u8 status;
......
...@@ -201,6 +201,10 @@ struct hci_conn { ...@@ -201,6 +201,10 @@ struct hci_conn {
__u16 disc_timeout; __u16 disc_timeout;
unsigned long pend; unsigned long pend;
__u8 remote_cap;
__u8 remote_oob;
__u8 remote_auth;
unsigned int sent; unsigned int sent;
struct sk_buff_head data_q; struct sk_buff_head data_q;
......
...@@ -1595,6 +1595,10 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff ...@@ -1595,6 +1595,10 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
hci_conn_put(conn); hci_conn_put(conn);
} }
if (!test_bit(HCI_PAIRABLE, &hdev->flags))
hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
sizeof(ev->bdaddr), &ev->bdaddr);
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
...@@ -1885,9 +1889,52 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff ...@@ -1885,9 +1889,52 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
hci_dev_lock(hdev); hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (conn) if (!conn)
goto unlock;
hci_conn_hold(conn); hci_conn_hold(conn);
if (!test_bit(HCI_MGMT, &hdev->flags))
goto unlock;
if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
(conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
/* FIXME: Do IO capa response based on information
* provided through the management interface */
} else {
struct hci_cp_io_capability_neg_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
cp.reason = 0x16; /* Pairing not allowed */
hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
sizeof(cp), &cp);
}
unlock:
hci_dev_unlock(hdev);
}
static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
struct hci_ev_io_capa_reply *ev = (void *) skb->data;
struct hci_conn *conn;
BT_DBG("%s", hdev->name);
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
if (!conn)
goto unlock;
hci_conn_hold(conn);
conn->remote_cap = ev->capability;
conn->remote_oob = ev->oob_data;
conn->remote_auth = ev->authentication;
unlock:
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
...@@ -2051,6 +2098,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -2051,6 +2098,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_io_capa_request_evt(hdev, skb); hci_io_capa_request_evt(hdev, skb);
break; break;
case HCI_EV_IO_CAPA_REPLY:
hci_io_capa_reply_evt(hdev, skb);
break;
case HCI_EV_SIMPLE_PAIR_COMPLETE: case HCI_EV_SIMPLE_PAIR_COMPLETE:
hci_simple_pair_complete_evt(hdev, skb); hci_simple_pair_complete_evt(hdev, skb);
break; break;
......
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