diff options
-rw-r--r-- | include/net/bluetooth/bluetooth.h | 9 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 56 | ||||
-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 |
7 files changed, 139 insertions, 191 deletions
diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h index 847e9e6df08b..3ad5390a4dd5 100644 --- a/include/net/bluetooth/bluetooth.h +++ b/include/net/bluetooth/bluetooth.h | |||
@@ -53,6 +53,15 @@ | |||
53 | #define SOL_SCO 17 | 53 | #define SOL_SCO 17 |
54 | #define SOL_RFCOMM 18 | 54 | #define SOL_RFCOMM 18 |
55 | 55 | ||
56 | #define BT_SECURITY 4 | ||
57 | struct bt_security { | ||
58 | __u8 level; | ||
59 | }; | ||
60 | #define BT_SECURITY_SDP 0 | ||
61 | #define BT_SECURITY_LOW 1 | ||
62 | #define BT_SECURITY_MEDIUM 2 | ||
63 | #define BT_SECURITY_HIGH 3 | ||
64 | |||
56 | #define BT_DEFER_SETUP 7 | 65 | #define BT_DEFER_SETUP 7 |
57 | 66 | ||
58 | #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) | 67 | #define BT_INFO(fmt, arg...) printk(KERN_INFO "Bluetooth: " fmt "\n" , ## arg) |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 46a43b721dd6..4b14972c1694 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -169,6 +169,7 @@ struct hci_conn { | |||
169 | __u16 link_policy; | 169 | __u16 link_policy; |
170 | __u32 link_mode; | 170 | __u32 link_mode; |
171 | __u8 auth_type; | 171 | __u8 auth_type; |
172 | __u8 sec_level; | ||
172 | __u8 power_save; | 173 | __u8 power_save; |
173 | unsigned long pend; | 174 | unsigned long pend; |
174 | 175 | ||
@@ -325,12 +326,11 @@ int hci_conn_del(struct hci_conn *conn); | |||
325 | void hci_conn_hash_flush(struct hci_dev *hdev); | 326 | void hci_conn_hash_flush(struct hci_dev *hdev); |
326 | void hci_conn_check_pending(struct hci_dev *hdev); | 327 | void hci_conn_check_pending(struct hci_dev *hdev); |
327 | 328 | ||
328 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 auth_type); | 329 | struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 sec_level, __u8 auth_type); |
329 | int hci_conn_check_link_mode(struct hci_conn *conn); | 330 | int hci_conn_check_link_mode(struct hci_conn *conn); |
330 | int hci_conn_auth(struct hci_conn *conn); | 331 | int hci_conn_security(struct hci_conn *conn, __u8 sec_level); |
331 | int hci_conn_encrypt(struct hci_conn *conn); | ||
332 | int hci_conn_change_link_key(struct hci_conn *conn); | 332 | int hci_conn_change_link_key(struct hci_conn *conn); |
333 | int hci_conn_switch_role(struct hci_conn *conn, uint8_t role); | 333 | int hci_conn_switch_role(struct hci_conn *conn, __u8 role); |
334 | 334 | ||
335 | void hci_conn_enter_active_mode(struct hci_conn *conn); | 335 | void hci_conn_enter_active_mode(struct hci_conn *conn); |
336 | void hci_conn_enter_sniff_mode(struct hci_conn *conn); | 336 | void hci_conn_enter_sniff_mode(struct hci_conn *conn); |
@@ -470,26 +470,25 @@ void hci_conn_del_sysfs(struct hci_conn *conn); | |||
470 | 470 | ||
471 | /* ----- HCI protocols ----- */ | 471 | /* ----- HCI protocols ----- */ |
472 | struct hci_proto { | 472 | struct hci_proto { |
473 | char *name; | 473 | char *name; |
474 | unsigned int id; | 474 | unsigned int id; |
475 | unsigned long flags; | 475 | unsigned long flags; |
476 | 476 | ||
477 | void *priv; | 477 | void *priv; |
478 | 478 | ||
479 | int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type); | 479 | int (*connect_ind) (struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type); |
480 | int (*connect_cfm) (struct hci_conn *conn, __u8 status); | 480 | int (*connect_cfm) (struct hci_conn *conn, __u8 status); |
481 | int (*disconn_ind) (struct hci_conn *conn, __u8 reason); | 481 | int (*disconn_ind) (struct hci_conn *conn, __u8 reason); |
482 | int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); | 482 | int (*recv_acldata) (struct hci_conn *conn, struct sk_buff *skb, __u16 flags); |
483 | int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); | 483 | int (*recv_scodata) (struct hci_conn *conn, struct sk_buff *skb); |
484 | int (*auth_cfm) (struct hci_conn *conn, __u8 status); | 484 | int (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); |
485 | int (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); | ||
486 | }; | 485 | }; |
487 | 486 | ||
488 | static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | 487 | static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) |
489 | { | 488 | { |
490 | register struct hci_proto *hp; | 489 | register struct hci_proto *hp; |
491 | int mask = 0; | 490 | int mask = 0; |
492 | 491 | ||
493 | hp = hci_proto[HCI_PROTO_L2CAP]; | 492 | hp = hci_proto[HCI_PROTO_L2CAP]; |
494 | if (hp && hp->connect_ind) | 493 | if (hp && hp->connect_ind) |
495 | mask |= hp->connect_ind(hdev, bdaddr, type); | 494 | mask |= hp->connect_ind(hdev, bdaddr, type); |
@@ -530,14 +529,20 @@ static inline void hci_proto_disconn_ind(struct hci_conn *conn, __u8 reason) | |||
530 | static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) | 529 | static inline void hci_proto_auth_cfm(struct hci_conn *conn, __u8 status) |
531 | { | 530 | { |
532 | register struct hci_proto *hp; | 531 | register struct hci_proto *hp; |
532 | __u8 encrypt; | ||
533 | |||
534 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | ||
535 | return; | ||
536 | |||
537 | encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; | ||
533 | 538 | ||
534 | hp = hci_proto[HCI_PROTO_L2CAP]; | 539 | hp = hci_proto[HCI_PROTO_L2CAP]; |
535 | if (hp && hp->auth_cfm) | 540 | if (hp && hp->security_cfm) |
536 | hp->auth_cfm(conn, status); | 541 | hp->security_cfm(conn, status, encrypt); |
537 | 542 | ||
538 | hp = hci_proto[HCI_PROTO_SCO]; | 543 | hp = hci_proto[HCI_PROTO_SCO]; |
539 | if (hp && hp->auth_cfm) | 544 | if (hp && hp->security_cfm) |
540 | hp->auth_cfm(conn, status); | 545 | hp->security_cfm(conn, status, encrypt); |
541 | } | 546 | } |
542 | 547 | ||
543 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) | 548 | static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encrypt) |
@@ -545,12 +550,12 @@ static inline void hci_proto_encrypt_cfm(struct hci_conn *conn, __u8 status, __u | |||
545 | register struct hci_proto *hp; | 550 | register struct hci_proto *hp; |
546 | 551 | ||
547 | hp = hci_proto[HCI_PROTO_L2CAP]; | 552 | hp = hci_proto[HCI_PROTO_L2CAP]; |
548 | if (hp && hp->encrypt_cfm) | 553 | if (hp && hp->security_cfm) |
549 | hp->encrypt_cfm(conn, status, encrypt); | 554 | hp->security_cfm(conn, status, encrypt); |
550 | 555 | ||
551 | hp = hci_proto[HCI_PROTO_SCO]; | 556 | hp = hci_proto[HCI_PROTO_SCO]; |
552 | if (hp && hp->encrypt_cfm) | 557 | if (hp && hp->security_cfm) |
553 | hp->encrypt_cfm(conn, status, encrypt); | 558 | hp->security_cfm(conn, status, encrypt); |
554 | } | 559 | } |
555 | 560 | ||
556 | int hci_register_proto(struct hci_proto *hproto); | 561 | int hci_register_proto(struct hci_proto *hproto); |
@@ -562,8 +567,7 @@ struct hci_cb { | |||
562 | 567 | ||
563 | char *name; | 568 | char *name; |
564 | 569 | ||
565 | void (*auth_cfm) (struct hci_conn *conn, __u8 status); | 570 | void (*security_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); |
566 | void (*encrypt_cfm) (struct hci_conn *conn, __u8 status, __u8 encrypt); | ||
567 | void (*key_change_cfm) (struct hci_conn *conn, __u8 status); | 571 | void (*key_change_cfm) (struct hci_conn *conn, __u8 status); |
568 | void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); | 572 | void (*role_switch_cfm) (struct hci_conn *conn, __u8 status, __u8 role); |
569 | }; | 573 | }; |
@@ -571,14 +575,20 @@ struct hci_cb { | |||
571 | static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) | 575 | static inline void hci_auth_cfm(struct hci_conn *conn, __u8 status) |
572 | { | 576 | { |
573 | struct list_head *p; | 577 | struct list_head *p; |
578 | __u8 encrypt; | ||
574 | 579 | ||
575 | hci_proto_auth_cfm(conn, status); | 580 | hci_proto_auth_cfm(conn, status); |
576 | 581 | ||
582 | if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) | ||
583 | return; | ||
584 | |||
585 | encrypt = (conn->link_mode & HCI_LM_ENCRYPT) ? 0x01 : 0x00; | ||
586 | |||
577 | read_lock_bh(&hci_cb_list_lock); | 587 | read_lock_bh(&hci_cb_list_lock); |
578 | list_for_each(p, &hci_cb_list) { | 588 | list_for_each(p, &hci_cb_list) { |
579 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | 589 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); |
580 | if (cb->auth_cfm) | 590 | if (cb->security_cfm) |
581 | cb->auth_cfm(conn, status); | 591 | cb->security_cfm(conn, status, encrypt); |
582 | } | 592 | } |
583 | read_unlock_bh(&hci_cb_list_lock); | 593 | read_unlock_bh(&hci_cb_list_lock); |
584 | } | 594 | } |
@@ -592,8 +602,8 @@ static inline void hci_encrypt_cfm(struct hci_conn *conn, __u8 status, __u8 encr | |||
592 | read_lock_bh(&hci_cb_list_lock); | 602 | read_lock_bh(&hci_cb_list_lock); |
593 | list_for_each(p, &hci_cb_list) { | 603 | list_for_each(p, &hci_cb_list) { |
594 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); | 604 | struct hci_cb *cb = list_entry(p, struct hci_cb, list); |
595 | if (cb->encrypt_cfm) | 605 | if (cb->security_cfm) |
596 | cb->encrypt_cfm(conn, status, encrypt); | 606 | cb->security_cfm(conn, status, encrypt); |
597 | } | 607 | } |
598 | read_unlock_bh(&hci_cb_list_lock); | 608 | read_unlock_bh(&hci_cb_list_lock); |
599 | } | 609 | } |
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 | ||