aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_conn.c38
-rw-r--r--net/bluetooth/hci_sock.c18
-rw-r--r--net/bluetooth/l2cap.c14
-rw-r--r--net/bluetooth/rfcomm/core.c3
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
638int 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
217static int hci_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 209static 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)
2150static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) 2150static 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))