From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> This adds "auto" capability which behaves like "on" but instead of asking user to confirm/autorize it automatically accepts, which is not secure to be used thus a warning is printed when user selects it. Usage: [bluetoothctl]# agent auto Warning: setting auto response is not secure, it bypass user confirmation/authorization, it shall only be used for test automation. or client/bluetoothctl -a auto --- client/agent.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++- client/main.c | 3 +- 2 files changed, 85 insertions(+), 2 deletions(-) diff --git a/client/agent.c b/client/agent.c index c8e1560e74a8..35b404114873 100644 --- a/client/agent.c +++ b/client/agent.c @@ -258,7 +258,7 @@ static DBusMessage *cancel_request(DBusConnection *conn, return dbus_message_new_method_return(msg); } -static const GDBusMethodTable methods[] = { +static const GDBusMethodTable agent_methods[] = { { GDBUS_METHOD("Release", NULL, NULL, release_agent) }, { GDBUS_ASYNC_METHOD("RequestPinCode", GDBUS_ARGS({ "device", "o" }), @@ -286,6 +286,78 @@ static const GDBusMethodTable methods[] = { { } }; +static DBusMessage *auto_confirmation(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + const char *device; + dbus_uint32_t passkey; + + bt_shell_printf("Request confirmation\n"); + + dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device, + DBUS_TYPE_UINT32, &passkey, DBUS_TYPE_INVALID); + + bt_shell_printf("Confirm passkey %06u (auto)", passkey); + + return dbus_message_new_method_return(msg); +} + +static DBusMessage *auto_authorization(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + const char *device; + + bt_shell_printf("Request authorization\n"); + + dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device, + DBUS_TYPE_INVALID); + + bt_shell_printf("Accept pairing (auto)"); + + return dbus_message_new_method_return(msg); +} + +static DBusMessage *auto_authorize_service(DBusConnection *conn, + DBusMessage *msg, void *user_data) +{ + const char *device, *uuid; + + dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &device, + DBUS_TYPE_STRING, &uuid, DBUS_TYPE_INVALID); + + bt_shell_printf("Authorize service %s (auto)", uuid); + + return dbus_message_new_method_return(msg); +} + +static const GDBusMethodTable auto_methods[] = { + { GDBUS_METHOD("Release", NULL, NULL, release_agent) }, + { GDBUS_ASYNC_METHOD("RequestPinCode", + GDBUS_ARGS({ "device", "o" }), + GDBUS_ARGS({ "pincode", "s" }), request_pincode) }, + { GDBUS_METHOD("DisplayPinCode", + GDBUS_ARGS({ "device", "o" }, { "pincode", "s" }), + NULL, display_pincode) }, + { GDBUS_ASYNC_METHOD("RequestPasskey", + GDBUS_ARGS({ "device", "o" }), + GDBUS_ARGS({ "passkey", "u" }), request_passkey) }, + { GDBUS_METHOD("DisplayPasskey", + GDBUS_ARGS({ "device", "o" }, { "passkey", "u" }, + { "entered", "q" }), + NULL, display_passkey) }, + { GDBUS_ASYNC_METHOD("RequestConfirmation", + GDBUS_ARGS({ "device", "o" }, { "passkey", "u" }), + NULL, auto_confirmation) }, + { GDBUS_ASYNC_METHOD("RequestAuthorization", + GDBUS_ARGS({ "device", "o" }), + NULL, auto_authorization) }, + { GDBUS_ASYNC_METHOD("AuthorizeService", + GDBUS_ARGS({ "device", "o" }, { "uuid", "s" }), + NULL, auto_authorize_service) }, + { GDBUS_METHOD("Cancel", NULL, NULL, cancel_request) }, + { } +}; + static void register_agent_setup(DBusMessageIter *iter, void *user_data) { const char *path = AGENT_PATH; @@ -319,6 +391,8 @@ void agent_register(DBusConnection *conn, GDBusProxy *manager, const char *capability) { + const GDBusMethodTable *methods = agent_methods; + if (agent_registered == TRUE) { bt_shell_printf("Agent is already registered\n"); return; @@ -326,6 +400,14 @@ void agent_register(DBusConnection *conn, GDBusProxy *manager, agent_capability = capability; + if (!strcasecmp(agent_capability, "auto")) { + bt_shell_printf("Warning: setting auto response is not secure, " + "it bypass user confirmation/authorization, it " + "shall only be used for test automation.\n"); + agent_capability = ""; + methods = auto_methods; + } + if (g_dbus_register_interface(conn, AGENT_PATH, AGENT_INTERFACE, methods, NULL, NULL, NULL, NULL) == FALSE) { diff --git a/client/main.c b/client/main.c index 0eac5bdf5015..a1c536c638d9 100644 --- a/client/main.c +++ b/client/main.c @@ -66,6 +66,7 @@ static GList *battery_proxies; static const char *agent_arguments[] = { "on", "off", + "auto", "DisplayOnly", "DisplayYesNo", "KeyboardDisplay", @@ -3096,7 +3097,7 @@ static const struct bt_shell_menu main_menu = { NULL }, { "discoverable-timeout", "[value]", cmd_discoverable_timeout, "Set discoverable timeout", NULL }, - { "agent", "<on/off/capability>", cmd_agent, + { "agent", "<on/off/auto/capability>", cmd_agent, "Enable/disable agent with given capability", capability_generator}, { "default-agent",NULL, cmd_default_agent, -- 2.41.0