summaryrefslogtreecommitdiffstats
path: root/hcid
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2007-04-10 14:06:44 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2007-04-10 14:06:44 +0000
commitc853057d20c7539d5214d0a126055baacb60887f (patch)
treea94452b4aff3c2cc6ed686e4b7872b1057b61ae2 /hcid
parent2a209d402e7cc324d03fb7172ac892626068d00b (diff)
Implement global trust setting
Diffstat (limited to 'hcid')
-rw-r--r--hcid/dbus-adapter.c94
-rw-r--r--hcid/dbus-common.c30
-rw-r--r--hcid/dbus-common.h2
-rw-r--r--hcid/dbus-database.c18
-rw-r--r--hcid/dbus-security.c29
-rw-r--r--hcid/dbus-service.c9
-rw-r--r--hcid/hcid.h7
-rw-r--r--hcid/storage.c9
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)