diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2008-06-06 11:28:57 +0000 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2008-06-06 11:28:57 +0000 |
commit | 833b95efc8bda83851624b203991db196282335c (patch) | |
tree | 91a36d9f9ab649b504685a018e88bc73ae0d4502 /hcid | |
parent | 30877999b61e655ff7f4e804240098c4cd31831e (diff) |
Further cleanup of authentication logic
Diffstat (limited to 'hcid')
-rw-r--r-- | hcid/adapter.c | 4 | ||||
-rw-r--r-- | hcid/adapter.h | 9 | ||||
-rw-r--r-- | hcid/dbus-hci.c | 35 | ||||
-rw-r--r-- | hcid/dbus-hci.h | 3 | ||||
-rw-r--r-- | hcid/dbus-security.c | 170 | ||||
-rw-r--r-- | hcid/security.c | 46 |
6 files changed, 43 insertions, 224 deletions
diff --git a/hcid/adapter.c b/hcid/adapter.c index d958a04b..8d71b3bd 100644 --- a/hcid/adapter.c +++ b/hcid/adapter.c @@ -2628,7 +2628,7 @@ static void create_bond_req_exit(void *user_data) l = g_slist_find_custom(adapter->pin_reqs, &adapter->bonding->bdaddr, pin_req_cmp); if (l) { - struct pending_pin_info *p = l->data; + struct pending_auth_info *p = l->data; if (!p->replied) { int dd; @@ -2773,7 +2773,7 @@ static DBusMessage *adapter_cancel_bonding(DBusConnection *conn, l = g_slist_find_custom(adapter->pin_reqs, &bdaddr, pin_req_cmp); if (l) { - struct pending_pin_info *pin_req = l->data; + struct pending_auth_info *pin_req = l->data; if (pin_req->replied) { /* diff --git a/hcid/adapter.h b/hcid/adapter.h index 7808609a..ec2c3f81 100644 --- a/hcid/adapter.h +++ b/hcid/adapter.h @@ -46,6 +46,12 @@ typedef enum { NAME_SENT /* D-Bus signal RemoteNameUpdated sent */ } name_status_t; +typedef enum { + AUTH_TYPE_PINCODE, + AUTH_TYPE_PASSKEY, + AUTH_TYPE_CONFIRM, +} auth_type_t; + struct remote_dev_info { bdaddr_t bdaddr; int8_t rssi; @@ -65,7 +71,8 @@ struct bonding_request_info { int auth_active; }; -struct pending_pin_info { +struct pending_auth_info { + auth_type_t type; bdaddr_t bdaddr; int replied; /* If we've already replied to the request */ }; diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c index 61bd1cd1..8c93a883 100644 --- a/hcid/dbus-hci.c +++ b/hcid/dbus-hci.c @@ -929,16 +929,16 @@ int hcid_dbus_stop_device(uint16_t id) int pin_req_cmp(const void *p1, const void *p2) { - const struct pending_pin_info *pb1 = p1; - const struct pending_pin_info *pb2 = p2; + const struct pending_auth_info *pb1 = p1; + const struct pending_auth_info *pb2 = p2; return p2 ? bacmp(&pb1->bdaddr, &pb2->bdaddr) : -1; } -void hcid_dbus_pending_pin_req_add(bdaddr_t *sba, bdaddr_t *dba) +void hcid_dbus_new_auth_request(bdaddr_t *sba, bdaddr_t *dba, auth_type_t type) { struct adapter *adapter; - struct pending_pin_info *info; + struct pending_auth_info *info; adapter = find_adapter(sba); if (!adapter) { @@ -946,9 +946,10 @@ void hcid_dbus_pending_pin_req_add(bdaddr_t *sba, bdaddr_t *dba) return; } - info = g_new0(struct pending_pin_info, 1); + info = g_new0(struct pending_auth_info, 1); bacpy(&info->bdaddr, dba); + info->type = type; adapter->pin_reqs = g_slist_append(adapter->pin_reqs, info); if (adapter->bonding && !bacmp(dba, &adapter->bonding->bdaddr)) @@ -1159,20 +1160,6 @@ int hcid_dbus_user_passkey(bdaddr_t *sba, bdaddr_t *dba) return 0; } -int hcid_dbus_confirm_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci, char *pin) -{ - struct adapter *adapter; - - adapter = find_adapter(sba); - if (!adapter) { - error("No matching adapter found"); - return -1; - } - - return handle_confirm_request_old(connection, dev, adapter, - sba, &ci->bdaddr, pin); -} - void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, uint8_t status) { @@ -1186,6 +1173,8 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, void *d; gboolean paired = TRUE; + debug("hcid_dbus_bonding_process_complete: status=%02x", status); + ba2str(peer, peer_addr); adapter = find_adapter(local); @@ -1216,6 +1205,8 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer, if (device) { char *ptr = adapter->path + ADAPTER_PATH_INDEX; + debug("hcid_dbus_bonding_process_complete: removing temporary flag"); + device->temporary = FALSE; dbus_connection_emit_signal(connection, ptr, @@ -2097,8 +2088,10 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status, device->path, DEVICE_INTERFACE, "Connected", DBUS_TYPE_BOOLEAN, &connected); - if (device->temporary) + if (device->temporary) { + debug("Removing temporary device %s", device->address); adapter_remove_device(connection, adapter, device); + } } } @@ -2396,7 +2389,7 @@ void hcid_dbus_pin_code_reply(bdaddr_t *local, void *ptr) l = g_slist_find_custom(adapter->pin_reqs, &ret->bdaddr, pin_req_cmp); if (l) { - struct pending_pin_info *p = l->data; + struct pending_auth_info *p = l->data; p->replied = 1; } } diff --git a/hcid/dbus-hci.h b/hcid/dbus-hci.h index 167780b4..31c13199 100644 --- a/hcid/dbus-hci.h +++ b/hcid/dbus-hci.h @@ -28,9 +28,8 @@ int hcid_dbus_register_device(uint16_t id); int hcid_dbus_unregister_device(uint16_t id); int hcid_dbus_start_device(uint16_t id); int hcid_dbus_stop_device(uint16_t id); -void hcid_dbus_pending_pin_req_add(bdaddr_t *sba, bdaddr_t *dba); +void hcid_dbus_new_auth_request(bdaddr_t *sba, bdaddr_t *dba, auth_type_t type); int hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci); -int hcid_dbus_confirm_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci, char *pin); void hcid_dbus_inquiry_start(bdaddr_t *local); void hcid_dbus_inquiry_complete(bdaddr_t *local); diff --git a/hcid/dbus-security.c b/hcid/dbus-security.c index dfa2c711..840efca6 100644 --- a/hcid/dbus-security.c +++ b/hcid/dbus-security.c @@ -1022,176 +1022,6 @@ int handle_passkey_request_old(DBusConnection *conn, int dev, return call_passkey_agent(conn, agent, dev, adapter->path, sba, dba); } -static DBusPendingCall *agent_confirm(const char *path, bdaddr_t *bda, - struct passkey_agent *agent, - const char *value) -{ - DBusMessage *message; - DBusPendingCall *call; - char bda_str[18], *ptr = bda_str; - - message = dbus_message_new_method_call(agent->name, agent->path, - "org.bluez.PasskeyAgent", "Confirm"); - if (message == NULL) { - error("Couldn't allocate D-Bus message"); - return NULL; - } - - ba2str(bda, bda_str); - - dbus_message_append_args(message, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_STRING, &ptr, - DBUS_TYPE_STRING, &value, - DBUS_TYPE_INVALID); - - if (dbus_connection_send_with_reply(agent->conn, message, - &call, REQUEST_TIMEOUT) == FALSE) { - error("D-Bus send failed"); - dbus_message_unref(message); - return NULL; - } - - dbus_message_unref(message); - return call; -} - -static void confirm_agent_reply(DBusPendingCall *call, void *user_data) -{ - struct pending_agent_request *req = user_data; - struct passkey_agent *agent = req->agent; - pin_code_reply_cp pr; - DBusMessage *message; - DBusError err; - int len; - - /* steal_reply will always return non-NULL since the callback - * is only called after a reply has been received */ - message = dbus_pending_call_steal_reply(call); - - dbus_error_init(&err); - if (dbus_set_error_from_message(&err, message)) { - - error("Passkey agent replied with an error: %s, %s", - err.name, err.message); - - dbus_error_free(&err); - goto fail; - } - - dbus_error_init(&err); - if (!dbus_message_get_args(message, &err, DBUS_TYPE_INVALID)) { - error("Wrong confirm reply signature: %s", err.message); - dbus_error_free(&err); - goto fail; - } - - len = strlen(req->pin); - - set_pin_length(&req->sba, len); - - memset(&pr, 0, sizeof(pr)); - bacpy(&pr.bdaddr, &req->bda); - memcpy(pr.pin_code, req->pin, len); - pr.pin_len = len; - hci_send_cmd(req->dev, OGF_LINK_CTL, - OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); - - goto done; - -fail: - hci_send_cmd(req->dev, OGF_LINK_CTL, - OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); - -done: - if (message) - dbus_message_unref(message); - - agent->pending_requests = g_slist_remove(agent->pending_requests, req); - dbus_pending_call_cancel(req->call); - if (req->call) - dbus_pending_call_unref(req->call); - g_free(req->pin); - g_free(req->path); - g_free(req); - - if (agent != default_agent) { - agent->adapter->passkey_agents = g_slist_remove(agent->adapter->passkey_agents, - agent); - passkey_agent_free(agent); - } -} - -static int call_confirm_agent(DBusConnection *conn, - struct passkey_agent *agent, int dev, - const char *path, bdaddr_t *sba, - bdaddr_t *dba, const char *pin) -{ - struct pending_agent_request *req; - - if (!agent) { - debug("call_passkey_agent(): no agent available"); - goto send; - } - - debug("Calling PasskeyAgent.Confirm: name=%s, path=%s", - agent->name, agent->path); - - req = g_new0(struct pending_agent_request, 1); - req->dev = dev; - bacpy(&req->sba, sba); - bacpy(&req->bda, dba); - req->agent = agent; - req->path = g_strdup(path); - req->pin = g_strdup(pin); - - req->call = agent_confirm(path, dba, agent, pin); - if (!req->call) - goto failed; - - dbus_pending_call_set_notify(req->call, confirm_agent_reply, req, NULL); - - agent->pending_requests = g_slist_append(agent->pending_requests, req); - - return 0; - -failed: - g_free(req->pin); - g_free(req->path); - g_free(req); - -send: - hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); - - return -1; -} - -int handle_confirm_request_old(DBusConnection *conn, int dev, - struct adapter *adapter, - bdaddr_t *sba, bdaddr_t *dba, - const char *pin) -{ - struct passkey_agent *agent = default_agent; - GSList *l; - char addr[18]; - - ba2str(dba, addr); - - for (l = adapter->passkey_agents; l != NULL; l = l->next) { - struct passkey_agent *a = l->data; - if (a != default_agent && - g_slist_length(a->pending_requests) >= 1) - continue; - if (!strcmp(a->addr, addr)) { - agent = a; - break; - } - } - - return call_confirm_agent(conn, agent, dev, adapter->path, - sba, dba, pin); -} - static void send_cancel_request(struct pending_agent_request *req) { DBusMessage *message; diff --git a/hcid/security.c b/hcid/security.c index 0df255ab..1a711e18 100644 --- a/hcid/security.c +++ b/hcid/security.c @@ -365,6 +365,8 @@ static void user_confirm_request(int dev, bdaddr_t *sba, void *ptr) if (hcid_dbus_user_confirm(sba, &req->bdaddr, req->passkey) < 0) hci_send_cmd(dev, OGF_LINK_CTL, OCF_USER_CONFIRM_NEG_REPLY, 6, ptr); + else + hcid_dbus_new_auth_request(sba, &req->bdaddr, AUTH_TYPE_CONFIRM); } static void user_passkey_request(int dev, bdaddr_t *sba, void *ptr) @@ -374,6 +376,8 @@ static void user_passkey_request(int dev, bdaddr_t *sba, void *ptr) if (hcid_dbus_user_passkey(sba, &req->bdaddr) < 0) hci_send_cmd(dev, OGF_LINK_CTL, OCF_USER_PASSKEY_NEG_REPLY, 6, ptr); + else + hcid_dbus_new_auth_request(sba, &req->bdaddr, AUTH_TYPE_PASSKEY); } static void remote_oob_data_request(int dev, bdaddr_t *sba, void *ptr) @@ -459,39 +463,27 @@ static void pin_code_request(int dev, bdaddr_t *sba, bdaddr_t *dba) } else if (pairing == HCID_PAIRING_NONE) goto reject; - if (hcid.security == HCID_SEC_AUTO) { - if (!ci->out) { - /* Incomming connection */ - set_pin_length(sba, hcid.pin_len); - memcpy(pr.pin_code, hcid.pin_code, hcid.pin_len); - pr.pin_len = hcid.pin_len; - hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, + if (hcid.security == HCID_SEC_AUTO && !ci->out) { + set_pin_length(sba, hcid.pin_len); + memcpy(pr.pin_code, hcid.pin_code, hcid.pin_len); + pr.pin_len = hcid.pin_len; + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, PIN_CODE_REPLY_CP_SIZE, &pr); - } else { - /* Outgoing connection */ - if (pinlen > 0) { - set_pin_length(sba, pinlen); - memcpy(pr.pin_code, pin, pinlen); - pr.pin_len = pinlen; - hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, - PIN_CODE_REPLY_CP_SIZE, &pr); - } else { - /* Request PIN from passkey agent */ - hcid_dbus_request_pin(dev, sba, ci); - } - } } else { if (pinlen > 0) { - /* Confirm PIN by passkey agent */ - hcid_dbus_confirm_pin(dev, sba, ci, pin); + set_pin_length(sba, pinlen); + memcpy(pr.pin_code, pin, pinlen); + pr.pin_len = pinlen; + hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_REPLY, + PIN_CODE_REPLY_CP_SIZE, &pr); } else { - /* Request PIN from passkey agent */ - hcid_dbus_request_pin(dev, sba, ci); + /* Request PIN from passkey agent */ + if (hcid_dbus_request_pin(dev, sba, ci) < 0) + goto reject; + hcid_dbus_new_auth_request(sba, dba, AUTH_TYPE_PINCODE); } } - hcid_dbus_pending_pin_req_add(sba, &ci->bdaddr); - g_free(cr); return; @@ -500,8 +492,6 @@ reject: g_free(cr); hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); - - return; } static inline void cmd_status(int dev, bdaddr_t *sba, void *ptr) |