diff options
| -rw-r--r-- | hcid/dbus-adapter.c | 94 | ||||
| -rw-r--r-- | hcid/dbus-common.c | 30 | ||||
| -rw-r--r-- | hcid/dbus-common.h | 2 | ||||
| -rw-r--r-- | hcid/dbus-database.c | 18 | ||||
| -rw-r--r-- | hcid/dbus-security.c | 29 | ||||
| -rw-r--r-- | hcid/dbus-service.c | 9 | ||||
| -rw-r--r-- | hcid/hcid.h | 7 | ||||
| -rw-r--r-- | hcid/storage.c | 9 | 
8 files changed, 158 insertions, 40 deletions
diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c index 612cef51..b67a3d3e 100644 --- a/hcid/dbus-adapter.c +++ b/hcid/dbus-adapter.c @@ -2809,6 +2809,96 @@ static DBusHandlerResult adapter_list_recent_remote_devices(DBusConnection *conn  	return send_message_and_unref(conn, reply);  } + +static DBusHandlerResult adapter_set_trusted(DBusConnection *conn, +						DBusMessage *msg, +						void *data) +{ +	struct adapter *adapter = data; +	DBusMessage *reply; +	bdaddr_t local; +	const char *address; + +	if (!dbus_message_get_args(msg, NULL, +			DBUS_TYPE_STRING, &address, +			DBUS_TYPE_INVALID)) +		return error_invalid_arguments(conn, msg); + +	if (check_address(address) < 0) +		return error_invalid_arguments(conn, msg); + +	reply = dbus_message_new_method_return(msg); +	if (!reply) +		return DBUS_HANDLER_RESULT_NEED_MEMORY; + +	str2ba(adapter->address, &local); + +	write_trust(&local, address, GLOBAL_TRUST, TRUE); + +	return send_message_and_unref(conn, reply); +} + +static DBusHandlerResult adapter_is_trusted(DBusConnection *conn, +						DBusMessage *msg, +						void *data) +{ +	struct adapter *adapter = data; +	DBusMessage *reply; +	const char *address; +	dbus_bool_t trusted; +	bdaddr_t local; + +	if (!dbus_message_get_args(msg, NULL, +			DBUS_TYPE_STRING, &address, +			DBUS_TYPE_INVALID)) +		return error_invalid_arguments(conn, msg); + +	if (check_address(address) < 0) +		return error_invalid_arguments(conn, msg); + +	str2ba(adapter->address, &local); + +	trusted = read_trust(&local, address, GLOBAL_TRUST); + +	reply = dbus_message_new_method_return(msg); +	if (!reply) +		return DBUS_HANDLER_RESULT_NEED_MEMORY; + +	dbus_message_append_args(reply, +				DBUS_TYPE_BOOLEAN, &trusted, +				DBUS_TYPE_INVALID); + +	return send_message_and_unref(conn, reply); +} + +static DBusHandlerResult adapter_remove_trust(DBusConnection *conn, +						DBusMessage *msg, +						void *data) +{ +	struct adapter *adapter = data; +	DBusMessage *reply; +	const char *address; +	bdaddr_t local; + +	if (!dbus_message_get_args(msg, NULL, +			DBUS_TYPE_STRING, &address, +			DBUS_TYPE_INVALID)) +		return error_invalid_arguments(conn, msg); + +	if (check_address(address) < 0) +		return error_invalid_arguments(conn, msg); + +	str2ba(adapter->address, &local); + +	write_trust(&local, address, GLOBAL_TRUST, FALSE); + +	reply = dbus_message_new_method_return(msg); +	if (!reply) +		return DBUS_HANDLER_RESULT_NEED_MEMORY; + +	return send_message_and_unref(conn, reply); +} +  const char *major_class_str(uint32_t class)  {  	uint8_t index = (class >> 8) & 0x1F; @@ -2947,6 +3037,10 @@ static struct service_data dev_services[] = {  	{ "ListRemoteDevices",			adapter_list_remote_devices	},  	{ "ListRecentRemoteDevices",		adapter_list_recent_remote_devices	}, +	{ "SetTrusted",				adapter_set_trusted		}, +	{ "IsTrusted",				adapter_is_trusted		}, +	{ "RemoveTrust",			adapter_remove_trust		}, +  	{ NULL, NULL }  }; diff --git a/hcid/dbus-common.c b/hcid/dbus-common.c index 3f08e5cd..7bdb2830 100644 --- a/hcid/dbus-common.c +++ b/hcid/dbus-common.c @@ -212,6 +212,36 @@ failed:  	return -1;  } +int find_conn(int s, int dev_id, long arg) +{ +	struct hci_conn_list_req *cl; +	struct hci_conn_info *ci; +	int i; + +	cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); + +	cl->dev_id = dev_id; +	cl->conn_num = 10; +	ci = cl->conn_info; + +	if (ioctl(s, HCIGETCONNLIST, cl)) { +		error("Can't get connection list"); +		goto failed; +	} + +	for (i = 0; i < cl->conn_num; i++, ci++) { +		if (bacmp((bdaddr_t *) arg, &ci->bdaddr)) +			continue; +		g_free(cl); +		return 1; +	} + +failed: +	g_free(cl); +	return 0; +} + +  int check_address(const char *addr)  {  	char tmp[18]; diff --git a/hcid/dbus-common.h b/hcid/dbus-common.h index 498f7eb4..21a6b003 100644 --- a/hcid/dbus-common.h +++ b/hcid/dbus-common.h @@ -50,6 +50,8 @@ int str2uuid(uuid_t *uuid, const char *string);  int l2raw_connect(const char *local, const bdaddr_t *remote); +int find_conn(int s, int dev_id, long arg); +  int check_address(const char *addr);  DBusHandlerResult handle_method_call(DBusConnection *conn, DBusMessage *msg, void *data); diff --git a/hcid/dbus-database.c b/hcid/dbus-database.c index 755de673..413fcffa 100644 --- a/hcid/dbus-database.c +++ b/hcid/dbus-database.c @@ -30,6 +30,8 @@  #include <string.h>  #include <bluetooth/bluetooth.h> +#include <bluetooth/hci.h> +#include <bluetooth/hci_lib.h>  #include <bluetooth/sdp.h>  #include <bluetooth/sdp_lib.h> @@ -323,6 +325,9 @@ static DBusHandlerResult request_authorization(DBusConnection *conn,  {  	const char *sender, *address, *path;  	struct service *service; +	bdaddr_t bdaddr; +	gboolean trusted; +	int adapter_id;  	debug("RequestAuthorization"); @@ -339,7 +344,18 @@ static DBusHandlerResult request_authorization(DBusConnection *conn,  	if (!service)  		return error_not_authorized(conn, msg); -	if (read_trust(address, service->ident)) { +	str2ba(address, &bdaddr); +	adapter_id = hci_for_each_dev(HCI_UP, find_conn, (long) &bdaddr); +	if (adapter_id < 0) +		return error_not_connected(conn, msg); + +	hci_devba(adapter_id, &bdaddr); + +	trusted = read_trust(&bdaddr, address, GLOBAL_TRUST); +	if (!trusted) +		trusted = read_trust(BDADDR_ANY, address, service->ident); + +	if (trusted) {  		DBusMessage *reply;  		reply = dbus_message_new_method_return(msg); diff --git a/hcid/dbus-security.c b/hcid/dbus-security.c index 1d034c2e..df06f008 100644 --- a/hcid/dbus-security.c +++ b/hcid/dbus-security.c @@ -723,35 +723,6 @@ static DBusPendingCall *auth_agent_call_authorize(struct authorization_agent *ag  	return call;  } -static int find_conn(int s, int dev_id, long arg) -{ -	struct hci_conn_list_req *cl; -	struct hci_conn_info *ci; -	int i; - -	cl = g_malloc0(10 * sizeof(*ci) + sizeof(*cl)); - -	cl->dev_id = dev_id; -	cl->conn_num = 10; -	ci = cl->conn_info; - -	if (ioctl(s, HCIGETCONNLIST, cl)) { -		error("Can't get connection list"); -		goto failed; -	} - -	for (i = 0; i < cl->conn_num; i++, ci++) { -		if (bacmp((bdaddr_t *) arg, &ci->bdaddr)) -			continue; -		g_free(cl); -		return 1; -	} - -failed: -	g_free(cl); -	return 0; -} -  DBusHandlerResult handle_authorize_request(DBusConnection *conn,  					DBusMessage *msg,  					struct service *service, diff --git a/hcid/dbus-service.c b/hcid/dbus-service.c index fe4f24df..d9ce3536 100644 --- a/hcid/dbus-service.c +++ b/hcid/dbus-service.c @@ -526,7 +526,7 @@ static DBusHandlerResult set_trusted(DBusConnection *conn,  	if (!reply)  		return DBUS_HANDLER_RESULT_NEED_MEMORY; -	write_trust(address, service->ident, TRUE); +	write_trust(BDADDR_ANY, address, service->ident, TRUE);  	return send_message_and_unref(conn, reply);  } @@ -547,7 +547,7 @@ static DBusHandlerResult is_trusted(DBusConnection *conn,  	if (check_address(address) < 0)  		return error_invalid_arguments(conn, msg); -	trusted = read_trust(address, service->ident); +	trusted = read_trust(BDADDR_ANY, address, service->ident);  	reply = dbus_message_new_method_return(msg);  	if (!reply) @@ -575,7 +575,7 @@ static DBusHandlerResult remove_trust(DBusConnection *conn,  	if (check_address(address) < 0)  		return error_invalid_arguments(conn, msg); -	write_trust(address, service->ident, FALSE); +	write_trust(BDADDR_ANY, address, service->ident, FALSE);  	reply = dbus_message_new_method_return(msg);  	if (!reply) @@ -646,7 +646,8 @@ static int register_service(struct service *service)  	int i;  	if (g_slist_find_custom(services, service->ident, -				(GCompareFunc) service_cmp_ident)) +				(GCompareFunc) service_cmp_ident) +			|| !strcmp(service->ident, GLOBAL_TRUST))  		return -EADDRINUSE;  	if (service->external) { diff --git a/hcid/hcid.h b/hcid/hcid.h index 41a22983..8983a899 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -37,6 +37,9 @@  #define HCID_DEFAULT_DISCOVERABLE_TIMEOUT 180 /* 3 minutes */ +/* When all services should trust a remote device */ +#define GLOBAL_TRUST "[all]" +  /*   * Scanning modes, used by DEV_SET_MODE   * off: remote devices are not allowed to find or connect to this device @@ -191,5 +194,5 @@ int write_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key, int type  int read_link_key(bdaddr_t *local, bdaddr_t *peer, unsigned char *key);  int read_pin_length(bdaddr_t *local, bdaddr_t *peer);  int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin); -gboolean read_trust(const char *addr, const char *service); -int write_trust(const char *addr, const char *service, gboolean trust); +gboolean read_trust(bdaddr_t *local, const char *addr, const char *service); +int write_trust(bdaddr_t *local, const char *addr, const char *service, gboolean trust); diff --git a/hcid/storage.c b/hcid/storage.c index 9e2f819b..19b13777 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -535,14 +535,15 @@ static char *service_list_to_string(GSList *services)  	return g_strdup(str);  } -int write_trust(const char *addr, const char *service, gboolean trust) +int write_trust(bdaddr_t *local, const char *addr, const char *service, +		gboolean trust)  {  	char filename[PATH_MAX + 1], *str;  	GSList *services = NULL, *match;  	gboolean trusted;  	int ret; -	create_filename(filename, PATH_MAX, BDADDR_ANY, "trusts"); +	create_filename(filename, PATH_MAX, local, "trusts");  	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); @@ -583,13 +584,13 @@ int write_trust(const char *addr, const char *service, gboolean trust)  	return ret;  } -gboolean read_trust(const char *addr, const char *service) +gboolean read_trust(bdaddr_t *local, const char *addr, const char *service)  {  	char filename[PATH_MAX + 1], *str;  	GSList *services;  	gboolean ret; -	create_filename(filename, PATH_MAX, BDADDR_ANY, "trusts"); +	create_filename(filename, PATH_MAX, local, "trusts");  	str = textfile_caseget(filename, addr);  	if (!str)  | 
