aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-07-14 14:13:49 -0400
committerMarcel Holtmann <marcel@holtmann.org>2008-07-14 14:13:49 -0400
commitf8558555f31e177e2644f3c8116801c3e5c29974 (patch)
tree5ad03ff814c4e1d0619e75d5f5a6033beff1c177 /net
parent769be974d0c7b4fe1a52f9cdaad22259b60953f7 (diff)
[Bluetooth] Initiate authentication during connection establishment
With Bluetooth 2.1 and Simple Pairing the requirement is that any new connection needs to be authenticated and that encryption has been switched on before allowing L2CAP to use it. So make sure that all the requirements are fulfilled and otherwise drop the connection with a minimal disconnect timeout of 10 milliseconds. This change only affects Bluetooth 2.1 devices and Simple Pairing needs to be enabled locally and in the remote host stack. The previous changes made sure that these information are discovered before any kind of authentication and encryption is triggered. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_event.c114
1 files changed, 103 insertions, 11 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index e3e360c3c536..64668e2656a5 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -619,6 +619,60 @@ static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
619 hci_dev_unlock(hdev); 619 hci_dev_unlock(hdev);
620} 620}
621 621
622static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
623{
624 struct hci_cp_auth_requested *cp;
625 struct hci_conn *conn;
626
627 BT_DBG("%s status 0x%x", hdev->name, status);
628
629 if (!status)
630 return;
631
632 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
633 if (!cp)
634 return;
635
636 hci_dev_lock(hdev);
637
638 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
639 if (conn) {
640 if (conn->state == BT_CONFIG) {
641 hci_proto_connect_cfm(conn, status);
642 hci_conn_put(conn);
643 }
644 }
645
646 hci_dev_unlock(hdev);
647}
648
649static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
650{
651 struct hci_cp_set_conn_encrypt *cp;
652 struct hci_conn *conn;
653
654 BT_DBG("%s status 0x%x", hdev->name, status);
655
656 if (!status)
657 return;
658
659 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
660 if (!cp)
661 return;
662
663 hci_dev_lock(hdev);
664
665 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
666 if (conn) {
667 if (conn->state == BT_CONFIG) {
668 hci_proto_connect_cfm(conn, status);
669 hci_conn_put(conn);
670 }
671 }
672
673 hci_dev_unlock(hdev);
674}
675
622static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) 676static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
623{ 677{
624 BT_DBG("%s status 0x%x", hdev->name, status); 678 BT_DBG("%s status 0x%x", hdev->name, status);
@@ -643,7 +697,6 @@ static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
643 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 697 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
644 if (conn) { 698 if (conn) {
645 if (conn->state == BT_CONFIG) { 699 if (conn->state == BT_CONFIG) {
646 conn->state = BT_CONNECTED;
647 hci_proto_connect_cfm(conn, status); 700 hci_proto_connect_cfm(conn, status);
648 hci_conn_put(conn); 701 hci_conn_put(conn);
649 } 702 }
@@ -671,7 +724,6 @@ static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
671 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle)); 724 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
672 if (conn) { 725 if (conn) {
673 if (conn->state == BT_CONFIG) { 726 if (conn->state == BT_CONFIG) {
674 conn->state = BT_CONNECTED;
675 hci_proto_connect_cfm(conn, status); 727 hci_proto_connect_cfm(conn, status);
676 hci_conn_put(conn); 728 hci_conn_put(conn);
677 } 729 }
@@ -982,15 +1034,29 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s
982 1034
983 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); 1035 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
984 1036
985 hci_auth_cfm(conn, ev->status); 1037 if (conn->state == BT_CONFIG) {
1038 if (!ev->status && hdev->ssp_mode > 0 &&
1039 conn->ssp_mode > 0) {
1040 struct hci_cp_set_conn_encrypt cp;
1041 cp.handle = ev->handle;
1042 cp.encrypt = 0x01;
1043 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1044 sizeof(cp), &cp);
1045 } else {
1046 conn->state = BT_CONNECTED;
1047 hci_proto_connect_cfm(conn, ev->status);
1048 hci_conn_put(conn);
1049 }
1050 } else
1051 hci_auth_cfm(conn, ev->status);
986 1052
987 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) { 1053 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
988 if (!ev->status) { 1054 if (!ev->status) {
989 struct hci_cp_set_conn_encrypt cp; 1055 struct hci_cp_set_conn_encrypt cp;
990 cp.handle = cpu_to_le16(conn->handle); 1056 cp.handle = ev->handle;
991 cp.encrypt = 1; 1057 cp.encrypt = 0x01;
992 hci_send_cmd(conn->hdev, 1058 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
993 HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); 1059 sizeof(cp), &cp);
994 } else { 1060 } else {
995 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); 1061 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
996 hci_encrypt_cfm(conn, ev->status, 0x00); 1062 hci_encrypt_cfm(conn, ev->status, 0x00);
@@ -1030,7 +1096,14 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
1030 1096
1031 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); 1097 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1032 1098
1033 hci_encrypt_cfm(conn, ev->status, ev->encrypt); 1099 if (conn->state == BT_CONFIG) {
1100 if (!ev->status)
1101 conn->state = BT_CONNECTED;
1102
1103 hci_proto_connect_cfm(conn, ev->status);
1104 hci_conn_put(conn);
1105 } else
1106 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
1034 } 1107 }
1035 1108
1036 hci_dev_unlock(hdev); 1109 hci_dev_unlock(hdev);
@@ -1250,6 +1323,14 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1250 hci_cs_add_sco(hdev, ev->status); 1323 hci_cs_add_sco(hdev, ev->status);
1251 break; 1324 break;
1252 1325
1326 case HCI_OP_AUTH_REQUESTED:
1327 hci_cs_auth_requested(hdev, ev->status);
1328 break;
1329
1330 case HCI_OP_SET_CONN_ENCRYPT:
1331 hci_cs_set_conn_encrypt(hdev, ev->status);
1332 break;
1333
1253 case HCI_OP_REMOTE_NAME_REQ: 1334 case HCI_OP_REMOTE_NAME_REQ:
1254 hci_cs_remote_name_req(hdev, ev->status); 1335 hci_cs_remote_name_req(hdev, ev->status);
1255 break; 1336 break;
@@ -1518,9 +1599,20 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b
1518 } 1599 }
1519 1600
1520 if (conn->state == BT_CONFIG) { 1601 if (conn->state == BT_CONFIG) {
1521 conn->state = BT_CONNECTED; 1602 if (!ev->status && hdev->ssp_mode > 0 &&
1522 hci_proto_connect_cfm(conn, ev->status); 1603 conn->ssp_mode > 0) {
1523 hci_conn_put(conn); 1604 if (conn->out) {
1605 struct hci_cp_auth_requested cp;
1606 cp.handle = ev->handle;
1607 hci_send_cmd(hdev,
1608 HCI_OP_AUTH_REQUESTED,
1609 sizeof(cp), &cp);
1610 }
1611 } else {
1612 conn->state = BT_CONNECTED;
1613 hci_proto_connect_cfm(conn, ev->status);
1614 hci_conn_put(conn);
1615 }
1524 } 1616 }
1525 } 1617 }
1526 1618