aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_conn.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-07-14 14:13:50 -0400
committerMarcel Holtmann <marcel@holtmann.org>2008-07-14 14:13:50 -0400
commit40be492fe4fab829951681860c2bb26fa1d5fe4a (patch)
tree41b576692c2206c9a51e689f54170076ec95bc3a /net/bluetooth/hci_conn.c
parentf8558555f31e177e2644f3c8116801c3e5c29974 (diff)
[Bluetooth] Export details about authentication requirements
With the Simple Pairing support, the authentication requirements are an explicit setting during the bonding process. Track and enforce the requirements and allow higher layers like L2CAP and RFCOMM to increase them if needed. This patch introduces a new IOCTL that allows to query the current authentication requirements. It is also possible to detect Simple Pairing support in the kernel this way. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r--net/bluetooth/hci_conn.c38
1 files changed, 34 insertions, 4 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}