diff options
-rw-r--r-- | net/bluetooth/hci_event.c | 54 |
1 files changed, 40 insertions, 14 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 84302768939a..9c6d9bc1d8af 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -677,6 +677,29 @@ static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status) | |||
677 | hci_dev_unlock(hdev); | 677 | hci_dev_unlock(hdev); |
678 | } | 678 | } |
679 | 679 | ||
680 | static int hci_request_outgoing_auth(struct hci_dev *hdev, | ||
681 | struct hci_conn *conn) | ||
682 | { | ||
683 | struct hci_cp_auth_requested cp; | ||
684 | |||
685 | if (conn->state != BT_CONFIG || !conn->out) | ||
686 | return 0; | ||
687 | |||
688 | if (conn->sec_level == BT_SECURITY_SDP) | ||
689 | return 0; | ||
690 | |||
691 | /* Only request authentication for SSP connections or non-SSP | ||
692 | * devices with sec_level HIGH */ | ||
693 | if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) && | ||
694 | conn->sec_level != BT_SECURITY_HIGH) | ||
695 | return 0; | ||
696 | |||
697 | cp.handle = __cpu_to_le16(conn->handle); | ||
698 | hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); | ||
699 | |||
700 | return 1; | ||
701 | } | ||
702 | |||
680 | static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) | 703 | static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status) |
681 | { | 704 | { |
682 | BT_DBG("%s status 0x%x", hdev->name, status); | 705 | BT_DBG("%s status 0x%x", hdev->name, status); |
@@ -1156,6 +1179,7 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff | |||
1156 | { | 1179 | { |
1157 | struct hci_ev_remote_features *ev = (void *) skb->data; | 1180 | struct hci_ev_remote_features *ev = (void *) skb->data; |
1158 | struct hci_conn *conn; | 1181 | struct hci_conn *conn; |
1182 | int auth_requested; | ||
1159 | 1183 | ||
1160 | BT_DBG("%s status %d", hdev->name, ev->status); | 1184 | BT_DBG("%s status %d", hdev->name, ev->status); |
1161 | 1185 | ||
@@ -1177,12 +1201,15 @@ static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff | |||
1177 | cp.page = 0x01; | 1201 | cp.page = 0x01; |
1178 | hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, | 1202 | hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES, |
1179 | sizeof(cp), &cp); | 1203 | sizeof(cp), &cp); |
1180 | } else if (!ev->status && conn->out && | 1204 | goto unlock; |
1181 | conn->sec_level == BT_SECURITY_HIGH) { | 1205 | } |
1182 | struct hci_cp_auth_requested cp; | 1206 | |
1183 | cp.handle = ev->handle; | 1207 | if (!ev->status) |
1184 | hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); | 1208 | auth_requested = hci_request_outgoing_auth(hdev, conn); |
1185 | } else { | 1209 | else |
1210 | auth_requested = 0; | ||
1211 | |||
1212 | if (!auth_requested) { | ||
1186 | conn->state = BT_CONNECTED; | 1213 | conn->state = BT_CONNECTED; |
1187 | hci_proto_connect_cfm(conn, ev->status); | 1214 | hci_proto_connect_cfm(conn, ev->status); |
1188 | hci_conn_put(conn); | 1215 | hci_conn_put(conn); |
@@ -1640,6 +1667,7 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b | |||
1640 | { | 1667 | { |
1641 | struct hci_ev_remote_ext_features *ev = (void *) skb->data; | 1668 | struct hci_ev_remote_ext_features *ev = (void *) skb->data; |
1642 | struct hci_conn *conn; | 1669 | struct hci_conn *conn; |
1670 | int auth_requested; | ||
1643 | 1671 | ||
1644 | BT_DBG("%s", hdev->name); | 1672 | BT_DBG("%s", hdev->name); |
1645 | 1673 | ||
@@ -1661,14 +1689,12 @@ static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_b | |||
1661 | if (conn->state != BT_CONFIG) | 1689 | if (conn->state != BT_CONFIG) |
1662 | goto unlock; | 1690 | goto unlock; |
1663 | 1691 | ||
1664 | if (!ev->status && hdev->ssp_mode > 0 && | 1692 | if (!ev->status) |
1665 | conn->ssp_mode > 0 && conn->out && | 1693 | auth_requested = hci_request_outgoing_auth(hdev, conn); |
1666 | conn->sec_level != BT_SECURITY_SDP) { | 1694 | else |
1667 | struct hci_cp_auth_requested cp; | 1695 | auth_requested = 0; |
1668 | cp.handle = ev->handle; | 1696 | |
1669 | hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, | 1697 | if (!auth_requested) { |
1670 | sizeof(cp), &cp); | ||
1671 | } else { | ||
1672 | conn->state = BT_CONNECTED; | 1698 | conn->state = BT_CONNECTED; |
1673 | hci_proto_connect_cfm(conn, ev->status); | 1699 | hci_proto_connect_cfm(conn, ev->status); |
1674 | hci_conn_put(conn); | 1700 | hci_conn_put(conn); |