diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_conn.c | 45 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 3 | ||||
-rw-r--r-- | net/bluetooth/l2cap.c | 134 | ||||
-rw-r--r-- | net/bluetooth/rfcomm/core.c | 81 | ||||
-rw-r--r-- | net/bluetooth/sco.c | 2 |
5 files changed, 97 insertions, 168 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index a4a789f24c8d..98f97a1e9bbb 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -325,7 +325,7 @@ EXPORT_SYMBOL(hci_get_route); | |||
325 | 325 | ||
326 | /* Create SCO or ACL connection. | 326 | /* Create SCO or ACL connection. |
327 | * Device _must_ be locked */ | 327 | * Device _must_ be locked */ |
328 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type) | 328 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type) |
329 | { | 329 | { |
330 | struct hci_conn *acl; | 330 | struct hci_conn *acl; |
331 | struct hci_conn *sco; | 331 | struct hci_conn *sco; |
@@ -340,6 +340,7 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 | |||
340 | hci_conn_hold(acl); | 340 | hci_conn_hold(acl); |
341 | 341 | ||
342 | if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { | 342 | if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { |
343 | acl->sec_level = sec_level; | ||
343 | acl->auth_type = auth_type; | 344 | acl->auth_type = auth_type; |
344 | hci_acl_connect(acl); | 345 | hci_acl_connect(acl); |
345 | } | 346 | } |
@@ -385,16 +386,17 @@ int hci_conn_check_link_mode(struct hci_conn *conn) | |||
385 | EXPORT_SYMBOL(hci_conn_check_link_mode); | 386 | EXPORT_SYMBOL(hci_conn_check_link_mode); |
386 | 387 | ||
387 | /* Authenticate remote device */ | 388 | /* Authenticate remote device */ |
388 | int hci_conn_auth(struct hci_conn *conn) | 389 | static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level) |
389 | { | 390 | { |
390 | BT_DBG("conn %p", conn); | 391 | BT_DBG("conn %p", conn); |
391 | 392 | ||
392 | if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) { | 393 | if (sec_level > conn->sec_level) |
393 | if (!(conn->auth_type & 0x01)) { | 394 | conn->link_mode &= ~HCI_LM_AUTH; |
394 | conn->auth_type |= 0x01; | 395 | |
395 | conn->link_mode &= ~HCI_LM_AUTH; | 396 | conn->sec_level = sec_level; |
396 | } | 397 | |
397 | } | 398 | if (sec_level == BT_SECURITY_HIGH) |
399 | conn->auth_type |= 0x01; | ||
398 | 400 | ||
399 | if (conn->link_mode & HCI_LM_AUTH) | 401 | if (conn->link_mode & HCI_LM_AUTH) |
400 | return 1; | 402 | return 1; |
@@ -405,31 +407,42 @@ int hci_conn_auth(struct hci_conn *conn) | |||
405 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, | 407 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, |
406 | sizeof(cp), &cp); | 408 | sizeof(cp), &cp); |
407 | } | 409 | } |
410 | |||
408 | return 0; | 411 | return 0; |
409 | } | 412 | } |
410 | EXPORT_SYMBOL(hci_conn_auth); | ||
411 | 413 | ||
412 | /* Enable encryption */ | 414 | /* Enable security */ |
413 | int hci_conn_encrypt(struct hci_conn *conn) | 415 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level) |
414 | { | 416 | { |
415 | BT_DBG("conn %p", conn); | 417 | BT_DBG("conn %p", conn); |
416 | 418 | ||
419 | if (sec_level == BT_SECURITY_SDP) | ||
420 | return 1; | ||
421 | |||
422 | if (sec_level == BT_SECURITY_LOW) { | ||
423 | if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) | ||
424 | return hci_conn_auth(conn, sec_level); | ||
425 | else | ||
426 | return 1; | ||
427 | } | ||
428 | |||
417 | if (conn->link_mode & HCI_LM_ENCRYPT) | 429 | if (conn->link_mode & HCI_LM_ENCRYPT) |
418 | return hci_conn_auth(conn); | 430 | return hci_conn_auth(conn, sec_level); |
419 | 431 | ||
420 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | 432 | if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) |
421 | return 0; | 433 | return 0; |
422 | 434 | ||
423 | if (hci_conn_auth(conn)) { | 435 | if (hci_conn_auth(conn, sec_level)) { |
424 | struct hci_cp_set_conn_encrypt cp; | 436 | struct hci_cp_set_conn_encrypt cp; |
425 | cp.handle = cpu_to_le16(conn->handle); | 437 | cp.handle = cpu_to_le16(conn->handle); |
426 | cp.encrypt = 1; | 438 | cp.encrypt = 1; |
427 | hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, | 439 | hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, |
428 | sizeof(cp), &cp); | 440 | sizeof(cp), &cp); |
429 | } | 441 | } |
442 | |||
430 | return 0; | 443 | return 0; |
431 | } | 444 | } |
432 | EXPORT_SYMBOL(hci_conn_encrypt); | 445 | EXPORT_SYMBOL(hci_conn_security); |
433 | 446 | ||
434 | /* Change link key */ | 447 | /* Change link key */ |
435 | int hci_conn_change_link_key(struct hci_conn *conn) | 448 | int hci_conn_change_link_key(struct hci_conn *conn) |
@@ -442,12 +455,13 @@ int hci_conn_change_link_key(struct hci_conn *conn) | |||
442 | hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, | 455 | hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, |
443 | sizeof(cp), &cp); | 456 | sizeof(cp), &cp); |
444 | } | 457 | } |
458 | |||
445 | return 0; | 459 | return 0; |
446 | } | 460 | } |
447 | EXPORT_SYMBOL(hci_conn_change_link_key); | 461 | EXPORT_SYMBOL(hci_conn_change_link_key); |
448 | 462 | ||
449 | /* Switch role */ | 463 | /* Switch role */ |
450 | int hci_conn_switch_role(struct hci_conn *conn, uint8_t role) | 464 | int hci_conn_switch_role(struct hci_conn *conn, __u8 role) |
451 | { | 465 | { |
452 | BT_DBG("conn %p", conn); | 466 | BT_DBG("conn %p", conn); |
453 | 467 | ||
@@ -460,6 +474,7 @@ int hci_conn_switch_role(struct hci_conn *conn, uint8_t role) | |||
460 | cp.role = role; | 474 | cp.role = role; |
461 | hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp); | 475 | hci_send_cmd(conn->hdev, HCI_OP_SWITCH_ROLE, sizeof(cp), &cp); |
462 | } | 476 | } |
477 | |||
463 | return 0; | 478 | return 0; |
464 | } | 479 | } |
465 | EXPORT_SYMBOL(hci_conn_switch_role); | 480 | EXPORT_SYMBOL(hci_conn_switch_role); |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index beea9dbb6562..014fc8b320ba 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1601,7 +1601,8 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b | |||
1601 | 1601 | ||
1602 | if (conn->state == BT_CONFIG) { | 1602 | if (conn->state == BT_CONFIG) { |
1603 | if (!ev->status && hdev->ssp_mode > 0 && | 1603 | if (!ev->status && hdev->ssp_mode > 0 && |
1604 | conn->ssp_mode > 0 && conn->out) { | 1604 | conn->ssp_mode > 0 && conn->out && |
1605 | conn->sec_level != BT_SECURITY_SDP) { | ||
1605 | struct hci_cp_auth_requested cp; | 1606 | struct hci_cp_auth_requested cp; |
1606 | cp.handle = ev->handle; | 1607 | cp.handle = ev->handle; |
1607 | hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, | 1608 | hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, |
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 123efb46d3f5..eadf09231866 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c | |||
@@ -263,12 +263,17 @@ static inline int l2cap_check_link_mode(struct sock *sk) | |||
263 | { | 263 | { |
264 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | 264 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; |
265 | 265 | ||
266 | if ((l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) || | 266 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) |
267 | (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE)) | 267 | return hci_conn_security(conn->hcon, BT_SECURITY_HIGH); |
268 | return hci_conn_encrypt(conn->hcon); | 268 | |
269 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) | ||
270 | return hci_conn_security(conn->hcon, BT_SECURITY_MEDIUM); | ||
269 | 271 | ||
270 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) | 272 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH) |
271 | return hci_conn_auth(conn->hcon); | 273 | return hci_conn_security(conn->hcon, BT_SECURITY_LOW); |
274 | |||
275 | if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) | ||
276 | return hci_conn_security(conn->hcon, BT_SECURITY_SDP); | ||
272 | 277 | ||
273 | return 1; | 278 | return 1; |
274 | } | 279 | } |
@@ -803,6 +808,7 @@ static int l2cap_do_connect(struct sock *sk) | |||
803 | struct l2cap_conn *conn; | 808 | struct l2cap_conn *conn; |
804 | struct hci_conn *hcon; | 809 | struct hci_conn *hcon; |
805 | struct hci_dev *hdev; | 810 | struct hci_dev *hdev; |
811 | __u8 sec_level; | ||
806 | __u8 auth_type; | 812 | __u8 auth_type; |
807 | int err = 0; | 813 | int err = 0; |
808 | 814 | ||
@@ -815,21 +821,37 @@ static int l2cap_do_connect(struct sock *sk) | |||
815 | 821 | ||
816 | err = -ENOMEM; | 822 | err = -ENOMEM; |
817 | 823 | ||
818 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_AUTH || | 824 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) |
819 | l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT || | 825 | sec_level = BT_SECURITY_HIGH; |
820 | l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) { | 826 | else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) |
821 | if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) | 827 | sec_level = BT_SECURITY_SDP; |
822 | auth_type = HCI_AT_NO_BONDING_MITM; | 828 | else if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) |
829 | sec_level = BT_SECURITY_MEDIUM; | ||
830 | else | ||
831 | sec_level = BT_SECURITY_LOW; | ||
832 | |||
833 | if (sk->sk_type == SOCK_RAW) { | ||
834 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) | ||
835 | auth_type = HCI_AT_DEDICATED_BONDING_MITM; | ||
836 | else if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) | ||
837 | auth_type = HCI_AT_DEDICATED_BONDING; | ||
823 | else | 838 | else |
824 | auth_type = HCI_AT_GENERAL_BONDING_MITM; | ||
825 | } else { | ||
826 | if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) | ||
827 | auth_type = HCI_AT_NO_BONDING; | 839 | auth_type = HCI_AT_NO_BONDING; |
840 | } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { | ||
841 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) | ||
842 | auth_type = HCI_AT_NO_BONDING_MITM; | ||
828 | else | 843 | else |
844 | auth_type = HCI_AT_NO_BONDING; | ||
845 | } else { | ||
846 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) | ||
847 | auth_type = HCI_AT_GENERAL_BONDING_MITM; | ||
848 | else if (l2cap_pi(sk)->link_mode & L2CAP_LM_ENCRYPT) | ||
829 | auth_type = HCI_AT_GENERAL_BONDING; | 849 | auth_type = HCI_AT_GENERAL_BONDING; |
850 | else | ||
851 | auth_type = HCI_AT_NO_BONDING; | ||
830 | } | 852 | } |
831 | 853 | ||
832 | hcon = hci_connect(hdev, ACL_LINK, dst, auth_type); | 854 | hcon = hci_connect(hdev, ACL_LINK, dst, sec_level, auth_type); |
833 | if (!hcon) | 855 | if (!hcon) |
834 | goto done; | 856 | goto done; |
835 | 857 | ||
@@ -1402,11 +1424,6 @@ static void l2cap_chan_ready(struct sock *sk) | |||
1402 | */ | 1424 | */ |
1403 | parent->sk_data_ready(parent, 0); | 1425 | parent->sk_data_ready(parent, 0); |
1404 | } | 1426 | } |
1405 | |||
1406 | if (l2cap_pi(sk)->link_mode & L2CAP_LM_SECURE) { | ||
1407 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
1408 | hci_conn_change_link_key(conn->hcon); | ||
1409 | } | ||
1410 | } | 1427 | } |
1411 | 1428 | ||
1412 | /* Copy frame to all raw sockets on that connection */ | 1429 | /* Copy frame to all raw sockets on that connection */ |
@@ -2323,77 +2340,7 @@ static int l2cap_disconn_ind(struct hci_conn *hcon, u8 reason) | |||
2323 | return 0; | 2340 | return 0; |
2324 | } | 2341 | } |
2325 | 2342 | ||
2326 | static int l2cap_auth_cfm(struct hci_conn *hcon, u8 status) | 2343 | static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) |
2327 | { | ||
2328 | struct l2cap_chan_list *l; | ||
2329 | struct l2cap_conn *conn = hcon->l2cap_data; | ||
2330 | struct sock *sk; | ||
2331 | |||
2332 | if (!conn) | ||
2333 | return 0; | ||
2334 | |||
2335 | l = &conn->chan_list; | ||
2336 | |||
2337 | BT_DBG("conn %p", conn); | ||
2338 | |||
2339 | read_lock(&l->lock); | ||
2340 | |||
2341 | for (sk = l->head; sk; sk = l2cap_pi(sk)->next_c) { | ||
2342 | struct l2cap_pinfo *pi = l2cap_pi(sk); | ||
2343 | |||
2344 | bh_lock_sock(sk); | ||
2345 | |||
2346 | if ((pi->link_mode & (L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)) && | ||
2347 | !(hcon->link_mode & HCI_LM_ENCRYPT) && | ||
2348 | !status) { | ||
2349 | bh_unlock_sock(sk); | ||
2350 | continue; | ||
2351 | } | ||
2352 | |||
2353 | if (sk->sk_state == BT_CONNECT) { | ||
2354 | if (!status) { | ||
2355 | struct l2cap_conn_req req; | ||
2356 | req.scid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
2357 | req.psm = l2cap_pi(sk)->psm; | ||
2358 | |||
2359 | l2cap_pi(sk)->ident = l2cap_get_ident(conn); | ||
2360 | |||
2361 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | ||
2362 | L2CAP_CONN_REQ, sizeof(req), &req); | ||
2363 | } else { | ||
2364 | l2cap_sock_clear_timer(sk); | ||
2365 | l2cap_sock_set_timer(sk, HZ / 10); | ||
2366 | } | ||
2367 | } else if (sk->sk_state == BT_CONNECT2) { | ||
2368 | struct l2cap_conn_rsp rsp; | ||
2369 | __u16 result; | ||
2370 | |||
2371 | if (!status) { | ||
2372 | sk->sk_state = BT_CONFIG; | ||
2373 | result = L2CAP_CR_SUCCESS; | ||
2374 | } else { | ||
2375 | sk->sk_state = BT_DISCONN; | ||
2376 | l2cap_sock_set_timer(sk, HZ / 10); | ||
2377 | result = L2CAP_CR_SEC_BLOCK; | ||
2378 | } | ||
2379 | |||
2380 | rsp.scid = cpu_to_le16(l2cap_pi(sk)->dcid); | ||
2381 | rsp.dcid = cpu_to_le16(l2cap_pi(sk)->scid); | ||
2382 | rsp.result = cpu_to_le16(result); | ||
2383 | rsp.status = cpu_to_le16(L2CAP_CS_NO_INFO); | ||
2384 | l2cap_send_cmd(conn, l2cap_pi(sk)->ident, | ||
2385 | L2CAP_CONN_RSP, sizeof(rsp), &rsp); | ||
2386 | } | ||
2387 | |||
2388 | bh_unlock_sock(sk); | ||
2389 | } | ||
2390 | |||
2391 | read_unlock(&l->lock); | ||
2392 | |||
2393 | return 0; | ||
2394 | } | ||
2395 | |||
2396 | static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | ||
2397 | { | 2344 | { |
2398 | struct l2cap_chan_list *l; | 2345 | struct l2cap_chan_list *l; |
2399 | struct l2cap_conn *conn = hcon->l2cap_data; | 2346 | struct l2cap_conn *conn = hcon->l2cap_data; |
@@ -2413,10 +2360,10 @@ static int l2cap_encrypt_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
2413 | 2360 | ||
2414 | bh_lock_sock(sk); | 2361 | bh_lock_sock(sk); |
2415 | 2362 | ||
2416 | if ((pi->link_mode & (L2CAP_LM_ENCRYPT | L2CAP_LM_SECURE)) && | 2363 | if (!status && encrypt == 0x00 && |
2364 | (pi->link_mode & L2CAP_LM_SECURE) && | ||
2417 | (sk->sk_state == BT_CONNECTED || | 2365 | (sk->sk_state == BT_CONNECTED || |
2418 | sk->sk_state == BT_CONFIG) && | 2366 | sk->sk_state == BT_CONFIG)) { |
2419 | !status && encrypt == 0x00) { | ||
2420 | __l2cap_sock_close(sk, ECONNREFUSED); | 2367 | __l2cap_sock_close(sk, ECONNREFUSED); |
2421 | bh_unlock_sock(sk); | 2368 | bh_unlock_sock(sk); |
2422 | continue; | 2369 | continue; |
@@ -2608,8 +2555,7 @@ static struct hci_proto l2cap_hci_proto = { | |||
2608 | .connect_ind = l2cap_connect_ind, | 2555 | .connect_ind = l2cap_connect_ind, |
2609 | .connect_cfm = l2cap_connect_cfm, | 2556 | .connect_cfm = l2cap_connect_cfm, |
2610 | .disconn_ind = l2cap_disconn_ind, | 2557 | .disconn_ind = l2cap_disconn_ind, |
2611 | .auth_cfm = l2cap_auth_cfm, | 2558 | .security_cfm = l2cap_security_cfm, |
2612 | .encrypt_cfm = l2cap_encrypt_cfm, | ||
2613 | .recv_acldata = l2cap_recv_acldata | 2559 | .recv_acldata = l2cap_recv_acldata |
2614 | }; | 2560 | }; |
2615 | 2561 | ||
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index edee49e00fbf..68f70c5270c6 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -226,16 +226,18 @@ static int rfcomm_l2sock_create(struct socket **sock) | |||
226 | static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d) | 226 | static inline int rfcomm_check_link_mode(struct rfcomm_dlc *d) |
227 | { | 227 | { |
228 | struct sock *sk = d->session->sock->sk; | 228 | struct sock *sk = d->session->sock->sk; |
229 | struct l2cap_conn *conn = l2cap_pi(sk)->conn; | ||
229 | 230 | ||
230 | if (d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) { | 231 | if (d->link_mode & RFCOMM_LM_SECURE) |
231 | if (!hci_conn_encrypt(l2cap_pi(sk)->conn->hcon)) | 232 | return hci_conn_security(conn->hcon, BT_SECURITY_HIGH); |
232 | return 1; | ||
233 | } else if (d->link_mode & RFCOMM_LM_AUTH) { | ||
234 | if (!hci_conn_auth(l2cap_pi(sk)->conn->hcon)) | ||
235 | return 1; | ||
236 | } | ||
237 | 233 | ||
238 | return 0; | 234 | if (d->link_mode & RFCOMM_LM_ENCRYPT) |
235 | return hci_conn_security(conn->hcon, BT_SECURITY_MEDIUM); | ||
236 | |||
237 | if (d->link_mode & RFCOMM_LM_AUTH) | ||
238 | return hci_conn_security(conn->hcon, BT_SECURITY_LOW); | ||
239 | |||
240 | return 1; | ||
239 | } | 241 | } |
240 | 242 | ||
241 | /* ---- RFCOMM DLCs ---- */ | 243 | /* ---- RFCOMM DLCs ---- */ |
@@ -389,9 +391,9 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst, | |||
389 | 391 | ||
390 | if (s->state == BT_CONNECTED) { | 392 | if (s->state == BT_CONNECTED) { |
391 | if (rfcomm_check_link_mode(d)) | 393 | if (rfcomm_check_link_mode(d)) |
392 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | ||
393 | else | ||
394 | rfcomm_send_pn(s, 1, d); | 394 | rfcomm_send_pn(s, 1, d); |
395 | else | ||
396 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | ||
395 | } | 397 | } |
396 | 398 | ||
397 | rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); | 399 | rfcomm_dlc_set_timer(d, RFCOMM_CONN_TIMEOUT); |
@@ -1199,14 +1201,14 @@ void rfcomm_dlc_accept(struct rfcomm_dlc *d) | |||
1199 | static void rfcomm_check_accept(struct rfcomm_dlc *d) | 1201 | static void rfcomm_check_accept(struct rfcomm_dlc *d) |
1200 | { | 1202 | { |
1201 | if (rfcomm_check_link_mode(d)) { | 1203 | if (rfcomm_check_link_mode(d)) { |
1202 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | ||
1203 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); | ||
1204 | } else { | ||
1205 | if (d->defer_setup) { | 1204 | if (d->defer_setup) { |
1206 | set_bit(RFCOMM_DEFER_SETUP, &d->flags); | 1205 | set_bit(RFCOMM_DEFER_SETUP, &d->flags); |
1207 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); | 1206 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); |
1208 | } else | 1207 | } else |
1209 | rfcomm_dlc_accept(d); | 1208 | rfcomm_dlc_accept(d); |
1209 | } else { | ||
1210 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | ||
1211 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); | ||
1210 | } | 1212 | } |
1211 | } | 1213 | } |
1212 | 1214 | ||
@@ -1659,10 +1661,11 @@ static void rfcomm_process_connect(struct rfcomm_session *s) | |||
1659 | if (d->state == BT_CONFIG) { | 1661 | if (d->state == BT_CONFIG) { |
1660 | d->mtu = s->mtu; | 1662 | d->mtu = s->mtu; |
1661 | if (rfcomm_check_link_mode(d)) { | 1663 | if (rfcomm_check_link_mode(d)) { |
1664 | rfcomm_send_pn(s, 1, d); | ||
1665 | } else { | ||
1662 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); | 1666 | set_bit(RFCOMM_AUTH_PENDING, &d->flags); |
1663 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); | 1667 | rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT); |
1664 | } else | 1668 | } |
1665 | rfcomm_send_pn(s, 1, d); | ||
1666 | } | 1669 | } |
1667 | } | 1670 | } |
1668 | } | 1671 | } |
@@ -1973,42 +1976,7 @@ static int rfcomm_run(void *unused) | |||
1973 | return 0; | 1976 | return 0; |
1974 | } | 1977 | } |
1975 | 1978 | ||
1976 | static void rfcomm_auth_cfm(struct hci_conn *conn, u8 status) | 1979 | static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt) |
1977 | { | ||
1978 | struct rfcomm_session *s; | ||
1979 | struct rfcomm_dlc *d; | ||
1980 | struct list_head *p, *n; | ||
1981 | |||
1982 | BT_DBG("conn %p status 0x%02x", conn, status); | ||
1983 | |||
1984 | s = rfcomm_session_get(&conn->hdev->bdaddr, &conn->dst); | ||
1985 | if (!s) | ||
1986 | return; | ||
1987 | |||
1988 | rfcomm_session_hold(s); | ||
1989 | |||
1990 | list_for_each_safe(p, n, &s->dlcs) { | ||
1991 | d = list_entry(p, struct rfcomm_dlc, list); | ||
1992 | |||
1993 | if ((d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) && | ||
1994 | !(conn->link_mode & HCI_LM_ENCRYPT) && !status) | ||
1995 | continue; | ||
1996 | |||
1997 | if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) | ||
1998 | continue; | ||
1999 | |||
2000 | if (!status) | ||
2001 | set_bit(RFCOMM_AUTH_ACCEPT, &d->flags); | ||
2002 | else | ||
2003 | set_bit(RFCOMM_AUTH_REJECT, &d->flags); | ||
2004 | } | ||
2005 | |||
2006 | rfcomm_session_put(s); | ||
2007 | |||
2008 | rfcomm_schedule(RFCOMM_SCHED_AUTH); | ||
2009 | } | ||
2010 | |||
2011 | static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt) | ||
2012 | { | 1980 | { |
2013 | struct rfcomm_session *s; | 1981 | struct rfcomm_session *s; |
2014 | struct rfcomm_dlc *d; | 1982 | struct rfcomm_dlc *d; |
@@ -2025,10 +1993,10 @@ static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt) | |||
2025 | list_for_each_safe(p, n, &s->dlcs) { | 1993 | list_for_each_safe(p, n, &s->dlcs) { |
2026 | d = list_entry(p, struct rfcomm_dlc, list); | 1994 | d = list_entry(p, struct rfcomm_dlc, list); |
2027 | 1995 | ||
2028 | if ((d->link_mode & (RFCOMM_LM_ENCRYPT | RFCOMM_LM_SECURE)) && | 1996 | if (!status && encrypt == 0x00 && |
1997 | (d->link_mode & RFCOMM_LM_ENCRYPT) && | ||
2029 | (d->state == BT_CONNECTED || | 1998 | (d->state == BT_CONNECTED || |
2030 | d->state == BT_CONFIG) && | 1999 | d->state == BT_CONFIG)) { |
2031 | !status && encrypt == 0x00) { | ||
2032 | __rfcomm_dlc_close(d, ECONNREFUSED); | 2000 | __rfcomm_dlc_close(d, ECONNREFUSED); |
2033 | continue; | 2001 | continue; |
2034 | } | 2002 | } |
@@ -2036,7 +2004,7 @@ static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt) | |||
2036 | if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) | 2004 | if (!test_and_clear_bit(RFCOMM_AUTH_PENDING, &d->flags)) |
2037 | continue; | 2005 | continue; |
2038 | 2006 | ||
2039 | if (!status && encrypt) | 2007 | if (!status) |
2040 | set_bit(RFCOMM_AUTH_ACCEPT, &d->flags); | 2008 | set_bit(RFCOMM_AUTH_ACCEPT, &d->flags); |
2041 | else | 2009 | else |
2042 | set_bit(RFCOMM_AUTH_REJECT, &d->flags); | 2010 | set_bit(RFCOMM_AUTH_REJECT, &d->flags); |
@@ -2049,8 +2017,7 @@ static void rfcomm_encrypt_cfm(struct hci_conn *conn, u8 status, u8 encrypt) | |||
2049 | 2017 | ||
2050 | static struct hci_cb rfcomm_cb = { | 2018 | static struct hci_cb rfcomm_cb = { |
2051 | .name = "RFCOMM", | 2019 | .name = "RFCOMM", |
2052 | .auth_cfm = rfcomm_auth_cfm, | 2020 | .security_cfm = rfcomm_security_cfm |
2053 | .encrypt_cfm = rfcomm_encrypt_cfm | ||
2054 | }; | 2021 | }; |
2055 | 2022 | ||
2056 | static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf) | 2023 | static ssize_t rfcomm_dlc_sysfs_show(struct class *dev, char *buf) |
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 71df982c09c9..7f10f97cd697 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -195,7 +195,7 @@ static int sco_connect(struct sock *sk) | |||
195 | else | 195 | else |
196 | type = SCO_LINK; | 196 | type = SCO_LINK; |
197 | 197 | ||
198 | hcon = hci_connect(hdev, type, dst, HCI_AT_NO_BONDING); | 198 | hcon = hci_connect(hdev, type, dst, BT_SECURITY_LOW, HCI_AT_NO_BONDING); |
199 | if (!hcon) | 199 | if (!hcon) |
200 | goto done; | 200 | goto done; |
201 | 201 | ||