Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 03b555e1 authored by Johan Hedberg's avatar Johan Hedberg Committed by Gustavo Padovan
Browse files

Bluetooth: Reject pairing requests when in non-pairable mode



This patch adds the necessary logic to act accordingly when the
HCI_PAIRABLE flag is not set. In that case PIN code replies as well as
Secure Simple Pairing requests without a NoBonding requirement need to
be rejected.

Signed-off-by: default avatarJohan Hedberg <johan.hedberg@nokia.com>
Signed-off-by: default avatarGustavo F. Padovan <padovan@profusion.mobi>
parent 930e1336
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -384,6 +384,12 @@ struct hci_cp_reject_sync_conn_req {
	__u8     reason;
} __packed;

#define HCI_OP_IO_CAPABILITY_NEG_REPLY	0x0434
struct hci_cp_io_capability_neg_reply {
	bdaddr_t bdaddr;
	__u8     reason;
} __packed;

#define HCI_OP_SNIFF_MODE		0x0803
struct hci_cp_sniff_mode {
	__le16   handle;
@@ -840,6 +846,14 @@ struct hci_ev_io_capa_request {
	bdaddr_t bdaddr;
} __packed;

#define HCI_EV_IO_CAPA_REPLY		0x32
struct hci_ev_io_capa_reply {
	bdaddr_t bdaddr;
	__u8     capability;
	__u8     oob_data;
	__u8     authentication;
} __packed;

#define HCI_EV_SIMPLE_PAIR_COMPLETE	0x36
struct hci_ev_simple_pair_complete {
	__u8     status;
+4 −0
Original line number Diff line number Diff line
@@ -201,6 +201,10 @@ struct hci_conn {
	__u16            disc_timeout;
	unsigned long	 pend;

	__u8		remote_cap;
	__u8		remote_oob;
	__u8		remote_auth;

	unsigned int	 sent;

	struct sk_buff_head data_q;
+53 −2
Original line number Diff line number Diff line
@@ -1595,6 +1595,10 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
		hci_conn_put(conn);
	}

	if (!test_bit(HCI_PAIRABLE, &hdev->flags))
		hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
					sizeof(ev->bdaddr), &ev->bdaddr);

	hci_dev_unlock(hdev);
}

@@ -1885,9 +1889,52 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
	hci_dev_lock(hdev);

	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
	if (conn)
	if (!conn)
		goto unlock;

	hci_conn_hold(conn);

	if (!test_bit(HCI_MGMT, &hdev->flags))
		goto unlock;

	if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
			(conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
		/* FIXME: Do IO capa response based on information
		 * provided through the management interface */
	} else {
		struct hci_cp_io_capability_neg_reply cp;

		bacpy(&cp.bdaddr, &ev->bdaddr);
		cp.reason = 0x16; /* Pairing not allowed */

		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
							sizeof(cp), &cp);
	}

unlock:
	hci_dev_unlock(hdev);
}

static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
{
	struct hci_ev_io_capa_reply *ev = (void *) skb->data;
	struct hci_conn *conn;

	BT_DBG("%s", hdev->name);

	hci_dev_lock(hdev);

	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
	if (!conn)
		goto unlock;

	hci_conn_hold(conn);

	conn->remote_cap = ev->capability;
	conn->remote_oob = ev->oob_data;
	conn->remote_auth = ev->authentication;

unlock:
	hci_dev_unlock(hdev);
}

@@ -2051,6 +2098,10 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
		hci_io_capa_request_evt(hdev, skb);
		break;

	case HCI_EV_IO_CAPA_REPLY:
		hci_io_capa_reply_evt(hdev, skb);
		break;

	case HCI_EV_SIMPLE_PAIR_COMPLETE:
		hci_simple_pair_complete_evt(hdev, skb);
		break;