public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ v3 0/7] Support Sixaxis gamepad with classic bonded only
@ 2025-04-24 14:48 Ludovico de Nittis
  2025-04-24 14:48 ` [PATCH BlueZ v3 1/7] src: Add new CablePairing property Ludovico de Nittis
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Ludovico de Nittis @ 2025-04-24 14:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ludovico de Nittis

This series adds a new "CablePairing" property to allow us to
indentify devices that have been paired using a custom USB cable
cable method and that don't support the canonical bonding with
encryption. With that information, we can dynamically enforce
encryption to drastically reduce the attack surface, compared to just
disabling the "ClassicBondedOnly" property.

The "CablePairing" property is exposed via D-Bus to allow
clients to potentually show this information to end users.

As far as I can tell, starting the listening input server with
BT_IO_SEC_LOW and then bumping it in `hidp_add_connection()` should not
have any negative effect regarding the overall security. However,
please let me know if it turns out not being the case.

Addresses https://github.com/bluez/bluez/issues/1165

Changes in v2:
 - Start the listening input server with BT_IO_SEC_LOW only if we
   actually have a known sixaxis device

Changes in v3:
  - Change the property from being sixaxis specific to a generic
    "CablePairing"
  - Remove the manual validation of Sixaxis HID report descriptor
    because we already replace it with a pre-dermined SDP record
    in `sixaxis.c`

Ludovico de Nittis (7):
  src: Add new CablePairing property
  client: Print CablePairing property
  sixaxis: Set CablePairing when pairing a Sixaxis with USB
  adapter: Add btd_adapter_has_cable_pairing_devices()
  input: Automatically use sec level low when using a cable paired
    device
  adapter: Set server security level in load_devices()
  sixaxis: Set security level when adding a sixaxis device

 client/main.c            |  1 +
 doc/org.bluez.Device.rst |  7 +++++
 plugins/sixaxis.c        |  8 ++++-
 profiles/input/device.c  |  9 ++++--
 profiles/input/manager.c |  3 +-
 profiles/input/server.c  | 63 ++++++++++++++++++++++++++++++++++++++--
 profiles/input/server.h  |  3 +-
 src/adapter.c            | 24 +++++++++++++++
 src/adapter.h            |  1 +
 src/device.c             | 40 +++++++++++++++++++++++++
 src/device.h             |  2 ++
 11 files changed, 153 insertions(+), 8 deletions(-)

-- 
2.49.0


^ permalink raw reply	[flat|nested] 14+ messages in thread
* [PATCH BlueZ v4 1/6] src: Add new CablePairing property
@ 2025-04-24 16:02 Ludovico de Nittis
  2025-04-24 17:17 ` Support Sixaxis gamepad with classic bonded only bluez.test.bot
  0 siblings, 1 reply; 14+ messages in thread
From: Ludovico de Nittis @ 2025-04-24 16:02 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ludovico de Nittis

This adds initial support for a new CablePairing property.
The property can be used for devices that are paired using a cable and
don't support the expected bonding (with pairing/encryption), for
example like the Sixaxis gamepads.
---
 doc/org.bluez.Device.rst |  7 +++++++
 src/device.c             | 40 ++++++++++++++++++++++++++++++++++++++++
 src/device.h             |  2 ++
 3 files changed, 49 insertions(+)

diff --git a/doc/org.bluez.Device.rst b/doc/org.bluez.Device.rst
index 13328249b..80501eddd 100644
--- a/doc/org.bluez.Device.rst
+++ b/doc/org.bluez.Device.rst
@@ -279,6 +279,13 @@ boolean LegacyPairing [readonly]
 	Bluetooth 2.1 (or newer) devices that have disabled Extended Inquiry
 	Response support.
 
+boolean CablePairing [readonly]
+```````````````````````````````
+
+	Set to true if the device was cable paired and it doesn't support the
+	canonical bonding with encryption, e.g. the Sixaxis gamepad.
+	If true, BlueZ will establish a connection without enforcing encryption.
+
 string Modalias [readonly, optional]
 ````````````````````````````````````
 
diff --git a/src/device.c b/src/device.c
index b82a905f9..123d44c14 100644
--- a/src/device.c
+++ b/src/device.c
@@ -239,6 +239,7 @@ struct btd_device {
 	GSList		*watches;		/* List of disconnect_data */
 	bool		temporary;
 	bool		connectable;
+	bool		cable_pairing;
 	unsigned int	disconn_timer;
 	unsigned int	discov_timer;
 	unsigned int	temporary_timer;	/* Temporary/disappear timer */
@@ -507,6 +508,9 @@ static gboolean store_device_info_cb(gpointer user_data)
 	g_key_file_set_boolean(key_file, "General", "Blocked",
 							device->blocked);
 
+	g_key_file_set_boolean(key_file, "General", "CablePairing",
+							device->cable_pairing);
+
 	if (device->wake_override != WAKE_FLAG_DEFAULT) {
 		g_key_file_set_boolean(key_file, "General", "WakeAllowed",
 				       device->wake_override ==
@@ -908,6 +912,11 @@ bool btd_device_is_trusted(struct btd_device *device)
 	return device->trusted;
 }
 
+bool device_is_cable_pairing(struct btd_device *device)
+{
+	return device->cable_pairing;
+}
+
 static gboolean dev_property_get_address(const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
 {
@@ -1153,6 +1162,17 @@ static gboolean dev_property_get_legacy(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static gboolean dev_property_get_cable_pairing(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_device *device = data;
+	dbus_bool_t val = device->cable_pairing;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
+
+	return TRUE;
+}
+
 static gboolean dev_property_get_rssi(const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
 {
@@ -3483,6 +3503,7 @@ static const GDBusPropertyTable device_properties[] = {
 	{ "Trusted", "b", dev_property_get_trusted, dev_property_set_trusted },
 	{ "Blocked", "b", dev_property_get_blocked, dev_property_set_blocked },
 	{ "LegacyPairing", "b", dev_property_get_legacy },
+	{ "CablePairing", "b", dev_property_get_cable_pairing },
 	{ "RSSI", "n", dev_property_get_rssi, NULL, dev_property_exists_rssi },
 	{ "Connected", "b", dev_property_get_connected },
 	{ "UUIDs", "as", dev_property_get_uuids },
@@ -4062,6 +4083,9 @@ next:
 	if (blocked)
 		device_block(device, FALSE);
 
+	device->cable_pairing = g_key_file_get_boolean(key_file, "General",
+							"CablePairing", NULL);
+
 	/* Load device profile list */
 	uuids = g_key_file_get_string_list(key_file, "General", "Services",
 						NULL, NULL);
@@ -6416,6 +6440,22 @@ void device_set_legacy(struct btd_device *device, bool legacy)
 					DEVICE_INTERFACE, "LegacyPairing");
 }
 
+void device_set_cable_pairing(struct btd_device *device, bool cable_pairing)
+{
+	if (!device)
+		return;
+
+	if (device->cable_pairing == cable_pairing)
+		return;
+
+	DBG("setting cable pairing %d", cable_pairing);
+
+	device->cable_pairing = cable_pairing;
+
+	g_dbus_emit_property_changed(dbus_conn, device->path,
+					DEVICE_INTERFACE, "CablePairing");
+}
+
 void device_store_svc_chng_ccc(struct btd_device *device, uint8_t bdaddr_type,
 								uint16_t value)
 {
diff --git a/src/device.h b/src/device.h
index 2e4a9771d..a35bb1386 100644
--- a/src/device.h
+++ b/src/device.h
@@ -94,6 +94,7 @@ bool device_is_connectable(struct btd_device *device);
 bool device_is_paired(struct btd_device *device, uint8_t bdaddr_type);
 bool device_is_bonded(struct btd_device *device, uint8_t bdaddr_type);
 bool btd_device_is_trusted(struct btd_device *device);
+bool device_is_cable_pairing(struct btd_device *device);
 void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type);
 void device_set_unpaired(struct btd_device *dev, uint8_t bdaddr_type);
 void btd_device_set_temporary(struct btd_device *device, bool temporary);
@@ -101,6 +102,7 @@ void btd_device_set_trusted(struct btd_device *device, gboolean trusted);
 void btd_device_set_connectable(struct btd_device *device, bool connectable);
 void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type);
 void device_set_legacy(struct btd_device *device, bool legacy);
+void device_set_cable_pairing(struct btd_device *device, bool cable_pairing);
 void device_set_rssi_with_delta(struct btd_device *device, int8_t rssi,
 							int8_t delta_threshold);
 void device_set_rssi(struct btd_device *device, int8_t rssi);
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread
* [PATCH BlueZ v5 1/6] src: Add new CablePairing property
@ 2025-04-24 16:29 Ludovico de Nittis
  2025-04-24 17:58 ` Support Sixaxis gamepad with classic bonded only bluez.test.bot
  0 siblings, 1 reply; 14+ messages in thread
From: Ludovico de Nittis @ 2025-04-24 16:29 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Ludovico de Nittis

This adds initial support for a new CablePairing property.
The property can be used for devices that are paired using a cable and
don't support the expected bonding (with pairing/encryption), for
example like the Sixaxis gamepads.
---
 doc/org.bluez.Device.rst |  7 +++++++
 src/device.c             | 40 ++++++++++++++++++++++++++++++++++++++++
 src/device.h             |  2 ++
 3 files changed, 49 insertions(+)

diff --git a/doc/org.bluez.Device.rst b/doc/org.bluez.Device.rst
index 13328249b..80501eddd 100644
--- a/doc/org.bluez.Device.rst
+++ b/doc/org.bluez.Device.rst
@@ -279,6 +279,13 @@ boolean LegacyPairing [readonly]
 	Bluetooth 2.1 (or newer) devices that have disabled Extended Inquiry
 	Response support.
 
+boolean CablePairing [readonly]
+```````````````````````````````
+
+	Set to true if the device was cable paired and it doesn't support the
+	canonical bonding with encryption, e.g. the Sixaxis gamepad.
+	If true, BlueZ will establish a connection without enforcing encryption.
+
 string Modalias [readonly, optional]
 ````````````````````````````````````
 
diff --git a/src/device.c b/src/device.c
index b82a905f9..123d44c14 100644
--- a/src/device.c
+++ b/src/device.c
@@ -239,6 +239,7 @@ struct btd_device {
 	GSList		*watches;		/* List of disconnect_data */
 	bool		temporary;
 	bool		connectable;
+	bool		cable_pairing;
 	unsigned int	disconn_timer;
 	unsigned int	discov_timer;
 	unsigned int	temporary_timer;	/* Temporary/disappear timer */
@@ -507,6 +508,9 @@ static gboolean store_device_info_cb(gpointer user_data)
 	g_key_file_set_boolean(key_file, "General", "Blocked",
 							device->blocked);
 
+	g_key_file_set_boolean(key_file, "General", "CablePairing",
+							device->cable_pairing);
+
 	if (device->wake_override != WAKE_FLAG_DEFAULT) {
 		g_key_file_set_boolean(key_file, "General", "WakeAllowed",
 				       device->wake_override ==
@@ -908,6 +912,11 @@ bool btd_device_is_trusted(struct btd_device *device)
 	return device->trusted;
 }
 
+bool device_is_cable_pairing(struct btd_device *device)
+{
+	return device->cable_pairing;
+}
+
 static gboolean dev_property_get_address(const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
 {
@@ -1153,6 +1162,17 @@ static gboolean dev_property_get_legacy(const GDBusPropertyTable *property,
 	return TRUE;
 }
 
+static gboolean dev_property_get_cable_pairing(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_device *device = data;
+	dbus_bool_t val = device->cable_pairing;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
+
+	return TRUE;
+}
+
 static gboolean dev_property_get_rssi(const GDBusPropertyTable *property,
 					DBusMessageIter *iter, void *data)
 {
@@ -3483,6 +3503,7 @@ static const GDBusPropertyTable device_properties[] = {
 	{ "Trusted", "b", dev_property_get_trusted, dev_property_set_trusted },
 	{ "Blocked", "b", dev_property_get_blocked, dev_property_set_blocked },
 	{ "LegacyPairing", "b", dev_property_get_legacy },
+	{ "CablePairing", "b", dev_property_get_cable_pairing },
 	{ "RSSI", "n", dev_property_get_rssi, NULL, dev_property_exists_rssi },
 	{ "Connected", "b", dev_property_get_connected },
 	{ "UUIDs", "as", dev_property_get_uuids },
@@ -4062,6 +4083,9 @@ next:
 	if (blocked)
 		device_block(device, FALSE);
 
+	device->cable_pairing = g_key_file_get_boolean(key_file, "General",
+							"CablePairing", NULL);
+
 	/* Load device profile list */
 	uuids = g_key_file_get_string_list(key_file, "General", "Services",
 						NULL, NULL);
@@ -6416,6 +6440,22 @@ void device_set_legacy(struct btd_device *device, bool legacy)
 					DEVICE_INTERFACE, "LegacyPairing");
 }
 
+void device_set_cable_pairing(struct btd_device *device, bool cable_pairing)
+{
+	if (!device)
+		return;
+
+	if (device->cable_pairing == cable_pairing)
+		return;
+
+	DBG("setting cable pairing %d", cable_pairing);
+
+	device->cable_pairing = cable_pairing;
+
+	g_dbus_emit_property_changed(dbus_conn, device->path,
+					DEVICE_INTERFACE, "CablePairing");
+}
+
 void device_store_svc_chng_ccc(struct btd_device *device, uint8_t bdaddr_type,
 								uint16_t value)
 {
diff --git a/src/device.h b/src/device.h
index 2e4a9771d..a35bb1386 100644
--- a/src/device.h
+++ b/src/device.h
@@ -94,6 +94,7 @@ bool device_is_connectable(struct btd_device *device);
 bool device_is_paired(struct btd_device *device, uint8_t bdaddr_type);
 bool device_is_bonded(struct btd_device *device, uint8_t bdaddr_type);
 bool btd_device_is_trusted(struct btd_device *device);
+bool device_is_cable_pairing(struct btd_device *device);
 void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type);
 void device_set_unpaired(struct btd_device *dev, uint8_t bdaddr_type);
 void btd_device_set_temporary(struct btd_device *device, bool temporary);
@@ -101,6 +102,7 @@ void btd_device_set_trusted(struct btd_device *device, gboolean trusted);
 void btd_device_set_connectable(struct btd_device *device, bool connectable);
 void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type);
 void device_set_legacy(struct btd_device *device, bool legacy);
+void device_set_cable_pairing(struct btd_device *device, bool cable_pairing);
 void device_set_rssi_with_delta(struct btd_device *device, int8_t rssi,
 							int8_t delta_threshold);
 void device_set_rssi(struct btd_device *device, int8_t rssi);
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2025-04-24 17:58 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-24 14:48 [PATCH BlueZ v3 0/7] Support Sixaxis gamepad with classic bonded only Ludovico de Nittis
2025-04-24 14:48 ` [PATCH BlueZ v3 1/7] src: Add new CablePairing property Ludovico de Nittis
2025-04-24 17:16   ` Support Sixaxis gamepad with classic bonded only bluez.test.bot
2025-04-24 14:48 ` [PATCH BlueZ v3 2/7] client: Print CablePairing property Ludovico de Nittis
2025-04-24 14:48 ` [PATCH BlueZ v3 3/7] sixaxis: Set CablePairing when pairing a Sixaxis with USB Ludovico de Nittis
2025-04-24 14:48 ` [PATCH BlueZ v3 4/7] adapter: Add btd_adapter_has_cable_pairing_devices() Ludovico de Nittis
2025-04-24 14:48 ` [PATCH BlueZ v3 5/7] input: Automatically use sec level low when using a cable paired device Ludovico de Nittis
2025-04-24 14:48 ` [PATCH BlueZ v3 6/7] adapter: Set server security level in load_devices() Ludovico de Nittis
2025-04-24 14:57   ` Luiz Augusto von Dentz
2025-04-24 15:10     ` Ludovico de Nittis
2025-04-24 15:20       ` Luiz Augusto von Dentz
2025-04-24 14:48 ` [PATCH BlueZ v3 7/7] sixaxis: Set security level when adding a sixaxis device Ludovico de Nittis
  -- strict thread matches above, loose matches on Subject: below --
2025-04-24 16:02 [PATCH BlueZ v4 1/6] src: Add new CablePairing property Ludovico de Nittis
2025-04-24 17:17 ` Support Sixaxis gamepad with classic bonded only bluez.test.bot
2025-04-24 16:29 [PATCH BlueZ v5 1/6] src: Add new CablePairing property Ludovico de Nittis
2025-04-24 17:58 ` Support Sixaxis gamepad with classic bonded only bluez.test.bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox