diff options
Diffstat (limited to 'net/bluetooth')
-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 |
4 files changed, 51 insertions, 22 deletions
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)) |