Commit 82346c76 authored by Marcel Holtmann's avatar Marcel Holtmann

[Bluetooth] Add security manager flags and options

This patch adds the initial flags and options for the upcoming kernel
based Bluetooth security manager.
Signed-off-by: default avatarMarcel Holtmann <marcel@holtmann.org>
parent 1dbca1a7
...@@ -68,7 +68,9 @@ enum { ...@@ -68,7 +68,9 @@ enum {
HCI_ENCRYPT, HCI_ENCRYPT,
HCI_INQUIRY, HCI_INQUIRY,
HCI_RAW HCI_RAW,
HCI_SECMGR
}; };
/* HCI ioctl defines */ /* HCI ioctl defines */
...@@ -91,7 +93,8 @@ enum { ...@@ -91,7 +93,8 @@ enum {
#define HCISETLINKMODE _IOW('H', 226, int) #define HCISETLINKMODE _IOW('H', 226, int)
#define HCISETACLMTU _IOW('H', 227, int) #define HCISETACLMTU _IOW('H', 227, int)
#define HCISETSCOMTU _IOW('H', 228, int) #define HCISETSCOMTU _IOW('H', 228, int)
#define HCISETRAWVND _IOW('H', 229, int)
#define HCISETSECMGR _IOW('H', 230, int)
#define HCIINQUIRY _IOR('H', 240, int) #define HCIINQUIRY _IOR('H', 240, int)
...@@ -324,20 +327,28 @@ struct hci_cp_inquiry { ...@@ -324,20 +327,28 @@ struct hci_cp_inquiry {
#define OCF_INQUIRY_CANCEL 0x0002 #define OCF_INQUIRY_CANCEL 0x0002
#define OCF_LINK_KEY_REPLY 0x000B #define OCF_LINK_KEY_REPLY 0x000B
#define OCF_LINK_KEY_NEG_REPLY 0x000C
struct hci_cp_link_key_reply { struct hci_cp_link_key_reply {
bdaddr_t bdaddr; bdaddr_t bdaddr;
__u8 link_key[16]; __u8 link_key[16];
} __attribute__ ((packed)); } __attribute__ ((packed));
#define OCF_LINK_KEY_NEG_REPLY 0x000C
struct hci_cp_link_key_neg_reply {
bdaddr_t bdaddr;
} __attribute__ ((packed));
#define OCF_PIN_CODE_REPLY 0x000D #define OCF_PIN_CODE_REPLY 0x000D
#define OCF_PIN_CODE_NEG_REPLY 0x000E
struct hci_cp_pin_code_reply { struct hci_cp_pin_code_reply {
bdaddr_t bdaddr; bdaddr_t bdaddr;
__u8 pin_len; __u8 pin_len;
__u8 pin_code[16]; __u8 pin_code[16];
} __attribute__ ((packed)); } __attribute__ ((packed));
#define OCF_PIN_CODE_NEG_REPLY 0x000E
struct hci_cp_pin_code_neg_reply {
bdaddr_t bdaddr;
} __attribute__ ((packed));
#define OCF_CHANGE_CONN_PTYPE 0x000F #define OCF_CHANGE_CONN_PTYPE 0x000F
struct hci_cp_change_conn_ptype { struct hci_cp_change_conn_ptype {
__u16 handle; __u16 handle;
......
...@@ -104,7 +104,7 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff * ...@@ -104,7 +104,7 @@ static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *
else else
conn->link_mode |= HCI_LM_MASTER; conn->link_mode |= HCI_LM_MASTER;
} }
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
break; break;
...@@ -320,7 +320,7 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s ...@@ -320,7 +320,7 @@ static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *s
hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt); hdev->sco_pkts = hdev->sco_cnt = __le16_to_cpu(bs->sco_max_pkt);
BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name, BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts); hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
break; break;
case OCF_READ_BD_ADDR: case OCF_READ_BD_ADDR:
...@@ -400,7 +400,7 @@ static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status) ...@@ -400,7 +400,7 @@ static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status); BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
hci_dev_lock(hdev); hci_dev_lock(hdev);
acl = hci_conn_hash_lookup_handle(hdev, handle); acl = hci_conn_hash_lookup_handle(hdev, handle);
if (acl && (sco = acl->link)) { if (acl && (sco = acl->link)) {
sco->state = BT_CLOSED; sco->state = BT_CLOSED;
...@@ -542,7 +542,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk ...@@ -542,7 +542,7 @@ static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *sk
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
bacpy(&cp.bdaddr, &ev->bdaddr); bacpy(&cp.bdaddr, &ev->bdaddr);
if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER)) if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
cp.role = 0x00; /* Become master */ cp.role = 0x00; /* Become master */
else else
...@@ -585,7 +585,6 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s ...@@ -585,7 +585,6 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s
if (test_bit(HCI_ENCRYPT, &hdev->flags)) if (test_bit(HCI_ENCRYPT, &hdev->flags))
conn->link_mode |= HCI_LM_ENCRYPT; conn->link_mode |= HCI_LM_ENCRYPT;
/* Set link policy */ /* Set link policy */
if (conn->type == ACL_LINK && hdev->link_policy) { if (conn->type == ACL_LINK && hdev->link_policy) {
struct hci_cp_write_link_policy cp; struct hci_cp_write_link_policy cp;
...@@ -710,7 +709,7 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb ...@@ -710,7 +709,7 @@ static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb
if (conn) { if (conn) {
if (ev->role) if (ev->role)
conn->link_mode &= ~HCI_LM_MASTER; conn->link_mode &= ~HCI_LM_MASTER;
else else
conn->link_mode |= HCI_LM_MASTER; conn->link_mode |= HCI_LM_MASTER;
} }
...@@ -774,13 +773,28 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff * ...@@ -774,13 +773,28 @@ static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *
conn->link_mode &= ~HCI_LM_ENCRYPT; conn->link_mode &= ~HCI_LM_ENCRYPT;
} }
clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend); clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
hci_proto_encrypt_cfm(conn, ev->status); hci_proto_encrypt_cfm(conn, ev->status);
} }
hci_dev_unlock(hdev); hci_dev_unlock(hdev);
} }
/* Pin Code Request*/
static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
}
/* Link Key Request */
static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
}
/* Link Key Notification */
static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
}
void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
{ {
struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data; struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
...@@ -833,6 +847,18 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb) ...@@ -833,6 +847,18 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
hci_encrypt_change_evt(hdev, skb); hci_encrypt_change_evt(hdev, skb);
break; break;
case HCI_EV_PIN_CODE_REQ:
hci_pin_code_request_evt(hdev, skb);
break;
case HCI_EV_LINK_KEY_REQ:
hci_link_key_request_evt(hdev, skb);
break;
case HCI_EV_LINK_KEY_NOTIFY:
hci_link_key_notify_evt(hdev, skb);
break;
case HCI_EV_CMD_STATUS: case HCI_EV_CMD_STATUS:
cs = (struct hci_ev_cmd_status *) skb->data; cs = (struct hci_ev_cmd_status *) skb->data;
skb_pull(skb, sizeof(cs)); skb_pull(skb, sizeof(cs));
......
...@@ -185,6 +185,17 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign ...@@ -185,6 +185,17 @@ static inline int hci_sock_bound_ioctl(struct sock *sk, unsigned int cmd, unsign
return 0; return 0;
case HCISETSECMGR:
if (!capable(CAP_NET_ADMIN))
return -EACCES;
if (arg)
set_bit(HCI_SECMGR, &hdev->flags);
else
clear_bit(HCI_SECMGR, &hdev->flags);
return 0;
case HCIGETCONNINFO: case HCIGETCONNINFO:
return hci_get_conn_info(hdev, (void __user *)arg); return hci_get_conn_info(hdev, (void __user *)arg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment