diff options
-rw-r--r-- | fs/compat_ioctl.c | 1 | ||||
-rw-r--r-- | include/net/bluetooth/hci.h | 18 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 38 | ||||
-rw-r--r-- | net/bluetooth/hci_sock.c | 18 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 14 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 3 |
7 files changed, 68 insertions, 26 deletions
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 97dba0d92348..d63d430d3b26 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -2399,6 +2399,7 @@ COMPATIBLE_IOCTL(HCIGETDEVLIST) | |||
2399 | COMPATIBLE_IOCTL(HCIGETDEVINFO) | 2399 | COMPATIBLE_IOCTL(HCIGETDEVINFO) |
2400 | COMPATIBLE_IOCTL(HCIGETCONNLIST) | 2400 | COMPATIBLE_IOCTL(HCIGETCONNLIST) |
2401 | COMPATIBLE_IOCTL(HCIGETCONNINFO) | 2401 | COMPATIBLE_IOCTL(HCIGETCONNINFO) |
2402 | COMPATIBLE_IOCTL(HCIGETAUTHINFO) | ||
2402 | COMPATIBLE_IOCTL(HCISETRAW) | 2403 | COMPATIBLE_IOCTL(HCISETRAW) |
2403 | COMPATIBLE_IOCTL(HCISETSCAN) | 2404 | COMPATIBLE_IOCTL(HCISETSCAN) |
2404 | COMPATIBLE_IOCTL(HCISETAUTH) | 2405 | COMPATIBLE_IOCTL(HCISETAUTH) |
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 55576e848827..3cc294919312 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -72,8 +72,6 @@ enum { | |||
72 | HCI_INQUIRY, | 72 | HCI_INQUIRY, |
73 | 73 | ||
74 | HCI_RAW, | 74 | HCI_RAW, |
75 | |||
76 | HCI_SECMGR | ||
77 | }; | 75 | }; |
78 | 76 | ||
79 | /* HCI ioctl defines */ | 77 | /* HCI ioctl defines */ |
@@ -86,6 +84,7 @@ enum { | |||
86 | #define HCIGETDEVINFO _IOR('H', 211, int) | 84 | #define HCIGETDEVINFO _IOR('H', 211, int) |
87 | #define HCIGETCONNLIST _IOR('H', 212, int) | 85 | #define HCIGETCONNLIST _IOR('H', 212, int) |
88 | #define HCIGETCONNINFO _IOR('H', 213, int) | 86 | #define HCIGETCONNINFO _IOR('H', 213, int) |
87 | #define HCIGETAUTHINFO _IOR('H', 215, int) | ||
89 | 88 | ||
90 | #define HCISETRAW _IOW('H', 220, int) | 89 | #define HCISETRAW _IOW('H', 220, int) |
91 | #define HCISETSCAN _IOW('H', 221, int) | 90 | #define HCISETSCAN _IOW('H', 221, int) |
@@ -97,8 +96,6 @@ enum { | |||
97 | #define HCISETACLMTU _IOW('H', 227, int) | 96 | #define HCISETACLMTU _IOW('H', 227, int) |
98 | #define HCISETSCOMTU _IOW('H', 228, int) | 97 | #define HCISETSCOMTU _IOW('H', 228, int) |
99 | 98 | ||
100 | #define HCISETSECMGR _IOW('H', 230, int) | ||
101 | |||
102 | #define HCIINQUIRY _IOR('H', 240, int) | 99 | #define HCIINQUIRY _IOR('H', 240, int) |
103 | 100 | ||
104 | /* HCI timeouts */ | 101 | /* HCI timeouts */ |
@@ -203,6 +200,14 @@ enum { | |||
203 | #define HCI_LM_RELIABLE 0x0010 | 200 | #define HCI_LM_RELIABLE 0x0010 |
204 | #define HCI_LM_SECURE 0x0020 | 201 | #define HCI_LM_SECURE 0x0020 |
205 | 202 | ||
203 | /* Authentication types */ | ||
204 | #define HCI_AT_NO_BONDING 0x00 | ||
205 | #define HCI_AT_NO_BONDING_MITM 0x01 | ||
206 | #define HCI_AT_DEDICATED_BONDING 0x02 | ||
207 | #define HCI_AT_DEDICATED_BONDING_MITM 0x03 | ||
208 | #define HCI_AT_GENERAL_BONDING 0x04 | ||
209 | #define HCI_AT_GENERAL_BONDING_MITM 0x05 | ||
210 | |||
206 | /* ----- HCI Commands ---- */ | 211 | /* ----- HCI Commands ---- */ |
207 | #define HCI_OP_INQUIRY 0x0401 | 212 | #define HCI_OP_INQUIRY 0x0401 |
208 | struct hci_cp_inquiry { | 213 | struct hci_cp_inquiry { |
@@ -1001,6 +1006,11 @@ struct hci_conn_info_req { | |||
1001 | struct hci_conn_info conn_info[0]; | 1006 | struct hci_conn_info conn_info[0]; |
1002 | }; | 1007 | }; |
1003 | 1008 | ||
1009 | struct hci_auth_info_req { | ||
1010 | bdaddr_t bdaddr; | ||
1011 | __u8 type; | ||
1012 | }; | ||
1013 | |||
1004 | struct hci_inquiry_req { | 1014 | struct hci_inquiry_req { |
1005 | __u16 dev_id; | 1015 | __u16 dev_id; |
1006 | __u16 flags; | 1016 | __u16 flags; |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 28fbd0caa534..cbf751094688 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -168,6 +168,7 @@ struct hci_conn { | |||
168 | __u16 pkt_type; | 168 | __u16 pkt_type; |
169 | __u16 link_policy; | 169 | __u16 link_policy; |
170 | __u32 link_mode; | 170 | __u32 link_mode; |
171 | __u8 auth_type; | ||
171 | __u8 power_save; | 172 | __u8 power_save; |
172 | unsigned long pend; | 173 | unsigned long pend; |
173 | 174 | ||
@@ -422,6 +423,7 @@ int hci_get_dev_list(void __user *arg); | |||
422 | int hci_get_dev_info(void __user *arg); | 423 | int hci_get_dev_info(void __user *arg); |
423 | int hci_get_conn_list(void __user *arg); | 424 | int hci_get_conn_list(void __user *arg); |
424 | int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); | 425 | int hci_get_conn_info(struct hci_dev *hdev, void __user *arg); |
426 | int hci_get_auth_info(struct hci_dev *hdev, void __user *arg); | ||
425 | int hci_inquiry(void __user *arg); | 427 | int hci_inquiry(void __user *arg); |
426 | 428 | ||
427 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); | 429 | void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb); |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 6f22533e7656..0d4b8aeb8e09 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -379,13 +379,21 @@ int hci_conn_auth(struct hci_conn *conn) | |||
379 | { | 379 | { |
380 | BT_DBG("conn %p", conn); | 380 | BT_DBG("conn %p", conn); |
381 | 381 | ||
382 | if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { | ||
383 | if (!(conn->auth_type & 0x01)) { | ||
384 | conn->auth_type = HCI_AT_GENERAL_BONDING_MITM; | ||
385 | conn->link_mode &= ~HCI_LM_AUTH; | ||
386 | } | ||
387 | } | ||
388 | |||
382 | if (conn->link_mode & HCI_LM_AUTH) | 389 | if (conn->link_mode & HCI_LM_AUTH) |
383 | return 1; | 390 | return 1; |
384 | 391 | ||
385 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | 392 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { |
386 | struct hci_cp_auth_requested cp; | 393 | struct hci_cp_auth_requested cp; |
387 | cp.handle = cpu_to_le16(conn->handle); | 394 | cp.handle = cpu_to_le16(conn->handle); |
388 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); | 395 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, |
396 | sizeof(cp), &cp); | ||
389 | } | 397 | } |
390 | return 0; | 398 | return 0; |
391 | } | 399 | } |
@@ -397,7 +405,7 @@ int hci_conn_encrypt(struct hci_conn *conn) | |||
397 | BT_DBG("conn %p", conn); | 405 | BT_DBG("conn %p", conn); |
398 | 406 | ||
399 | if (conn->link_mode & HCI_LM_ENCRYPT) | 407 | if (conn->link_mode & HCI_LM_ENCRYPT) |
400 | return 1; | 408 | return hci_conn_auth(conn); |
401 | 409 | ||
402 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | 410 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) |
403 | return 0; | 411 | return 0; |
@@ -406,7 +414,8 @@ int hci_conn_encrypt(struct hci_conn *conn) | |||
406 | struct hci_cp_set_conn_encrypt cp; | 414 | struct hci_cp_set_conn_encrypt cp; |
407 | cp.handle = cpu_to_le16(conn->handle); | 415 | cp.handle = cpu_to_le16(conn->handle); |
408 | cp.encrypt = 1; | 416 | cp.encrypt = 1; |
409 | hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); | 417 | hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, |
418 | sizeof(cp), &cp); | ||
410 | } | 419 | } |
411 | return 0; | 420 | return 0; |
412 | } | 421 | } |
@@ -420,7 +429,8 @@ int hci_conn_change_link_key(struct hci_conn *conn) | |||
420 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { | 429 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { |
421 | struct hci_cp_change_conn_link_key cp; | 430 | struct hci_cp_change_conn_link_key cp; |
422 | cp.handle = cpu_to_le16(conn->handle); | 431 | cp.handle = cpu_to_le16(conn->handle); |
423 | hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp); | 432 | hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, |
433 | sizeof(cp), &cp); | ||
424 | } | 434 | } |
425 | return 0; | 435 | return 0; |
426 | } | 436 | } |
@@ -624,3 +634,23 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg) | |||
624 | 634 | ||
625 | return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0; | 635 | return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0; |
626 | } | 636 | } |
637 | |||
638 | int hci_get_auth_info(struct hci_dev *hdev, void __user *arg) | ||
639 | { | ||
640 | struct hci_auth_info_req req; | ||
641 | struct hci_conn *conn; | ||
642 | |||
643 | if (copy_from_user(&req, arg, sizeof(req))) | ||
644 | return -EFAULT; | ||
645 | |||
646 | hci_dev_lock_bh(hdev); | ||
647 | conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr); | ||
648 | if (conn) | ||
649 | req.type = conn->auth_type; | ||
650 | hci_dev_unlock_bh(hdev); | ||
651 | |||
652 | if (!conn) | ||
653 | return -ENOENT; | ||
654 | |||
655 | return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0; | ||
656 | } | ||
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 747fabd735d2..d62579b67959 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -193,19 +193,11 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign | |||
193 | 193 | ||
194 | return 0; | 194 | return 0; |
195 | 195 | ||
196 | case HCISETSECMGR: | ||
197 | if (!capable(CAP_NET_ADMIN)) | ||
198 | return -EACCES; | ||
199 | |||
200 | if (arg) | ||
201 | set_bit(HCI_SECMGR, &hdev->flags); | ||
202 | else | ||
203 | clear_bit(HCI_SECMGR, &hdev->flags); | ||
204 | |||
205 | return 0; | ||
206 | |||
207 | case HCIGETCONNINFO: | 196 | case HCIGETCONNINFO: |
208 | return hci_get_conn_info(hdev, (void __user *)arg); | 197 | return hci_get_conn_info(hdev, (void __user *) arg); |
198 | |||
199 | case HCIGETAUTHINFO: | ||
200 | return hci_get_auth_info(hdev, (void __user *) arg); | ||
209 | 201 | ||
210 | default: | 202 | default: |
211 | if (hdev->ioctl) | 203 | if (hdev->ioctl) |
@@ -217,7 +209,7 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign | |||
217 | static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | 209 | static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) |
218 | { | 210 | { |
219 | struct sock *sk = sock->sk; | 211 | struct sock *sk = sock->sk; |
220 | void __user *argp = (void __user *)arg; | 212 | void __user *argp = (void __user *) arg; |
221 | int err; | 213 | int err; |
222 | 214 | ||
223 | BT_DBG("cmd %x arg %lx", cmd, arg); | 215 | BT_DBG("cmd %x arg %lx", cmd, arg); |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 252264062f59..30ad59b717d5 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -2150,7 +2150,7 @@ static int l2cap_disconn_ind(struct hci_conn *hcon, u8 reason) | |||
2150 | static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) | 2150 | static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) |
2151 | { | 2151 | { |
2152 | struct l2cap_chan_list *l; | 2152 | struct l2cap_chan_list *l; |
2153 | struct l2cap_conn *conn = conn = hcon->l2cap_data; | 2153 | struct l2cap_conn *conn = hcon->l2cap_data; |
2154 | struct l2cap_conn_rsp rsp; | 2154 | struct l2cap_conn_rsp rsp; |
2155 | struct sock *sk; | 2155 | struct sock *sk; |
2156 | int result; | 2156 | int result; |
@@ -2165,11 +2165,17 @@ static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) | |||
2165 | read_lock(&l->lock); | 2165 | read_lock(&l->lock); |
2166 | 2166 | ||
2167 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { | 2167 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { |
2168 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
2169 | |||
2168 | bh_lock_sock(sk); | 2170 | bh_lock_sock(sk); |
2169 | 2171 | ||
2170 | if (sk->sk_state != BT_CONNECT2 || | 2172 | if (sk->sk_state != BT_CONNECT2) { |
2171 | (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) || | 2173 | bh_unlock_sock(sk); |
2172 | (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE)) { | 2174 | continue; |
2175 | } | ||
2176 | |||
2177 | if ((pi->link_mode & (L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)) && | ||
2178 | !(hcon->link_mode & HCI_LM_ENCRYPT)) { | ||
2173 | bh_unlock_sock(sk); | 2179 | bh_unlock_sock(sk); |
2174 | continue; | 2180 | continue; |
2175 | } | 2181 | } |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index e7a6a03cea37..e56bcfc35a49 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -1969,7 +1969,8 @@ static void rfcomm_auth_cfm(struct hci_conn *conn, u8 status) | |||
1969 | list_for_each_safe(p, n, &s->dlcs) { | 1969 | list_for_each_safe(p, n, &s->dlcs) { |
1970 | d = list_entry(p, struct rfcomm_dlc, list); | 1970 | d = list_entry(p, struct rfcomm_dlc, list); |
1971 | 1971 | ||
1972 | if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) | 1972 | if ((d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) && |
1973 | !(conn->link_mode & HCI_LM_ENCRYPT) && !status) | ||
1973 | continue; | 1974 | continue; |
1974 | 1975 | ||
1975 | if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) | 1976 | if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) |