summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2007-02-26 20:57:42 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2007-02-26 20:57:42 +0000
commit04a18d65207a17e4005c0c7d71c7aa01be1659fb (patch)
tree73c90b366976515b9ae9d0931795c56e69251a08
parentd9aa4a2058eace37d5c2d15508b4c4d9962c2bb5 (diff)
Implement the trust methods properly
-rw-r--r--hcid/dbus-database.c3
-rw-r--r--hcid/dbus-service.c34
-rw-r--r--hcid/dbus-service.h2
-rw-r--r--hcid/hcid.h4
-rw-r--r--hcid/storage.c129
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;
+}