From 97b930870dcd016b9cdd612e47b832736b4d0c5d Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 4 Sep 2012 13:46:41 +0300 Subject: [PATCH] core: Refactor authentication handling --- src/device.c | 133 ++++++++++++++++++++++++++++++++++++++++----------- src/device.h | 11 ++++- src/event.c | 17 +++---- 3 files changed, 119 insertions(+), 42 deletions(-) diff --git a/src/device.c b/src/device.c index 6b454ceb7..d2bac97d4 100644 --- a/src/device.c +++ b/src/device.c @@ -2782,27 +2782,26 @@ done: device->authr->agent = NULL; } - -int device_request_authentication(struct btd_device *device, auth_type_t type, - void *data, gboolean secure, void *cb) +static struct authentication_req *new_auth(struct btd_device *device, + auth_type_t type, gboolean secure, + void *cb) { struct authentication_req *auth; struct agent *agent; char addr[18]; - int err; ba2str(&device->bdaddr, addr); DBG("Requesting agent authentication for %s", addr); if (device->authr) { error("Authentication already requested for %s", addr); - return -EALREADY; + return NULL; } agent = device_get_agent(device); if (!agent) { error("No agent available for request type %d", type); - return -EPERM; + return NULL; } auth = g_new0(struct authentication_req, 1); @@ -2813,33 +2812,109 @@ int device_request_authentication(struct btd_device *device, auth_type_t type, auth->secure = secure; device->authr = auth; - switch (type) { - case AUTH_TYPE_PINCODE: - err = agent_request_pincode(agent, device, pincode_cb, secure, - auth, NULL); - break; - case AUTH_TYPE_PASSKEY: - err = agent_request_passkey(agent, device, passkey_cb, + return auth; +} + +int device_request_pincode(struct btd_device *device, gboolean secure, + void *cb) +{ + struct authentication_req *auth; + int err; + + auth = new_auth(device, AUTH_TYPE_PINCODE, secure, cb); + if (!auth) + return -EPERM; + + err = agent_request_pincode(auth->agent, device, pincode_cb, secure, auth, NULL); - break; - case AUTH_TYPE_CONFIRM: - auth->passkey = *((uint32_t *) data); - err = agent_request_confirmation(agent, device, auth->passkey, + if (err < 0) { + error("Failed requesting authentication"); + device_auth_req_free(device); + } + + return err; +} + +int device_request_passkey(struct btd_device *device, void *cb) +{ + struct authentication_req *auth; + int err; + + auth = new_auth(device, AUTH_TYPE_PASSKEY, FALSE, cb); + if (!auth) + return -EPERM; + + err = agent_request_passkey(auth->agent, device, passkey_cb, auth, + NULL); + if (err < 0) { + error("Failed requesting authentication"); + device_auth_req_free(device); + } + + return err; +} + +int device_confirm_passkey(struct btd_device *device, uint32_t passkey, + void *cb) +{ + struct authentication_req *auth; + int err; + + auth = new_auth(device, AUTH_TYPE_CONFIRM, FALSE, cb); + if (!auth) + return -EPERM; + + auth->passkey = passkey; + + err = agent_request_confirmation(auth->agent, device, passkey, confirm_cb, auth, NULL); - break; - case AUTH_TYPE_NOTIFY_PASSKEY: - auth->passkey = *((uint32_t *) data); - err = agent_display_passkey(agent, device, auth->passkey); - break; - case AUTH_TYPE_NOTIFY_PINCODE: - auth->pincode = g_strdup((const char *) data); - err = agent_display_pincode(agent, device, auth->pincode, - display_pincode_cb, auth, NULL); - break; - default: - err = -EINVAL; + if (err < 0) { + error("Failed requesting authentication"); + device_auth_req_free(device); } + return err; +} + +int device_notify_passkey(struct btd_device *device, uint32_t passkey, + uint8_t entered) +{ + struct authentication_req *auth; + int err; + + if (device->authr) { + auth = device->authr; + if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY) + return -EPERM; + } else { + auth = new_auth(device, AUTH_TYPE_NOTIFY_PASSKEY, FALSE, NULL); + if (!auth) + return -EPERM; + } + + err = agent_display_passkey(auth->agent, device, passkey, entered); + if (err < 0) { + error("Failed requesting authentication"); + device_auth_req_free(device); + } + + return err; +} + +int device_notify_pincode(struct btd_device *device, gboolean secure, + const char *pincode, void *cb) +{ + struct authentication_req *auth; + int err; + + auth = new_auth(device, AUTH_TYPE_NOTIFY_PINCODE, secure, cb); + if (!auth) + return -EPERM; + + auth->pincode = g_strdup(pincode); + + err = agent_display_pincode(auth->agent, device, pincode, + display_pincode_cb, auth, NULL); if (err < 0) { error("Failed requesting authentication"); device_auth_req_free(device); diff --git a/src/device.h b/src/device.h index ccb15fc80..edc64b991 100644 --- a/src/device.h +++ b/src/device.h @@ -119,8 +119,15 @@ void device_simple_pairing_complete(struct btd_device *device, uint8_t status); gboolean device_is_creating(struct btd_device *device, const char *sender); gboolean device_is_bonding(struct btd_device *device, const char *sender); void device_cancel_bonding(struct btd_device *device, uint8_t status); -int device_request_authentication(struct btd_device *device, auth_type_t type, - void *data, gboolean secure, void *cb); +int device_request_pincode(struct btd_device *device, gboolean secure, + void *cb); +int device_request_passkey(struct btd_device *device, void *cb); +int device_confirm_passkey(struct btd_device *device, uint32_t passkey, + void *cb); +int device_notify_passkey(struct btd_device *device, uint32_t passkey, + uint8_t entered); +int device_notify_pincode(struct btd_device *device, gboolean secure, + const char *pincode, void *cb); void device_cancel_authentication(struct btd_device *device, gboolean aborted); gboolean device_is_authenticating(struct btd_device *device); gboolean device_is_authorizing(struct btd_device *device); diff --git a/src/event.c b/src/event.c index 42d05b692..26bbf64a9 100644 --- a/src/event.c +++ b/src/event.c @@ -129,16 +129,14 @@ int btd_event_request_pin(bdaddr_t *sba, bdaddr_t *dba, gboolean secure) pinlen = btd_adapter_get_pin(adapter, device, pin, &display); if (pinlen > 0 && (!secure || pinlen == 16)) { if (display && device_is_bonding(device, NULL)) - return device_request_authentication(device, - AUTH_TYPE_NOTIFY_PINCODE, pin, - secure, pincode_cb); + return device_notify_pincode(device, secure, pin, + pincode_cb); btd_adapter_pincode_reply(adapter, dba, pin, pinlen); return 0; } - return device_request_authentication(device, AUTH_TYPE_PINCODE, NULL, - secure, pincode_cb); + return device_request_pincode(device, secure, pincode_cb); } static int confirm_reply(struct btd_adapter *adapter, @@ -186,8 +184,7 @@ int btd_event_user_confirm(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE)) return -ENODEV; - return device_request_authentication(device, AUTH_TYPE_CONFIRM, - &passkey, FALSE, confirm_cb); + return device_confirm_passkey(device, passkey, confirm_cb); } int btd_event_user_passkey(bdaddr_t *sba, bdaddr_t *dba) @@ -198,8 +195,7 @@ int btd_event_user_passkey(bdaddr_t *sba, bdaddr_t *dba) if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE)) return -ENODEV; - return device_request_authentication(device, AUTH_TYPE_PASSKEY, NULL, - FALSE, passkey_cb); + return device_request_passkey(device, passkey_cb); } int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) @@ -210,8 +206,7 @@ int btd_event_user_notify(bdaddr_t *sba, bdaddr_t *dba, uint32_t passkey) if (!get_adapter_and_device(sba, dba, &adapter, &device, TRUE)) return -ENODEV; - return device_request_authentication(device, AUTH_TYPE_NOTIFY_PASSKEY, - &passkey, FALSE, NULL); + return device_notify_passkey(device, passkey, 0); } void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer, -- 2.47.3