diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2011-01-17 07:41:05 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-02-07 22:40:07 -0500 |
commit | 55ed8ca10f3530de8edbbf138acb50992bf5005b (patch) | |
tree | 3145b2b995758b2cb64493fc8ec29e63d0e9f0b4 /net/bluetooth/hci_event.c | |
parent | 1aff6f09491f454d4cd9f405c783fa5e9d3168a0 (diff) |
Bluetooth: Implement link key handling for the management interface
This patch adds a management commands to feed the kernel with all stored
link keys as well as remove specific ones or all of them. Once the
load_keys command has been called the kernel takes over link key
replies. A new_key event is also added to inform userspace of newly
created link keys that should be stored permanently.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index c69ee44d5bd7..80ffd3a901fc 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1810,13 +1810,60 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff | |||
1810 | 1810 | ||
1811 | static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1811 | static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1812 | { | 1812 | { |
1813 | struct hci_ev_link_key_req *ev = (void *) skb->data; | ||
1814 | struct hci_cp_link_key_reply cp; | ||
1815 | struct hci_conn *conn; | ||
1816 | struct link_key *key; | ||
1817 | |||
1813 | BT_DBG("%s", hdev->name); | 1818 | BT_DBG("%s", hdev->name); |
1819 | |||
1820 | if (!test_bit(HCI_LINK_KEYS, &hdev->flags)) | ||
1821 | return; | ||
1822 | |||
1823 | hci_dev_lock(hdev); | ||
1824 | |||
1825 | key = hci_find_link_key(hdev, &ev->bdaddr); | ||
1826 | if (!key) { | ||
1827 | BT_DBG("%s link key not found for %s", hdev->name, | ||
1828 | batostr(&ev->bdaddr)); | ||
1829 | goto not_found; | ||
1830 | } | ||
1831 | |||
1832 | BT_DBG("%s found key type %u for %s", hdev->name, key->type, | ||
1833 | batostr(&ev->bdaddr)); | ||
1834 | |||
1835 | if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) { | ||
1836 | BT_DBG("%s ignoring debug key", hdev->name); | ||
1837 | goto not_found; | ||
1838 | } | ||
1839 | |||
1840 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr); | ||
1841 | |||
1842 | if (key->type == 0x04 && conn && conn->auth_type != 0xff && | ||
1843 | (conn->auth_type & 0x01)) { | ||
1844 | BT_DBG("%s ignoring unauthenticated key", hdev->name); | ||
1845 | goto not_found; | ||
1846 | } | ||
1847 | |||
1848 | bacpy(&cp.bdaddr, &ev->bdaddr); | ||
1849 | memcpy(cp.link_key, key->val, 16); | ||
1850 | |||
1851 | hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp); | ||
1852 | |||
1853 | hci_dev_unlock(hdev); | ||
1854 | |||
1855 | return; | ||
1856 | |||
1857 | not_found: | ||
1858 | hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr); | ||
1859 | hci_dev_unlock(hdev); | ||
1814 | } | 1860 | } |
1815 | 1861 | ||
1816 | static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) | 1862 | static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) |
1817 | { | 1863 | { |
1818 | struct hci_ev_link_key_notify *ev = (void *) skb->data; | 1864 | struct hci_ev_link_key_notify *ev = (void *) skb->data; |
1819 | struct hci_conn *conn; | 1865 | struct hci_conn *conn; |
1866 | u8 pin_len = 0; | ||
1820 | 1867 | ||
1821 | BT_DBG("%s", hdev->name); | 1868 | BT_DBG("%s", hdev->name); |
1822 | 1869 | ||
@@ -1829,6 +1876,10 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff | |||
1829 | hci_conn_put(conn); | 1876 | hci_conn_put(conn); |
1830 | } | 1877 | } |
1831 | 1878 | ||
1879 | if (test_bit(HCI_LINK_KEYS, &hdev->flags)) | ||
1880 | hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key, | ||
1881 | ev->key_type, pin_len); | ||
1882 | |||
1832 | hci_dev_unlock(hdev); | 1883 | hci_dev_unlock(hdev); |
1833 | } | 1884 | } |
1834 | 1885 | ||