diff options
| -rw-r--r-- | hcid/Makefile.am | 3 | ||||
| -rw-r--r-- | hcid/adapter.c | 6 | ||||
| -rw-r--r-- | hcid/agent.c | 1 | ||||
| -rw-r--r-- | hcid/dbus-common.c | 8 | ||||
| -rw-r--r-- | hcid/dbus-database.c | 2 | ||||
| -rw-r--r-- | hcid/dbus-hci.c | 43 | ||||
| -rw-r--r-- | hcid/dbus-security.c | 1113 | ||||
| -rw-r--r-- | hcid/dbus-security.h | 50 | ||||
| -rw-r--r-- | hcid/dbus-service.c | 578 | ||||
| -rw-r--r-- | hcid/dbus-service.h | 19 | ||||
| -rw-r--r-- | hcid/device.c | 6 | ||||
| -rw-r--r-- | hcid/main.c | 1 | ||||
| -rw-r--r-- | hcid/manager.c | 2 | 
13 files changed, 7 insertions, 1825 deletions
diff --git a/hcid/Makefile.am b/hcid/Makefile.am index 763374f1..d24c06af 100644 --- a/hcid/Makefile.am +++ b/hcid/Makefile.am @@ -20,8 +20,7 @@ libhciserver_a_SOURCES = hcid.h security.c storage.c \  	server.h server.c manager.h manager.c \  	adapter.h adapter.c device.h device.c plugin.h plugin.c \  	dbus-common.c dbus-common.h dbus-error.c dbus-error.h \ -	dbus-database.c dbus-database.h dbus-security.c dbus-security.h \ -	dbus-service.c dbus-service.h \ +	dbus-database.c dbus-database.h dbus-service.c dbus-service.h \  	dbus-hci.h dbus-hci.c dbus-sdp.c dbus-sdp.h \  	telephony.h telephony.c agent.h agent.c diff --git a/hcid/adapter.c b/hcid/adapter.c index e08ab300..5a9ad77e 100644 --- a/hcid/adapter.c +++ b/hcid/adapter.c @@ -59,8 +59,6 @@  #include "dbus-hci.h"  #include "dbus-sdp.h"  #include "dbus-database.h" -#include "dbus-service.h" -#include "dbus-security.h"  #include "dbus-error.h"  #include "error.h"  #include "glib-helper.h" @@ -1144,10 +1142,6 @@ static void create_bond_req_exit(void *user_data)  	debug("CreateConnection requestor exited before bonding was completed"); -	cancel_passkey_agent_requests(adapter->passkey_agents, path, -					&adapter->bonding->bdaddr); -	release_passkey_agents(adapter, &adapter->bonding->bdaddr); -  	auth = adapter_find_auth_request(adapter, &adapter->bonding->bdaddr);  	if (auth) {  		cancel_auth_request(auth, adapter->dev_id); diff --git a/hcid/agent.c b/hcid/agent.c index 91dbd2d9..8fa7c502 100644 --- a/hcid/agent.c +++ b/hcid/agent.c @@ -43,7 +43,6 @@  #include "hcid.h"  #include "dbus-common.h" -#include "dbus-service.h"  #include "dbus-error.h"  #include "error.h"  #include "adapter.h" diff --git a/hcid/dbus-common.c b/hcid/dbus-common.c index 46670e9c..eae6d3c5 100644 --- a/hcid/dbus-common.c +++ b/hcid/dbus-common.c @@ -48,9 +48,7 @@  #include "manager.h"  #include "adapter.h"  #include "dbus-hci.h" -#include "dbus-service.h"  #include "dbus-database.h" -#include "dbus-security.h"  #include "dbus-sdp.h"  #include "dbus-common.h" @@ -177,8 +175,6 @@ static void disconnect_callback(void *user_data)  {  	set_dbus_connection(NULL); -	release_services(NULL); -  	g_timeout_add(RECONNECT_RETRY_TIMEOUT,  				system_bus_reconnect, NULL);  } @@ -217,10 +213,6 @@ void hcid_dbus_exit(void)  	if (!conn || !dbus_connection_get_is_connected(conn))  		return; -	release_default_agent_old(); -	release_default_auth_agent(); -	release_services(conn); -  	manager_cleanup(conn, "/");  	set_dbus_connection(NULL); diff --git a/hcid/dbus-database.c b/hcid/dbus-database.c index ab88c8f5..acdb5a72 100644 --- a/hcid/dbus-database.c +++ b/hcid/dbus-database.c @@ -46,8 +46,6 @@  #include "dbus-hci.h"  #include "dbus-common.h"  #include "error.h" -#include "dbus-service.h" -#include "dbus-security.h"  #include "dbus-database.h"  static GSList *records = NULL; diff --git a/hcid/dbus-hci.c b/hcid/dbus-hci.c index be5ce703..b9963f23 100644 --- a/hcid/dbus-hci.c +++ b/hcid/dbus-hci.c @@ -54,8 +54,6 @@  #include "glib-helper.h"  #include "dbus-common.h"  #include "dbus-error.h" -#include "dbus-service.h" -#include "dbus-security.h"  #include "agent.h"  #include "dbus-hci.h" @@ -401,10 +399,6 @@ int unregister_adapter_path(const char *path)  	/* check pending requests */  	reply_pending_requests(path, adapter); -	cancel_passkey_agent_requests(adapter->passkey_agents, path, NULL); - -	release_passkey_agents(adapter, NULL); -  	if (adapter->agent) {  		agent_destroy(adapter->agent, FALSE);  		adapter->agent = NULL; @@ -478,12 +472,6 @@ unreg:  		return -1;  	} -	if (!security_cleanup(connection, path)) { -		error("Failed to unregister security interface on %s object", -			path); -		return -1; -	} -  	return 0;  } @@ -717,10 +705,6 @@ int hcid_dbus_stop_device(uint16_t id)  	/* check pending requests */  	reply_pending_requests(path, adapter); -	cancel_passkey_agent_requests(adapter->passkey_agents, path, NULL); - -	release_passkey_agents(adapter, NULL); -  	if (adapter->discov_requestor) {  		g_dbus_remove_watch(connection, adapter->discov_listener);  		adapter->discov_listener = 0; @@ -839,15 +823,12 @@ int hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci)  		return -1;  	} -	if (!hcid_dbus_use_experimental()) -		goto old_fallback; -  	ba2str(&ci->bdaddr, addr);  	device = adapter_find_device(adapter, addr);  	agent = device && device->agent ? device->agent : adapter->agent;  	if (!agent) -		goto old_fallback; +		return -EPERM;  	if (!device) {  		device = adapter_create_device(connection, adapter, addr); @@ -865,15 +846,6 @@ int hcid_dbus_request_pin(int dev, bdaddr_t *sba, struct hci_conn_info *ci)  		auth->agent = agent;  	} - -	return ret; - -old_fallback: -	ret = handle_passkey_request_old(connection, dev, adapter, sba, -						&ci->bdaddr); -	if (ret == 0) -		adapter_new_auth_request(adapter, &ci->bdaddr, -						AUTH_TYPE_PINCODE);  	return ret;  } @@ -1175,8 +1147,6 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,  	if (status) {  		if (adapter->bonding)  			adapter->bonding->hci_status = status; -		cancel_passkey_agent_requests(adapter->passkey_agents, -						adapter->path, peer);  	}  	auth = adapter_find_auth_request(adapter, peer); @@ -1213,9 +1183,6 @@ void hcid_dbus_bonding_process_complete(bdaddr_t *local, bdaddr_t *peer,  	}  proceed: - -	release_passkey_agents(adapter, peer); -  	bonding = adapter->bonding;  	if (!bonding || bacmp(&bonding->bdaddr, peer))  		return; /* skip: no bonding req pending */ @@ -1879,10 +1846,6 @@ void hcid_dbus_conn_complete(bdaddr_t *local, uint8_t status, uint16_t handle,  	if (status) {  		struct pending_auth_info *auth; -		cancel_passkey_agent_requests(adapter->passkey_agents, -						adapter->path, peer); -		release_passkey_agents(adapter, peer); -  		auth = adapter_find_auth_request(adapter, peer);  		if (auth && auth->agent)  			agent_cancel(auth->agent); @@ -1946,10 +1909,6 @@ void hcid_dbus_disconn_complete(bdaddr_t *local, uint8_t status,  	hci_req_queue_remove(adapter->dev_id, &dev->bdaddr);  	/* Cancel D-Bus/non D-Bus requests */ -	cancel_passkey_agent_requests(adapter->passkey_agents, adapter->path, -					&dev->bdaddr); -	release_passkey_agents(adapter, &dev->bdaddr); -  	auth = adapter_find_auth_request(adapter, &dev->bdaddr);  	if (auth && auth->agent)  		agent_cancel(auth->agent); 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); -			} -		} -	} -} diff --git a/hcid/dbus-security.h b/hcid/dbus-security.h deleted file mode 100644 index 8c23417a..00000000 --- a/hcid/dbus-security.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * - *  BlueZ - Bluetooth protocol stack for Linux - * - *  Copyright (C) 2006-2007  Nokia Corporation - *  Copyright (C) 2004-2008  Marcel Holtmann <marcel@holtmann.org> - * - * - *  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 - * - */ - -#define SECURITY_INTERFACE "org.bluez.Security" - -dbus_bool_t security_init(DBusConnection *conn, const char *path); -dbus_bool_t security_cleanup(DBusConnection *conn, const char *path); - -int handle_passkey_request_old(DBusConnection *conn, int dev, -						struct adapter *adapter, -						bdaddr_t *sba, bdaddr_t *dba); - -int handle_confirm_request_old(DBusConnection *conn, int dev, -						struct adapter *adapter, -						bdaddr_t *sba, bdaddr_t *dba, -							const char *pin); - -void release_default_agent_old(void); - -void release_default_auth_agent(void); - -void release_passkey_agents(struct adapter *adapter, bdaddr_t *bda); - -void cancel_passkey_agent_requests(GSList *agents, const char *path, bdaddr_t *dba); - -int handle_authorize_request_old(struct service *service, const char *path, -				const char *address, const char *uuid, -				service_auth_cb cb, void *user_data); -int cancel_authorize_request_old(const char *path, const char *address); diff --git a/hcid/dbus-service.c b/hcid/dbus-service.c index fda7cf1b..f6946052 100644 --- a/hcid/dbus-service.c +++ b/hcid/dbus-service.c @@ -55,575 +55,12 @@  #include "device.h"  #include "dbus-service.h"  #include "dbus-hci.h" -#include "dbus-security.h" - -#define SERVICE_INTERFACE "org.bluez.Service" - -struct service_uuids { -	char *name; -	char **uuids; -};  struct service_auth {  	service_auth_cb cb;  	void *user_data;  }; -static GSList *services = NULL; -static GSList *services_uuids = NULL; - -static void service_free(struct service *service) -{ -	if (!service) -		return; - -	g_free(service->object_path); -	g_free(service->ident); -	g_free(service->name); - -	g_free(service); -} - -static DBusMessage *get_info(DBusConnection *conn, -			DBusMessage *msg, void *data) -{ -	struct service *service = data; -	DBusMessage *reply; -	DBusMessageIter iter; -	DBusMessageIter dict; - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return NULL; - -	dbus_message_iter_init_append(reply, &iter); - -	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, -			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING -			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING -			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - -	dbus_message_iter_append_dict_entry(&dict, "identifier", -			DBUS_TYPE_STRING, &service->ident); - -	dbus_message_iter_append_dict_entry(&dict, "name", -			DBUS_TYPE_STRING, &service->name); - -	dbus_message_iter_close_container(&iter, &dict); - -	return reply; -} - -static DBusMessage *get_identifier(DBusConnection *conn, -				DBusMessage *msg, void *data) -{ - -	struct service *service = data; -	DBusMessage *reply; -	const char *identifier = ""; - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return NULL; - -	if (service->ident) -		identifier = service->ident; - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &identifier, -							DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage *get_name(DBusConnection *conn, -			DBusMessage *msg, void *data) -{ - -	struct service *service = data; -	DBusMessage *reply; -	const char *name = ""; - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return NULL; - -	if (service->name) -		name = service->name; - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &name, -							DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage *get_description(DBusConnection *conn, -				DBusMessage *msg, void *data) -{ -	DBusMessage *reply; -	const char *description = ""; - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return NULL; - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &description, -							DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage *get_bus_name(DBusConnection *conn, -				DBusMessage *msg, void *data) -{ -	DBusMessage *reply; -	const char *busname = "org.bluez"; - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return NULL; - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &busname, -							DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage *start(DBusConnection *conn, -			DBusMessage *msg, void *data) -{ -	return g_dbus_create_error(msg, -			ERROR_INTERFACE ".Failed", -			strerror(EALREADY)); -} - -static DBusMessage *stop(DBusConnection *conn, -			DBusMessage *msg, void *data) -{ -	return g_dbus_create_error(msg, -			ERROR_INTERFACE ".Failed", -			strerror(EPERM)); -} - -static DBusMessage *is_running(DBusConnection *conn, -				DBusMessage *msg, void *data) -{ -	DBusMessage *reply; -	dbus_bool_t running = TRUE; - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return NULL; - -	dbus_message_append_args(reply, -			DBUS_TYPE_BOOLEAN, &running, -			DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage *is_external(DBusConnection *conn, -				DBusMessage *msg, void *data) -{ -	DBusMessage *reply; -	dbus_bool_t external = TRUE; - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return NULL; - -	dbus_message_append_args(reply, -			DBUS_TYPE_BOOLEAN, &external, -			DBUS_TYPE_INVALID); - -	return reply; -} - -static inline DBusMessage *invalid_args(DBusMessage *msg) -{ -	return g_dbus_create_error(msg, -			ERROR_INTERFACE ".InvalidArguments", -			"Invalid arguments in method call"); -} - -static DBusMessage *set_trusted(DBusConnection *conn, -				DBusMessage *msg, void *data) -{ -	struct service *service = data; -	const char *address; - -	if (!dbus_message_get_args(msg, NULL, -			DBUS_TYPE_STRING, &address, -			DBUS_TYPE_INVALID)) -		return invalid_args(msg); - -	if (check_address(address) < 0) -		return invalid_args(msg); - -	write_trust(BDADDR_ANY, address, service->ident, TRUE); - -	g_dbus_emit_signal(conn, service->object_path, -					SERVICE_INTERFACE, "TrustAdded", -					DBUS_TYPE_STRING, &address, -					DBUS_TYPE_INVALID); - -	return dbus_message_new_method_return(msg); -} - -static DBusMessage *list_trusted(DBusConnection *conn, -					DBusMessage *msg, void *data) -{ -	struct service *service = data; -	DBusMessage *reply; -	GSList *trusts, *l; -	char **addrs; -	int len; - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return NULL; - -	trusts = list_trusts(BDADDR_ANY, service->ident); - -	addrs = g_new(char *, g_slist_length(trusts)); - -	for (l = trusts, len = 0; l; l = l->next, len++) -		addrs[len] = l->data; - -	dbus_message_append_args(reply, -			DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, -			&addrs, len, DBUS_TYPE_INVALID); - -	g_free(addrs); -	g_slist_foreach(trusts, (GFunc) g_free, NULL); -	g_slist_free(trusts); - -	return reply; -} - -static DBusMessage *is_trusted(DBusConnection *conn, -					DBusMessage *msg, void *data) -{ -	struct service *service = data; -	DBusMessage *reply; -	const char *address; -	dbus_bool_t trusted; - -	if (!dbus_message_get_args(msg, NULL, -			DBUS_TYPE_STRING, &address, -			DBUS_TYPE_INVALID)) -		return invalid_args(msg); - -	if (check_address(address) < 0) -		return invalid_args(msg); - -	trusted = read_trust(BDADDR_ANY, address, service->ident); - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return NULL; - -	dbus_message_append_args(reply, -				DBUS_TYPE_BOOLEAN, &trusted, -				DBUS_TYPE_INVALID); - -	return reply; -} - -static DBusMessage *remove_trust(DBusConnection *conn, -					DBusMessage *msg, void *data) -{ -	struct service *service = data; -	const char *address; - -	if (!dbus_message_get_args(msg, NULL, -			DBUS_TYPE_STRING, &address, -			DBUS_TYPE_INVALID)) -		return invalid_args(msg); - -	if (check_address(address) < 0) -		return invalid_args(msg); - -	write_trust(BDADDR_ANY, address, service->ident, FALSE); - -	g_dbus_emit_signal(conn, service->object_path, -					SERVICE_INTERFACE, "TrustRemoved", -					DBUS_TYPE_STRING, &address, -					DBUS_TYPE_INVALID); - -	return dbus_message_new_method_return(msg); -} - -static GDBusMethodTable service_methods[] = { -	{ "GetInfo",		"",	"a{sv}",	get_info	}, -	{ "GetIdentifier",	"",	"s",		get_identifier	}, -	{ "GetName",		"",	"s",		get_name	}, -	{ "GetDescription",	"",	"s",		get_description	}, -	{ "GetBusName",		"",	"s",		get_bus_name	}, -	{ "Start",		"",	"",		start		}, -	{ "Stop",		"",	"",		stop		}, -	{ "IsRunning",		"",	"b",		is_running	}, -	{ "IsExternal",		"",	"b",		is_external	}, -	{ "SetTrusted",		"s",	"",		set_trusted	}, -	{ "IsTrusted",		"s",	"b",		is_trusted	}, -	{ "RemoveTrust",	"s",	"",		remove_trust	}, -	{ "ListTrusts",		"",	"as",		list_trusted	}, -	{ NULL, NULL, NULL, NULL } -}; - -static GDBusSignalTable service_signals[] = { -	{ "Started",		""	}, -	{ "Stopped",		""	}, -	{ "TrustAdded",		"s"	}, -	{ "TrustRemoved",	"s"	}, -	{ NULL, NULL } -}; - -static int service_cmp_path(struct service *service, const char *path) -{ -	return strcmp(service->object_path, path); -} - -static int service_cmp_ident(struct service *service, const char *ident) -{ -	return strcmp(service->ident, ident); -} - -static int unregister_service_for_connection(DBusConnection *connection, -						struct service *service) -{ -	debug("Unregistering service object: %s", service->object_path); - -	services = g_slist_remove(services, service); -	service_free(service); - -	return 0; -} - -static int do_unregister(struct service *service) -{ -	DBusConnection *conn = get_dbus_connection(); - -	return unregister_service_for_connection(conn, service); -} - -void release_services(DBusConnection *conn) -{ -	debug("release_services"); - -	g_slist_foreach(services, (GFunc) do_unregister, NULL); -	g_slist_free(services); -	services = NULL; -} - -struct service *search_service(const char *pattern) -{ -	GSList *l; -	const char *bus_id; - -	/* Workaround for plugins: share the same bus id */ -	bus_id = dbus_bus_get_unique_name(get_dbus_connection()); -	if (!strcmp(bus_id, pattern)) -		return NULL; - -	for (l = services; l != NULL; l = l->next) { -		struct service *service = l->data; - -		if (service->ident && !strcmp(service->ident, pattern)) -			return service; -	} - -	return NULL; -} - -void append_available_services(DBusMessageIter *array_iter) -{ -	GSList *l; - -	for (l = services; l != NULL; l = l->next) { -		struct service *service = l->data; - -		dbus_message_iter_append_basic(array_iter, -					DBUS_TYPE_STRING, &service->object_path); -	} -} - -int service_unregister(DBusConnection *conn, struct service *service) -{ -	return unregister_service_for_connection(conn, service); -} - -static gint name_cmp(struct service_uuids *su, const char *name) -{ -	return strcmp(su->name, name); -} - -static gint uuid_cmp(struct service_uuids *su, const char *uuid) -{ -	int i; - -	for (i = 0; su->uuids[i]; i++) { -		if (!strcasecmp(su->uuids[i], uuid)) -			return 0; -	} - -	return -1; -} - -struct service *search_service_by_uuid(const char *uuid) -{ -	struct service_uuids *su; -	struct service *service; -	GSList *l; - -	if (!services_uuids) -		return NULL; - -	l = g_slist_find_custom(services_uuids, uuid, (GCompareFunc) uuid_cmp); -	if (!l) -		return NULL; - -	su = l->data; -	service = search_service(su->name); -	if (!service) -		return NULL; - -	return service; -} - -static void register_uuids(const char *ident, const char **uuids) -{ -	struct service_uuids *su; -	int i; - -	if (!ident) -		return; - -	su = g_new0(struct service_uuids, 1); -	su->name = g_strdup(ident); - -	for (i = 0; uuids[i]; i++); - -	su->uuids = g_new0(char *, i + 1); - -	for (i = 0; uuids[i]; i++) -		su->uuids[i] = g_strdup(uuids[i]); - -	services_uuids = g_slist_append(services_uuids, su); -} - -static void service_uuids_free(struct service_uuids *su) -{ -	int i; - -	if (!su) -		return; - -	g_free(su->name); - -	for (i = 0; su->uuids[i]; i++) -		g_free(su->uuids[i]); - -	g_free(su); -} - -static void unregister_uuids(const char *ident) -{ -	struct service_uuids *su; -	GSList *l; - -	if (!services_uuids) -		return; - -	l = g_slist_find_custom(services_uuids, ident, (GCompareFunc) name_cmp); -	if (!l) -		return; - -	su = l->data; -	services_uuids = g_slist_remove(services_uuids, su); - -	service_uuids_free(su); -} - -static struct service *create_external_service(const char *ident) -{ -	struct service *service; -	const char *name; - -	service = g_try_new0(struct service, 1); -	if (!service) { -		error("OOM while allocating new external service"); -		return NULL; -	} - -	if (!strcmp(ident, "input")) -		name = "Input service"; -	else if (!strcmp(ident, "audio")) -		name = "Audio service"; -	else if (!strcmp(ident, "network")) -		name = "Network service"; -	else if (!strcmp(ident, "serial")) -		name = "Serial service"; -	else -		name = ""; - -	service->ident = g_strdup(ident); -	service->name = g_strdup(name); - -	return service; -} - -int register_service(const char *ident, const char **uuids) -{ -	DBusConnection *conn = get_dbus_connection(); -	struct service *service; -	char obj_path[PATH_MAX]; -	int i; - -	if (g_slist_find_custom(services, ident, -					(GCompareFunc) service_cmp_ident)) -		return -EADDRINUSE; - -	snprintf(obj_path, sizeof(obj_path) - 1, -				"/org/bluez/service_%s", ident); - -	/* Make the path valid for D-Bus */ -	for (i = strlen("/org/bluez/"); obj_path[i]; i++) { -		if (!isalnum(obj_path[i])) -			obj_path[i] = '_'; -	} - -	if (g_slist_find_custom(services, obj_path, -				(GCompareFunc) service_cmp_path)) -		return -EADDRINUSE; - -	service = create_external_service(ident); - -	debug("Registering service object: %s (%s)", -					service->ident, obj_path); - -	if (!g_dbus_register_interface(conn, obj_path, SERVICE_INTERFACE, -				service_methods, service_signals, -				NULL, service, NULL)) { -		error("D-Bus failed to register %s object", obj_path); -		service_free(service); -		return -1; -	} - -	service->object_path = g_strdup(obj_path); - -	services = g_slist_append(services, service); - -	if (uuids) -		register_uuids(ident, uuids); - -	return 0; -} - -void unregister_service(const char *ident) -{ -	unregister_uuids(ident); -} -  static void agent_auth_cb(struct agent *agent, DBusError *derr, void *user_data)  {  	struct service_auth *auth = user_data; @@ -640,7 +77,6 @@ int service_req_auth(const bdaddr_t *src, const bdaddr_t *dst,  	struct adapter *adapter;  	struct device *device;  	struct agent *agent; -	struct service *service;  	char address[18];  	gboolean trusted; @@ -653,14 +89,8 @@ int service_req_auth(const bdaddr_t *src, const bdaddr_t *dst,  				dst, active_conn_find_by_bdaddr))  		return -ENOTCONN; -	service = search_service_by_uuid(uuid); -	if (!service) -		return -EPERM; -  	ba2str(dst, address);  	trusted = read_trust(src, address, GLOBAL_TRUST); -	if (!trusted) -		trusted = read_trust(BDADDR_ANY, address, service->ident);  	if (trusted) {  		cb(NULL, user_data); @@ -669,13 +99,11 @@ int service_req_auth(const bdaddr_t *src, const bdaddr_t *dst,  	device = adapter_find_device(adapter, address);  	if (!device) -		return handle_authorize_request_old(service, adapter->path, -					address, uuid, cb, user_data); +		return -EPERM;  	agent = (device->agent ? : adapter->agent);  	if (!agent) -		return handle_authorize_request_old(service, adapter->path, -					address, uuid, cb, user_data); +		return -EPERM;  	auth = g_try_new0(struct service_auth, 1);  	if (!auth) @@ -709,7 +137,7 @@ int service_cancel_auth(const bdaddr_t *src, const bdaddr_t *dst)  	agent = (device->agent ? : adapter->agent);  	if (!agent) -		return cancel_authorize_request_old(adapter->path, address); +		return -EPERM;  	return agent_cancel(agent);  } diff --git a/hcid/dbus-service.h b/hcid/dbus-service.h index d41a170a..374f9008 100644 --- a/hcid/dbus-service.h +++ b/hcid/dbus-service.h @@ -22,25 +22,6 @@   *   */ -struct service { -	char *object_path; -	char *ident; -	char *name; -}; - -void release_services(DBusConnection *conn); - -void append_available_services(DBusMessageIter *iter); - -struct service *search_service(const char *pattern); - -struct service *search_service_by_uuid(const char *uuid); - -int service_unregister(DBusConnection *conn, struct service *service); - -int register_service(const char *ident, const char **uuids); -void unregister_service(const char *ident); -  typedef void (*service_auth_cb) (DBusError *derr, void *user_data);  int service_req_auth(const bdaddr_t *src, const bdaddr_t *dst,  		const char *uuid, service_auth_cb cb, void *user_data); diff --git a/hcid/device.c b/hcid/device.c index 7a519716..00f77aa4 100644 --- a/hcid/device.c +++ b/hcid/device.c @@ -1576,20 +1576,18 @@ int btd_register_device_driver(struct btd_device_driver *driver)  {  	const char **uuid; +	/* FIXME: hack to make hci to resolve service_req_auth symbol*/ +	service_req_auth(NULL, NULL, NULL, NULL, NULL);  	drivers = g_slist_append(drivers, driver);  	for (uuid = driver->uuids; *uuid; uuid++) {  		debug("name %s uuid %s", driver->name, *uuid);  	} -	register_service(driver->name, driver->uuids); -  	return 0;  }  void btd_unregister_device_driver(struct btd_device_driver *driver)  { -	unregister_service(driver->name); -  	drivers = g_slist_remove(drivers, driver);  } diff --git a/hcid/main.c b/hcid/main.c index f75f6c1f..8ecc5a39 100644 --- a/hcid/main.c +++ b/hcid/main.c @@ -52,7 +52,6 @@  #include "sdpd.h"  #include "adapter.h"  #include "dbus-common.h" -#include "dbus-service.h"  #include "dbus-database.h"  #include "dbus-hci.h"  #include "device.h" diff --git a/hcid/manager.c b/hcid/manager.c index caf1c956..20293e21 100644 --- a/hcid/manager.c +++ b/hcid/manager.c @@ -52,9 +52,7 @@  #include "error.h"  #include "dbus-error.h"  #include "dbus-hci.h" -#include "dbus-service.h"  #include "dbus-database.h" -#include "dbus-security.h"  #include "sdp-xml.h"  #include "manager.h"  | 
