diff options
author | Luiz Augusto von Dentz <luiz.dentz@indt.org.br> | 2008-07-10 18:35:04 -0300 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.dentz@indt.org.br> | 2008-07-28 10:31:32 -0300 |
commit | f0e152e16102de80b7fe8510f455f993980ebb2f (patch) | |
tree | c6f682bce1d381f50414533e551fc3351e817de1 /hcid/dbus-security.c | |
parent | 34f8a76bd5bd24ae1a1594f4d1460df393675ec1 (diff) |
Remove deprecated object paths and files.
Diffstat (limited to 'hcid/dbus-security.c')
-rw-r--r-- | hcid/dbus-security.c | 1113 |
1 files changed, 0 insertions, 1113 deletions
diff --git a/hcid/dbus-security.c b/hcid/dbus-security.c deleted file mode 100644 index e84174bb..00000000 --- a/hcid/dbus-security.c +++ /dev/null @@ -1,1113 +0,0 @@ -/* - * - * BlueZ - Bluetooth protocol stack for Linux - * - * Copyright (C) 2006-2007 Nokia Corporation - * Copyright (C) 2004-2008 Marcel Holtmann <marcel@holtmann.org> - * Copyright (C) 2005-2007 Johan Hedberg <johan.hedberg@nokia.com> - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <limits.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/ioctl.h> - -#include <bluetooth/bluetooth.h> -#include <bluetooth/hci.h> -#include <bluetooth/hci_lib.h> -#include <bluetooth/sdp.h> - -#include <glib.h> -#include <dbus/dbus.h> -#include <gdbus.h> - -#include "adapter.h" -#include "manager.h" -#include "hcid.h" -#include "dbus-common.h" -#include "dbus-service.h" -#include "error.h" -#include "dbus-security.h" -#include "dbus-hci.h" - -#define REQUEST_TIMEOUT (60 * 1000) /* 60 seconds */ -#define AGENT_TIMEOUT (10 * 60 * 1000) /* 10 minutes */ - -struct passkey_agent { - struct adapter *adapter; - DBusConnection *conn; - char *addr; - char *name; - char *path; - GSList *pending_requests; - int exited; - guint timeout; - guint listener_id; -}; - -struct pending_agent_request { - struct passkey_agent *agent; - int dev; - bdaddr_t sba; - bdaddr_t bda; - char *path; - DBusPendingCall *call; - int old_if; - char *pin; -}; - -struct authorization_agent { - DBusConnection *conn; - char *name; - char *path; - GSList *pending_requests; - guint listener_id; -}; - -struct auth_agent_req { - struct authorization_agent *agent; - char *adapter_path; - char *address; - char *service_path; - char *uuid; - service_auth_cb cb; - void *user_data; - DBusPendingCall *call; -}; - -static struct passkey_agent *default_agent = NULL; -static struct authorization_agent *default_auth_agent = NULL; - -static void release_agent(struct passkey_agent *agent); -static void send_cancel_request(struct pending_agent_request *req); - -static void passkey_agent_free(struct passkey_agent *agent) -{ - GSList *l; - - if (!agent) - return; - - for (l = agent->pending_requests; l != NULL; l = l->next) { - struct pending_agent_request *req = l->data; - struct adapter *adapter = manager_find_adapter(&req->sba); - - hci_send_cmd(req->dev, OGF_LINK_CTL, - OCF_PIN_CODE_NEG_REPLY, 6, &req->bda); - - if (adapter) - adapter_auth_request_replied(adapter, &req->bda); - - send_cancel_request(req); - } - - if (agent->timeout) - g_source_remove(agent->timeout); - - if (!agent->exited) - release_agent(agent); - - g_free(agent->name); - g_free(agent->path); - g_free(agent->addr); - - if (agent->conn) - dbus_connection_unref(agent->conn); - - g_slist_free(agent->pending_requests); - - g_free(agent); -} - -static void agent_exited(void *user_data) -{ - struct passkey_agent *agent = user_data; - struct adapter *adapter = agent->adapter; - - debug("Passkey agent exited without calling Unregister"); - - agent->exited = 1; - - adapter->passkey_agents = g_slist_remove(adapter->passkey_agents, agent); - passkey_agent_free(agent); -} - -static gboolean agent_timeout(struct passkey_agent *agent) -{ - struct adapter *adapter = agent->adapter; - - debug("Passkey Agent at %s, %s timed out", agent->name, agent->path); - - if (adapter) - adapter->passkey_agents = g_slist_remove(adapter->passkey_agents, agent); - - agent->timeout = 0; - - passkey_agent_free(agent); - - return FALSE; -} - -static void default_agent_exited(void *data) -{ - debug("D-Bus client exited without unregistering the" - " default passkey agent"); - - default_agent->exited = 1; - - passkey_agent_free(default_agent); - default_agent = NULL; -} - -static struct passkey_agent *passkey_agent_new(struct adapter *adapter, DBusConnection *conn, - const char *name, const char *path, - const char *addr) -{ - struct passkey_agent *agent; - - agent = g_new0(struct passkey_agent, 1); - - agent->adapter = adapter; - - agent->name = g_strdup(name); - agent->path = g_strdup(path); - - if (addr) - agent->addr = g_strdup(addr); - - agent->conn = dbus_connection_ref(conn); - - return agent; -} - -static int agent_cmp(const struct passkey_agent *a, const struct passkey_agent *b) -{ - int ret; - - if (b->name) { - if (!a->name) - return -1; - ret = strcmp(a->name, b->name); - if (ret) - return ret; - } - - if (b->path) { - if (!a->path) - return -1; - ret = strcmp(a->path, b->path); - if (ret) - return ret; - } - - if (b->addr) { - if (!a->addr) - return -1; - ret = strcmp(a->addr, b->addr); - if (ret) - return ret; - } - - return 0; -} - -static inline DBusMessage *invalid_args(DBusMessage *msg) -{ - return g_dbus_create_error(msg, ERROR_INTERFACE ".InvalidArguments", - "Invalid arguments in method call"); -} - -static DBusMessage *register_passkey_agent(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - struct passkey_agent *agent, ref; - struct adapter *adapter; - const char *path, *addr; - - if (!data) { - error("register_passkey_agent called without any adapter info!"); - return NULL; - } - - adapter = data; - - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_STRING, &addr, - DBUS_TYPE_INVALID)) - return invalid_args(msg); - - if ((check_address(addr) < 0) || (path[0] != '/')) - return invalid_args(msg); - - memset(&ref, 0, sizeof(ref)); - - ref.name = (char *) dbus_message_get_sender(msg); - ref.addr = (char *) addr; - ref.path = (char *) path; - - if (g_slist_find_custom(adapter->passkey_agents, &ref, (GCompareFunc) agent_cmp)) - return g_dbus_create_error(msg, - ERROR_INTERFACE ".AlreadyExists", - "Passkey agent already exists"); - - agent = passkey_agent_new(adapter, conn, ref.name, path, addr); - if (!agent) - return NULL; - - /* Only add a name listener if there isn't one already for this name */ - ref.addr = NULL; - ref.path = NULL; - if (!g_slist_find_custom(adapter->passkey_agents, &ref, - (GCompareFunc) agent_cmp)) - agent->listener_id = g_dbus_add_disconnect_watch(conn, ref.name, - agent_exited, agent, NULL); - - agent->timeout = g_timeout_add(AGENT_TIMEOUT, - (GSourceFunc) agent_timeout, agent); - - adapter->passkey_agents = g_slist_append(adapter->passkey_agents, agent); - - return dbus_message_new_method_return(msg); -} - -static DBusMessage *unregister_passkey_agent(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - struct adapter *adapter; - GSList *match; - struct passkey_agent ref, *agent; - const char *path, *addr; - - if (!data) { - error("unregister_passkey_agent called without any adapter info!"); - return NULL; - } - - adapter = data; - - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_STRING, &addr, - DBUS_TYPE_INVALID)) - return invalid_args(msg); - - memset(&ref, 0, sizeof(ref)); - - ref.name = (char *) dbus_message_get_sender(msg); - ref.path = (char *) path; - ref.addr = (char *) addr; - - match = g_slist_find_custom(adapter->passkey_agents, &ref, (GCompareFunc) agent_cmp); - if (!match) - return g_dbus_create_error(msg, - ERROR_INTERFACE ".DoesNotExist", - "Passkey agent does not exist"); - - agent = match->data; - - g_dbus_remove_watch(agent->conn, agent->listener_id); - - adapter->passkey_agents = g_slist_remove(adapter->passkey_agents, agent); - agent->exited = 1; - passkey_agent_free(agent); - - return dbus_message_new_method_return(msg); -} - -static DBusMessage *register_default_passkey_agent(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - const char *path; - - if (default_agent) - return g_dbus_create_error(msg, - ERROR_INTERFACE ".AlreadyExists", - "Passkey agent already exists"); - - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID)) - return invalid_args(msg); - - default_agent = passkey_agent_new(NULL, conn, dbus_message_get_sender(msg), - path, NULL); - if (!default_agent) - goto need_memory; - - default_agent->listener_id = g_dbus_add_disconnect_watch(conn, - default_agent->name, - default_agent_exited, - NULL, NULL); - - info("Default passkey agent (%s, %s) registered", - default_agent->name, default_agent->path); - - return dbus_message_new_method_return(msg); - -need_memory: - if (default_agent) { - default_agent->exited = 1; - passkey_agent_free(default_agent); - default_agent = NULL; - } - - return NULL; -} - -static DBusMessage *unregister_default_passkey_agent(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - const char *path, *name; - - if (!default_agent) - return g_dbus_create_error(msg, - ERROR_INTERFACE ".DoesNotExist", - "Passkey agent does not exist"); - - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID)) - return invalid_args(msg); - - name = dbus_message_get_sender(msg); - - if (strcmp(name, default_agent->name) || strcmp(path, default_agent->path)) - return g_dbus_create_error(msg, - ERROR_INTERFACE ".DoesNotExist", - "Passkey agent does not exist"); - - g_dbus_remove_watch(default_agent->conn, default_agent->listener_id); - - info("Default passkey agent (%s, %s) unregistered", - default_agent->name, default_agent->path); - - default_agent->exited = 1; - passkey_agent_free(default_agent); - default_agent = NULL; - - return dbus_message_new_method_return(msg); -} - -static struct auth_agent_req *auth_agent_req_new(struct authorization_agent *agent, - const char *adapter_path, - const char *address, - const char *service_path, - const char *uuid, - service_auth_cb cb, - void *user_data) -{ - struct auth_agent_req *req; - - req = g_new0(struct auth_agent_req, 1); - - req->agent = agent; - req->adapter_path = g_strdup(adapter_path); - req->address = g_strdup(address); - req->service_path = g_strdup(service_path); - req->uuid = g_strdup(uuid); - req->cb = cb; - req->user_data = user_data; - - return req; -} - -static void auth_agent_req_free(struct auth_agent_req *req) -{ - g_free(req->adapter_path); - g_free(req->address); - g_free(req->service_path); - g_free(req->uuid); - if (req->call) - dbus_pending_call_unref(req->call); - g_free(req); -} - -static void auth_agent_req_cancel(struct auth_agent_req *req) -{ - dbus_pending_call_cancel(req->call); -} - -static void auth_agent_cancel_requests(struct authorization_agent *agent) -{ - GSList *l; - - for (l = agent->pending_requests; l != NULL; l = l->next) { - struct auth_agent_req *req = l->data; - auth_agent_req_cancel(req); - auth_agent_req_free(req); - } -} - -static void auth_agent_call_cancel(struct auth_agent_req *req) -{ - struct authorization_agent *agent = req->agent; - DBusMessage *message; - - message = dbus_message_new_method_call(agent->name, agent->path, - "org.bluez.AuthorizationAgent", "Cancel"); - if (!message) { - error("Couldn't allocate D-Bus message"); - return; - } - - dbus_message_append_args(message, - DBUS_TYPE_STRING, &req->adapter_path, - DBUS_TYPE_STRING, &req->address, - DBUS_TYPE_STRING, &req->service_path, - DBUS_TYPE_STRING, &req->uuid, - DBUS_TYPE_INVALID); - - dbus_message_set_no_reply(message, TRUE); - - dbus_connection_send(agent->conn, message, NULL); - - dbus_message_unref(message); -} - -static void auth_agent_free(struct authorization_agent *agent) -{ - g_free(agent->name); - g_free(agent->path); - dbus_connection_unref(agent->conn); - g_slist_free(agent->pending_requests); - g_free(agent); -} - -static struct authorization_agent *auth_agent_new(DBusConnection *conn, - const char *name, - const char *path) -{ - struct authorization_agent *agent; - - agent = g_new0(struct authorization_agent, 1); - - agent->name = g_strdup(name); - agent->path = g_strdup(path); - - agent->conn = dbus_connection_ref(conn); - - return agent; -} - -static void default_auth_agent_exited(void *data) -{ - debug("D-Bus client exited without unregistering the " - "default authorization agent"); - - auth_agent_cancel_requests(default_auth_agent); - auth_agent_free(default_auth_agent); - default_auth_agent = NULL; -} - -static void auth_agent_release(struct authorization_agent *agent) -{ - DBusMessage *message; - - debug("Releasing authorization agent %s, %s", - agent->name, agent->path); - - message = dbus_message_new_method_call(agent->name, agent->path, - "org.bluez.AuthorizationAgent", "Release"); - if (!message) { - error("Couldn't allocate D-Bus message"); - return; - } - - dbus_message_set_no_reply(message, TRUE); - - dbus_connection_send(agent->conn, message, NULL); - - dbus_message_unref(message); - - if (agent == default_auth_agent) - g_dbus_remove_watch(agent->conn, agent->listener_id); -} - -static DBusMessage *register_default_auth_agent(DBusConnection *conn, - DBusMessage *msg, - void *data) -{ - const char *path; - - if (default_auth_agent) - return g_dbus_create_error(msg, - ERROR_INTERFACE ".AlreadyExists", - "Authorization agent already exists"); - - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID)) - return invalid_args(msg); - - default_auth_agent = auth_agent_new(conn, - dbus_message_get_sender(msg), path); - if (!default_auth_agent) - goto need_memory; - - default_auth_agent->listener_id = g_dbus_add_disconnect_watch(conn, - default_auth_agent->name, - default_auth_agent_exited, - NULL, NULL); - - info("Default authorization agent (%s, %s) registered", - default_auth_agent->name, default_auth_agent->path); - - return dbus_message_new_method_return(msg); - -need_memory: - if (default_auth_agent) { - auth_agent_free(default_auth_agent); - default_auth_agent = NULL; - } - - return NULL; -} - -static DBusMessage *unregister_default_auth_agent(DBusConnection *conn, - DBusMessage *msg, - void *data) -{ - const char *path, *name; - - if (!default_auth_agent) - return g_dbus_create_error(msg, - ERROR_INTERFACE ".DoesNotExist", - "Authorization agent does not exist"); - - if (!dbus_message_get_args(msg, NULL, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_INVALID)) - return invalid_args(msg); - - name = dbus_message_get_sender(msg); - - if (strcmp(name, default_auth_agent->name) || - strcmp(path, default_auth_agent->path)) - return g_dbus_create_error(msg, - ERROR_INTERFACE ".DoesNotExist", - "Authorization agent does not exist"); - - g_dbus_remove_watch(default_auth_agent->conn, - default_auth_agent->listener_id); - - info("Default authorization agent (%s, %s) unregistered", - default_auth_agent->name, default_auth_agent->path); - - auth_agent_cancel_requests(default_auth_agent); - auth_agent_free(default_auth_agent); - default_auth_agent = NULL; - - return dbus_message_new_method_return(msg); -} - -static void auth_agent_req_reply(DBusPendingCall *call, void *data) -{ - struct auth_agent_req *req = data; - DBusMessage *reply = dbus_pending_call_steal_reply(call); - DBusError err; - - debug("authorize reply"); - - dbus_error_init(&err); - dbus_set_error_from_message(&err, reply); - req->cb(&err, req->user_data); - - default_auth_agent->pending_requests = - g_slist_remove(default_auth_agent->pending_requests, req); - auth_agent_req_free(req); - - debug("auth_agent_reply: returning"); -} - -static DBusPendingCall *auth_agent_call_authorize(struct authorization_agent *agent, - const char *adapter_path, - const char *service_path, - const char *address, - const char *uuid) -{ - DBusMessage *message; - DBusPendingCall *call; - - message = dbus_message_new_method_call(agent->name, agent->path, - "org.bluez.AuthorizationAgent", "Authorize"); - if (!message) { - error("Couldn't allocate D-Bus message"); - return NULL; - } - - dbus_message_append_args(message, - DBUS_TYPE_STRING, &adapter_path, - DBUS_TYPE_STRING, &address, - DBUS_TYPE_STRING, &service_path, - DBUS_TYPE_STRING, &uuid, - 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; -} - -int handle_authorize_request_old(struct service *service, const char *path, - const char *address, const char *uuid, - service_auth_cb cb, void *user_data) -{ - struct auth_agent_req *req; - - if (!default_auth_agent) { - debug("no default agent"); - return -EPERM; - } - - req = auth_agent_req_new(default_auth_agent, path, - address, service->object_path, - uuid, cb, user_data); - - req->call = auth_agent_call_authorize(default_auth_agent, path, - service->object_path, address, uuid); - if (!req->call) { - auth_agent_req_free(req); - return -ENOMEM; - } - - dbus_pending_call_set_notify(req->call, auth_agent_req_reply, req, - NULL); - default_auth_agent->pending_requests = - g_slist_append(default_auth_agent->pending_requests, req); - - debug("authorize request was forwarded"); - - return 0; -} - -static int auth_agent_send_cancel(struct authorization_agent *agent, - const char *adapter_path, - const char *address) -{ - struct auth_agent_req *req = NULL; - GSList *l; - - for (l = agent->pending_requests; l != NULL; l = l->next) { - req = l->data; - if (!strcmp(adapter_path, req->adapter_path) && - !strcmp(address, req->address)) - break; - } - - if (!req) - return -EIO; - - auth_agent_call_cancel(req); - auth_agent_req_cancel(req); - agent->pending_requests = g_slist_remove(agent->pending_requests, req); - auth_agent_req_free(req); - - return 0; -} - -int cancel_authorize_request_old(const char *path, const char *address) -{ - if (!default_auth_agent) - return -EIO; - - return auth_agent_send_cancel(default_auth_agent, path, address); -} - -static GDBusMethodTable security_methods[] = { - { "RegisterDefaultPasskeyAgent", "s", "", - register_default_passkey_agent }, - { "UnregisterDefaultPasskeyAgent", "s", "", - unregister_default_passkey_agent}, - { "RegisterPasskeyAgent", "ss", "", - register_passkey_agent }, - { "UnregisterPasskeyAgent", "ss", "", - unregister_passkey_agent }, - { "RegisterDefaultAuthorizationAgent", "s", "", - register_default_auth_agent }, - { "UnregisterDefaultAuthorizationAgent","s", "", - unregister_default_auth_agent }, - { } -}; - -dbus_bool_t security_init(DBusConnection *conn, const char *path) -{ - return g_dbus_register_interface(conn, path, SECURITY_INTERFACE, - security_methods, NULL, NULL, NULL, NULL); -} - -dbus_bool_t security_cleanup(DBusConnection *conn, const char *path) -{ - return g_dbus_unregister_interface(conn, path, SECURITY_INTERFACE); -} - -static DBusPendingCall *agent_request(const char *path, bdaddr_t *bda, - struct passkey_agent *agent, - dbus_bool_t numeric, int old_if) -{ - DBusMessage *message; - DBusPendingCall *call; - char bda_str[18], *ptr = bda_str; - - message = dbus_message_new_method_call(agent->name, agent->path, - "org.bluez.PasskeyAgent", "Request"); - if (message == NULL) { - error("Couldn't allocate D-Bus message"); - return NULL; - } - - ba2str(bda, bda_str); - - if (old_if) - dbus_message_append_args(message, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_STRING, &ptr, - DBUS_TYPE_INVALID); - else - dbus_message_append_args(message, - DBUS_TYPE_STRING, &path, - DBUS_TYPE_STRING, &ptr, - DBUS_TYPE_BOOLEAN, &numeric, - 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 passkey_agent_reply(DBusPendingCall *call, void *user_data) -{ - struct pending_agent_request *req = user_data; - struct passkey_agent *agent = req->agent; - struct adapter *adapter = manager_find_adapter(&req->sba); - pin_code_reply_cp pr; - DBusMessage *message; - DBusError err; - size_t len; - char *pin; - - /* 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)) { - if (!req->old_if && !strcmp(err.name, DBUS_ERROR_UNKNOWN_METHOD)) { - debug("New Request API failed, trying old one"); - req->old_if = 1; - dbus_error_free(&err); - dbus_pending_call_unref(req->call); - req->call = agent_request(req->path, &req->bda, agent, - FALSE, 1); - if (!req->call) - goto fail; - - dbus_message_unref(message); - - dbus_pending_call_set_notify(req->call, - passkey_agent_reply, - req, NULL); - return; - } - - 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_STRING, &pin, - DBUS_TYPE_INVALID)) { - error("Wrong passkey reply signature: %s", err.message); - dbus_error_free(&err); - goto fail; - } - - len = strlen(pin); - - if (len > 16 || len < 1) { - error("Invalid passkey length from handler"); - goto fail; - } - - set_pin_length(&req->sba, len); - - memset(&pr, 0, sizeof(pr)); - bacpy(&pr.bdaddr, &req->bda); - memcpy(pr.pin_code, 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 (adapter) - adapter_auth_request_replied(adapter, &req->bda); - - 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->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_passkey_agent(DBusConnection *conn, - struct passkey_agent *agent, int dev, - const char *path, bdaddr_t *sba, - bdaddr_t *dba) -{ - struct pending_agent_request *req; - struct adapter *adapter = manager_find_adapter(sba); - - if (!agent) { - debug("call_passkey_agent(): no agent available"); - goto send; - } - - debug("Calling PasskeyAgent.Request: 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->call = agent_request(path, dba, agent, FALSE, 0); - if (!req->call) - goto failed; - - dbus_pending_call_set_notify(req->call, passkey_agent_reply, req, NULL); - - agent->pending_requests = g_slist_append(agent->pending_requests, req); - - return 0; - -failed: - g_free(req->path); - g_free(req); - -send: - hci_send_cmd(dev, OGF_LINK_CTL, OCF_PIN_CODE_NEG_REPLY, 6, dba); - - if (adapter) - adapter_auth_request_replied(adapter, dba); - - return -1; -} - -int handle_passkey_request_old(DBusConnection *conn, int dev, - struct adapter *adapter, - bdaddr_t *sba, bdaddr_t *dba) -{ - 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_passkey_agent(conn, agent, dev, adapter->path, sba, dba); -} - -static void send_cancel_request(struct pending_agent_request *req) -{ - DBusMessage *message; - char address[18], *ptr = address; - - message = dbus_message_new_method_call(req->agent->name, req->agent->path, - "org.bluez.PasskeyAgent", "Cancel"); - if (message == NULL) { - error("Couldn't allocate D-Bus message"); - return; - } - - ba2str(&req->bda, address); - - dbus_message_append_args(message, - DBUS_TYPE_STRING, &req->path, - DBUS_TYPE_STRING, &ptr, - DBUS_TYPE_INVALID); - - dbus_message_set_no_reply(message, TRUE); - - dbus_connection_send(req->agent->conn, message, NULL); - - dbus_message_unref(message); - - debug("PasskeyAgent.Request(%s, %s) was canceled", req->path, address); - - dbus_pending_call_cancel(req->call); - dbus_pending_call_unref(req->call); - g_free(req->pin); - g_free(req->path); - g_free(req); -} - -static void release_agent(struct passkey_agent *agent) -{ - DBusMessage *message; - - debug("Releasing agent %s, %s", agent->name, agent->path); - - message = dbus_message_new_method_call(agent->name, agent->path, - "org.bluez.PasskeyAgent", "Release"); - if (message == NULL) { - error("Couldn't allocate D-Bus message"); - return; - } - - dbus_message_set_no_reply(message, TRUE); - - dbus_connection_send(agent->conn, message, NULL); - - dbus_message_unref(message); - - if (agent == default_agent) - g_dbus_remove_watch(agent->conn, agent->listener_id); - else { - struct passkey_agent ref; - - /* Only remove the name listener if there are no more agents - * for this name */ - memset(&ref, 0, sizeof(ref)); - ref.name = agent->name; - if (!g_slist_find_custom(agent->adapter->passkey_agents, &ref, - (GCompareFunc) agent_cmp)) - g_dbus_remove_watch(agent->conn, agent->listener_id); - } -} - -void release_default_agent_old(void) -{ - if (!default_agent) - return; - - passkey_agent_free(default_agent); - default_agent = NULL; -} - -void release_default_auth_agent(void) -{ - if (!default_auth_agent) - return; - - auth_agent_cancel_requests(default_auth_agent); - auth_agent_release(default_auth_agent); - - auth_agent_free(default_auth_agent); - default_auth_agent = NULL; -} - -void release_passkey_agents(struct adapter *adapter, bdaddr_t *bda) -{ - GSList *l, *next; - - for (l = adapter->passkey_agents; l != NULL; l = next) { - struct passkey_agent *agent = l->data; - next = l->next; - - if (bda && agent->addr) { - bdaddr_t tmp; - str2ba(agent->addr, &tmp); - if (bacmp(&tmp, bda)) - continue; - } - - adapter->passkey_agents = g_slist_remove(adapter->passkey_agents, agent); - passkey_agent_free(agent); - } -} - -void cancel_passkey_agent_requests(GSList *agents, const char *path, - bdaddr_t *addr) -{ - GSList *l, *next; - - /* First check the default agent */ - for (l = default_agent ? default_agent->pending_requests : NULL; l != NULL; l = next) { - struct pending_agent_request *req = l->data; - next = l->next; - if (!strcmp(path, req->path) && (!addr || !bacmp(addr, &req->bda))) { - send_cancel_request(req); - default_agent->pending_requests = g_slist_remove(default_agent->pending_requests, - req); - } - } - - /* and then the adapter specific agents */ - for (; agents != NULL; agents = agents->next) { - struct passkey_agent *agent = agents->data; - - for (l = agent->pending_requests; l != NULL; l = next) { - struct pending_agent_request *req = l->data; - next = l->next; - if (!strcmp(path, req->path) && (!addr || !bacmp(addr, &req->bda))) { - send_cancel_request(req); - agent->pending_requests = g_slist_remove(agent->pending_requests, req); - } - } - } -} |