diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2011-01-04 08:40:05 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-02-07 22:40:06 -0500 |
commit | 03b555e119de8288a16e086e1fbd223d9b429d3d (patch) | |
tree | 5f0dd5efc8439ba4300761bc9ebba22c3d718c06 | |
parent | 930e13363fb0e94db6e8b59c54dfb5c59355113e (diff) |
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: Johan Hedberg <johan.hedberg@nokia.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
-rw-r--r-- | include/net/bluetooth/hci.h | 14 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 4 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 55 |
3 files changed, 71 insertions, 2 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index f0c25b5ba4b2..65cab137e19f 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -384,6 +384,12 @@ struct hci_cp_reject_sync_conn_req { | |||
384 | __u8 reason; | 384 | __u8 reason; |
385 | } __packed; | 385 | } __packed; |
386 | 386 | ||
387 | #define HCI_OP_IO_CAPABILITY_NEG_REPLY 0x0434 | ||
388 | struct hci_cp_io_capability_neg_reply { | ||
389 | bdaddr_t bdaddr; | ||
390 | __u8 reason; | ||
391 | } __packed; | ||
392 | |||
387 | #define HCI_OP_SNIFF_MODE 0x0803 | 393 | #define HCI_OP_SNIFF_MODE 0x0803 |
388 | struct hci_cp_sniff_mode { | 394 | struct hci_cp_sniff_mode { |
389 | __le16 handle; | 395 | __le16 handle; |
@@ -840,6 +846,14 @@ struct hci_ev_io_capa_request { | |||
840 | bdaddr_t bdaddr; | 846 | bdaddr_t bdaddr; |
841 | } __packed; | 847 | } __packed; |
842 | 848 | ||
849 | #define HCI_EV_IO_CAPA_REPLY 0x32 | ||
850 | struct hci_ev_io_capa_reply { | ||
851 | bdaddr_t bdaddr; | ||
852 | __u8 capability; | ||
853 | __u8 oob_data; | ||
854 | __u8 authentication; | ||
855 | } __packed; | ||
856 | |||
843 | #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 | 857 | #define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 |
844 | struct hci_ev_simple_pair_complete { | 858 | struct hci_ev_simple_pair_complete { |
845 | __u8 status; | 859 | __u8 status; |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 8ee0b8bac77c..dc8084a139ed 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -201,6 +201,10 @@ struct hci_conn { | |||
201 | __u16 disc_timeout; | 201 | __u16 disc_timeout; |
202 | unsigned long pend; | 202 | unsigned long pend; |
203 | 203 | ||
204 | __u8 remote_cap; | ||
205 | __u8 remote_oob; | ||
206 | __u8 remote_auth; | ||
207 | |||
204 | unsigned int sent; | 208 | unsigned int sent; |
205 | 209 | ||
206 | struct sk_buff_head data_q; | 210 | struct sk_buff_head data_q; |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index a8a38f17ef78..cf3014ae00e4 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1595,6 +1595,10 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff | |||
1595 | hci_conn_put(conn); | 1595 | hci_conn_put(conn); |
1596 | } | 1596 | } |
1597 | 1597 | ||
1598 | if (!test_bit(HCI_PAIRABLE, &hdev->flags)) | ||
1599 | hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY, | ||
1600 | sizeof(ev->bdaddr), &ev->bdaddr); | ||
1601 | |||
1598 | hci_dev_unlock(hdev); | 1602 | hci_dev_unlock(hdev); |
1599 | } | 1603 | } |
1600 | 1604 | ||
@@ -1885,9 +1889,52 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff | |||
1885 | hci_dev_lock(hdev); | 1889 | hci_dev_lock(hdev); |
1886 | 1890 | ||
1887 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | 1891 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); |
1888 | if (conn) | 1892 | if (!conn) |
1889 | hci_conn_hold(conn); | 1893 | goto unlock; |
1894 | |||
1895 | hci_conn_hold(conn); | ||
1896 | |||
1897 | if (!test_bit(HCI_MGMT, &hdev->flags)) | ||
1898 | goto unlock; | ||
1899 | |||
1900 | if (test_bit(HCI_PAIRABLE, &hdev->flags) || | ||
1901 | (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) { | ||
1902 | /* FIXME: Do IO capa response based on information | ||
1903 | * provided through the management interface */ | ||
1904 | } else { | ||
1905 | struct hci_cp_io_capability_neg_reply cp; | ||
1906 | |||
1907 | bacpy(&cp.bdaddr, &ev->bdaddr); | ||
1908 | cp.reason = 0x16; /* Pairing not allowed */ | ||
1890 | 1909 | ||
1910 | hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY, | ||
1911 | sizeof(cp), &cp); | ||
1912 | } | ||
1913 | |||
1914 | unlock: | ||
1915 | hci_dev_unlock(hdev); | ||
1916 | } | ||
1917 | |||
1918 | static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb) | ||
1919 | { | ||
1920 | struct hci_ev_io_capa_reply *ev = (void *) skb->data; | ||
1921 | struct hci_conn *conn; | ||
1922 | |||
1923 | BT_DBG("%s", hdev->name); | ||
1924 | |||
1925 | hci_dev_lock(hdev); | ||
1926 | |||
1927 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | ||
1928 | if (!conn) | ||
1929 | goto unlock; | ||
1930 | |||
1931 | hci_conn_hold(conn); | ||
1932 | |||
1933 | conn->remote_cap = ev->capability; | ||
1934 | conn->remote_oob = ev->oob_data; | ||
1935 | conn->remote_auth = ev->authentication; | ||
1936 | |||
1937 | unlock: | ||
1891 | hci_dev_unlock(hdev); | 1938 | hci_dev_unlock(hdev); |
1892 | } | 1939 | } |
1893 | 1940 | ||
@@ -2051,6 +2098,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) | |||
2051 | hci_io_capa_request_evt(hdev, skb); | 2098 | hci_io_capa_request_evt(hdev, skb); |
2052 | break; | 2099 | break; |
2053 | 2100 | ||
2101 | case HCI_EV_IO_CAPA_REPLY: | ||
2102 | hci_io_capa_reply_evt(hdev, skb); | ||
2103 | break; | ||
2104 | |||
2054 | case HCI_EV_SIMPLE_PAIR_COMPLETE: | 2105 | case HCI_EV_SIMPLE_PAIR_COMPLETE: |
2055 | hci_simple_pair_complete_evt(hdev, skb); | 2106 | hci_simple_pair_complete_evt(hdev, skb); |
2056 | break; | 2107 | break; |