diff options
| -rw-r--r-- | hcid/dbus-database.c | 3 | ||||
| -rw-r--r-- | hcid/dbus-service.c | 34 | ||||
| -rw-r--r-- | hcid/dbus-service.h | 2 | ||||
| -rw-r--r-- | hcid/hcid.h | 4 | ||||
| -rw-r--r-- | hcid/storage.c | 129 | 
5 files changed, 144 insertions, 28 deletions
| diff --git a/hcid/dbus-database.c b/hcid/dbus-database.c index 86053915..755de673 100644 --- a/hcid/dbus-database.c +++ b/hcid/dbus-database.c @@ -339,8 +339,7 @@ static DBusHandlerResult request_authorization(DBusConnection *conn,  	if (!service)  		return error_not_authorized(conn, msg); -	if (g_slist_find_custom(service->trusted_devices, address, -				(GCompareFunc) strcasecmp)) { +	if (read_trust(address, service->ident)) {  		DBusMessage *reply;  		reply = dbus_message_new_method_return(msg); diff --git a/hcid/dbus-service.c b/hcid/dbus-service.c index e99cb8e0..4a4da621 100644 --- a/hcid/dbus-service.c +++ b/hcid/dbus-service.c @@ -76,11 +76,6 @@ static void service_free(struct service *service)  	g_free(service->descr);  	g_free(service->ident); -	if (service->trusted_devices) { -		g_slist_foreach(service->trusted_devices, (GFunc) g_free, NULL); -		g_slist_free(service->trusted_devices); -	} -  	g_free(service);  } @@ -481,7 +476,6 @@ static DBusHandlerResult set_trusted(DBusConnection *conn,  					DBusMessage *msg, void *data)  {  	struct service *service = data; -	GSList *l;  	DBusMessage *reply;  	const char *address; @@ -493,15 +487,11 @@ static DBusHandlerResult set_trusted(DBusConnection *conn,  	if (check_address(address) < 0)  		return error_invalid_arguments(conn, msg); -	l = g_slist_find_custom(service->trusted_devices, address, (GCompareFunc) strcasecmp); -	if (l) -		return error_trusted_device_already_exists(conn, msg); -  	reply = dbus_message_new_method_return(msg);  	if (!reply)  		return DBUS_HANDLER_RESULT_NEED_MEMORY; -	service->trusted_devices = g_slist_append(service->trusted_devices, g_strdup(address)); +	write_trust(address, service->ident, TRUE);  	return send_message_and_unref(conn, reply);  } @@ -510,7 +500,6 @@ static DBusHandlerResult is_trusted(DBusConnection *conn,  					DBusMessage *msg, void *data)  {  	struct service *service = data; -	GSList *l;  	DBusMessage *reply;  	const char *address;  	dbus_bool_t trusted; @@ -520,14 +509,16 @@ static DBusHandlerResult is_trusted(DBusConnection *conn,  			DBUS_TYPE_INVALID))  		return error_invalid_arguments(conn, msg); -	l = g_slist_find_custom(service->trusted_devices, address, (GCompareFunc) strcasecmp); -	trusted = (l? TRUE : FALSE); +	if (check_address(address) < 0) +		return error_invalid_arguments(conn, msg); + +	trusted = read_trust(address, service->ident);  	reply = dbus_message_new_method_return(msg);  	if (!reply)  		return DBUS_HANDLER_RESULT_NEED_MEMORY; -	dbus_message_append_args(msg, +	dbus_message_append_args(reply,  				DBUS_TYPE_BOOLEAN, &trusted,  				DBUS_TYPE_INVALID); @@ -538,28 +529,23 @@ static DBusHandlerResult remove_trust(DBusConnection *conn,  					DBusMessage *msg, void *data)  {  	struct service *service = data; -	GSList *l;  	DBusMessage *reply;  	const char *address; -	void *paddress;  	if (!dbus_message_get_args(msg, NULL,  			DBUS_TYPE_STRING, &address,  			DBUS_TYPE_INVALID))  		return error_invalid_arguments(conn, msg); -	l = g_slist_find_custom(service->trusted_devices, address, (GCompareFunc) strcasecmp); -	if (!l) -		return error_trusted_device_does_not_exists(conn, msg); +	if (check_address(address) < 0) +		return error_invalid_arguments(conn, msg); + +	write_trust(address, service->ident, FALSE);  	reply = dbus_message_new_method_return(msg);  	if (!reply)  		return DBUS_HANDLER_RESULT_NEED_MEMORY; -	paddress = l->data; -	service->trusted_devices = g_slist_remove(service->trusted_devices, l->data); -	g_free(paddress); -  	return send_message_and_unref(conn, reply);  } diff --git a/hcid/dbus-service.h b/hcid/dbus-service.h index 948537c6..141d703f 100644 --- a/hcid/dbus-service.h +++ b/hcid/dbus-service.h @@ -47,8 +47,6 @@ struct service {  	/* Services without a *.service file */  	gboolean external; - -	GSList *trusted_devices;  };  void release_services(DBusConnection *conn); diff --git a/hcid/hcid.h b/hcid/hcid.h index aeba6bb6..41a22983 100644 --- a/hcid/hcid.h +++ b/hcid/hcid.h @@ -26,6 +26,8 @@  #include <time.h>  #include <sys/types.h> +#include <glib.h> +  #include <bluetooth/bluetooth.h>  #include <bluetooth/hci.h> @@ -189,3 +191,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); diff --git a/hcid/storage.c b/hcid/storage.c index d99defb4..145a0f82 100644 --- a/hcid/storage.c +++ b/hcid/storage.c @@ -37,6 +37,8 @@  #include <sys/param.h>  #include <sys/socket.h> +#include <glib.h> +  #include <bluetooth/bluetooth.h>  #include "textfile.h" @@ -486,3 +488,130 @@ int read_pin_code(bdaddr_t *local, bdaddr_t *peer, char *pin)  	return len;  } + +static GSList *service_string_to_list(char *services) +{ +	GSList *l = NULL; +	char *start = services; +	int i, finished = 0; + +	for (i = 0; ; i++) { +		if (services[i] == '\0') +			finished = 1; + +		if (services[i] == ' ' || services[i] == '\0') { +			services[i] = '\0'; +			l = g_slist_append(l, start); +			start = services + i + 1; +		} + +		if (finished) +			break; +	} + +	return l; +} + +static char *service_list_to_string(GSList *services) +{ +	char str[1024]; +	int len = 0; + +	if (!services) +		return g_strdup(""); + +	memset(str, 0, sizeof(str)); + +	while (services) { +		int ret; +		char *ident = services->data; + +		if (services->next) +			ret = snprintf(str + len, sizeof(str) - len - 1, "%s ", +					ident); +					 +		else +			ret = snprintf(str + len, sizeof(str) - len - 1, "%s", +					ident); + +		if (ret > 0) +			len += ret; + +		services = services->next; +	} + +	return g_strdup(str); +} + +int write_trust(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_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + +	str = textfile_caseget(filename, addr); +	if (str) +		services = service_string_to_list(str); + +	match = g_slist_find_custom(services, service, (GCompareFunc) strcmp); +	trusted = match ? TRUE : FALSE; + +	/* If the old setting is the same as the requested one, we're done */ +	if (trusted == trust) { +		g_slist_free(services); +		if (str) +			free(str); +		return 0; +	} + +	if (trust) +		services = g_slist_append(services, (void *) service); +	else +		services = g_slist_remove(services, match->data); + +	/* Remove the entry if the last trusted service was removed */ +	if (!trust && !services) +		ret = textfile_casedel(filename, addr); +	else { +		char *new_str = service_list_to_string(services); +		ret = textfile_caseput(filename, addr, new_str); +		free(new_str); +	} + +	g_slist_free(services); + +	if (str) +		free(str); + +	return ret; +} + +gboolean read_trust(const char *addr, const char *service) +{ +	char filename[PATH_MAX + 1], *str; +	GSList *services; +	gboolean ret; + +	create_filename(filename, PATH_MAX, BDADDR_ANY, "trusts"); + +	str = textfile_caseget(filename, addr); +	if (!str) +		return FALSE; + +	services = service_string_to_list(str); + +	if (g_slist_find_custom(services, service, (GCompareFunc) strcmp)) +		ret = TRUE; +	else +		ret = FALSE; + +	g_slist_free(services); +	free(str); + +	return ret; +} | 
