diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2007-04-10 14:06:44 +0000 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2007-04-10 14:06:44 +0000 |
commit | c853057d20c7539d5214d0a126055baacb60887f (patch) | |
tree | a94452b4aff3c2cc6ed686e4b7872b1057b61ae2 | |
parent | 2a209d402e7cc324d03fb7172ac892626068d00b (diff) |
Implement global trust setting
-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) |