diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2006-03-10 21:27:51 +0000 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2006-03-10 21:27:51 +0000 |
commit | 6508cdb8cd4ecf53c21826a878ec57d0dbb9205c (patch) | |
tree | 874e5c61c5894f1b2fa9c2908c4c4b7c503c3975 | |
parent | 1c37ee6736011106383c591cb387c724b0ff494e (diff) |
Break everything
-rw-r--r-- | hcid/dbus-adapter.c | 128 | ||||
-rw-r--r-- | hcid/dbus-common.c | 16 | ||||
-rw-r--r-- | hcid/dbus-manager.c | 58 | ||||
-rw-r--r-- | hcid/dbus-security.c | 159 | ||||
-rw-r--r-- | hcid/dbus.h | 8 |
5 files changed, 255 insertions, 114 deletions
diff --git a/hcid/dbus-adapter.c b/hcid/dbus-adapter.c index 06eb40f6..e1627a6e 100644 --- a/hcid/dbus-adapter.c +++ b/hcid/dbus-adapter.c @@ -1310,68 +1310,59 @@ static DBusMessage *handle_dev_discover_service_req(DBusMessage *msg, void *data } static const struct service_data dev_services[] = { - { DEV_GET_ADDRESS, handle_dev_get_address_req, DEV_GET_ADDRESS_SIGNATURE }, - { DEV_GET_VERSION, handle_dev_get_version_req, DEV_GET_VERSION_SIGNATURE }, - { DEV_GET_REVISION, handle_dev_get_revision_req, DEV_GET_REVISION_SIGNATURE }, - { DEV_GET_MANUFACTURER, handle_dev_get_manufacturer_req, DEV_GET_MANUFACTURER_SIGNATURE }, - { DEV_GET_COMPANY, handle_dev_get_company_req, DEV_GET_COMPANY_SIGNATURE }, - { DEV_GET_FEATURES, handle_dev_get_features_req, DEV_GET_FEATURES_SIGNATURE }, - { DEV_GET_MODE, handle_dev_get_mode_req, DEV_GET_MODE_SIGNATURE }, - { DEV_LIST_MINOR_CLASSES, handle_dev_list_minor_classes_req, DEV_LIST_MINOR_CLASSES_SIGNATURE }, - { DEV_SET_MODE, handle_dev_set_mode_req, DEV_SET_MODE_SIGNATURE }, - { DEV_GET_DISCOVERABLE_TO, handle_dev_get_discoverable_to_req, DEV_GET_DISCOVERABLE_TO_SIGNATURE }, - { DEV_SET_DISCOVERABLE_TO, handle_dev_set_discoverable_to_req, DEV_SET_DISCOVERABLE_TO_SIGNATURE }, - { DEV_IS_CONNECTABLE, handle_dev_is_connectable_req, DEV_IS_CONNECTABLE_SIGNATURE }, - { DEV_IS_DISCOVERABLE, handle_dev_is_discoverable_req, DEV_IS_DISCOVERABLE_SIGNATURE }, - { DEV_GET_MAJOR_CLASS, handle_dev_get_major_class_req, DEV_GET_MAJOR_CLASS_SIGNATURE }, - { DEV_GET_MINOR_CLASS, handle_dev_get_minor_class_req, DEV_GET_MINOR_CLASS_SIGNATURE }, - { DEV_SET_MINOR_CLASS, handle_dev_set_minor_class_req, DEV_SET_MINOR_CLASS_SIGNATURE }, - { DEV_GET_SERVICE_CLASSES, handle_dev_get_service_classes_req, DEV_GET_SERVICE_CLASSES_SIGNATURE }, - { DEV_GET_NAME, handle_dev_get_name_req, DEV_GET_NAME_SIGNATURE }, - { DEV_SET_NAME, handle_dev_set_name_req, DEV_SET_NAME_SIGNATURE }, + { DEV_GET_ADDRESS, handle_dev_get_address_req, }, + { DEV_GET_VERSION, handle_dev_get_version_req, }, + { DEV_GET_REVISION, handle_dev_get_revision_req, }, + { DEV_GET_MANUFACTURER, handle_dev_get_manufacturer_req, }, + { DEV_GET_COMPANY, handle_dev_get_company_req, }, + { DEV_GET_FEATURES, handle_dev_get_features_req, }, + { DEV_GET_MODE, handle_dev_get_mode_req, }, + { DEV_LIST_MINOR_CLASSES, handle_dev_list_minor_classes_req, }, + { DEV_SET_MODE, handle_dev_set_mode_req, }, + { DEV_GET_DISCOVERABLE_TO, handle_dev_get_discoverable_to_req, }, + { DEV_SET_DISCOVERABLE_TO, handle_dev_set_discoverable_to_req, }, + { DEV_IS_CONNECTABLE, handle_dev_is_connectable_req, }, + { DEV_IS_DISCOVERABLE, handle_dev_is_discoverable_req, }, + { DEV_GET_MAJOR_CLASS, handle_dev_get_major_class_req, }, + { DEV_GET_MINOR_CLASS, handle_dev_get_minor_class_req, }, + { DEV_SET_MINOR_CLASS, handle_dev_set_minor_class_req, }, + { DEV_GET_SERVICE_CLASSES, handle_dev_get_service_classes_req, }, + { DEV_GET_NAME, handle_dev_get_name_req, }, + { DEV_SET_NAME, handle_dev_set_name_req, }, - { DEV_GET_REMOTE_VERSION, handle_dev_get_remote_version_req, DEV_GET_REMOTE_VERSION_SIGNATURE }, - { DEV_GET_REMOTE_REVISION, handle_dev_get_remote_revision_req, DEV_GET_REMOTE_REVISION_SIGNATURE }, - { DEV_GET_REMOTE_MANUFACTURER, handle_dev_get_remote_manufacturer_req, DEV_GET_REMOTE_MANUFACTURER_SIGNATURE }, - { DEV_GET_REMOTE_COMPANY, handle_dev_get_remote_company_req, DEV_GET_REMOTE_COMPANY_SIGNATURE }, - { DEV_GET_REMOTE_NAME, handle_dev_get_remote_name_req, DEV_GET_REMOTE_NAME_SIGNATURE }, - { DEV_GET_REMOTE_ALIAS, handle_dev_get_remote_alias_req, DEV_GET_REMOTE_ALIAS_SIGNATURE }, - { DEV_SET_REMOTE_ALIAS, handle_dev_set_remote_alias_req, DEV_SET_REMOTE_ALIAS_SIGNATURE }, - - { DEV_LAST_SEEN, handle_dev_last_seen_req, DEV_LAST_SEEN_SIGNATURE }, - { DEV_LAST_USED, handle_dev_last_used_req, DEV_LAST_USED_SIGNATURE }, - - { DEV_CREATE_BONDING, handle_dev_create_bonding_req, DEV_CREATE_BONDING_SIGNATURE }, - { DEV_REMOVE_BONDING, handle_dev_remove_bonding_req, DEV_REMOVE_BONDING_SIGNATURE }, - { DEV_HAS_BONDING_NAME, handle_dev_has_bonding_req, DEV_HAS_BONDING_SIGNATURE }, - { DEV_LIST_BONDINGS, handle_dev_list_bondings_req, DEV_LIST_BONDINGS_SIGNATURE }, - { DEV_GET_PIN_CODE_LENGTH, handle_dev_get_pin_code_length_req, DEV_GET_PIN_CODE_LENGTH_SIGNATURE }, - { DEV_GET_ENCRYPTION_KEY_SIZE, handle_dev_get_encryption_key_size_req, DEV_GET_ENCRYPTION_KEY_SIZE_SIGNATURE }, - - { DEV_DISCOVER_DEVICES, handle_dev_discover_devices_req, DEV_DISCOVER_DEVICES_SIGNATURE }, - { DEV_CANCEL_DISCOVERY, handle_dev_cancel_discovery_req, DEV_CANCEL_DISCOVERY_SIGNATURE }, - { DEV_DISCOVER_CACHE, handle_dev_discover_cache_req, DEV_DISCOVER_CACHE_SIGNATURE }, - { DEV_DISCOVER_SERVICE, handle_dev_discover_service_req, DEV_DISCOVER_SERVICE_SIGNATURE }, - - { NULL, NULL, NULL} + { DEV_GET_REMOTE_VERSION, handle_dev_get_remote_version_req, }, + { DEV_GET_REMOTE_REVISION, handle_dev_get_remote_revision_req, }, + { DEV_GET_REMOTE_MANUFACTURER, handle_dev_get_remote_manufacturer_req, }, + { DEV_GET_REMOTE_COMPANY, handle_dev_get_remote_company_req, }, + { DEV_GET_REMOTE_NAME, handle_dev_get_remote_name_req, }, + { DEV_GET_REMOTE_ALIAS, handle_dev_get_remote_alias_req, }, + { DEV_SET_REMOTE_ALIAS, handle_dev_set_remote_alias_req, }, + + { DEV_LAST_SEEN, handle_dev_last_seen_req, }, + { DEV_LAST_USED, handle_dev_last_used_req, }, + + { DEV_CREATE_BONDING, handle_dev_create_bonding_req, }, + { DEV_REMOVE_BONDING, handle_dev_remove_bonding_req, }, + { DEV_HAS_BONDING_NAME, handle_dev_has_bonding_req, }, + { DEV_LIST_BONDINGS, handle_dev_list_bondings_req, }, + { DEV_GET_PIN_CODE_LENGTH, handle_dev_get_pin_code_length_req, }, + { DEV_GET_ENCRYPTION_KEY_SIZE, handle_dev_get_encryption_key_size_req, }, + + { DEV_DISCOVER_DEVICES, handle_dev_discover_devices_req, }, + { DEV_CANCEL_DISCOVERY, handle_dev_cancel_discovery_req, }, + { DEV_DISCOVER_CACHE, handle_dev_discover_cache_req, }, + { DEV_DISCOVER_SERVICE, handle_dev_discover_service_req, }, + + { NULL, NULL } }; DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void *data) { - const struct service_data *handlers = dev_services; - DBusMessage *reply = NULL; struct hci_dbus_data *dbus_data = data; - const char *method; - const char *signature; const char *iface; - uint32_t err = BLUEZ_EDBUS_UNKNOWN_METHOD; - method = dbus_message_get_member(msg); - signature = dbus_message_get_signature(msg); iface = dbus_message_get_interface(msg); - info("Adapter path:%s iface:%s method:%s", dbus_message_get_path(msg), iface, method); - if (strcmp(ADAPTER_INTERFACE, iface)) return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; @@ -1381,33 +1372,22 @@ DBusHandlerResult msg_func_device(DBusConnection *conn, DBusMessage *msg, void * goto failed; } - /* It's a device path id */ - for (; handlers->name != NULL; handlers++) { - if (strcmp(handlers->name, method)) - continue; + handler = find_service_handler(dev_services, msg); + if (!handler) + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - if (!strcmp(handlers->signature, signature)) { - reply = handlers->handler_func(msg, data); - err = 0; - break; - } else { - /* Set the error, but continue looping incase there is - * another method with the same name but a different - * signature */ - err = BLUEZ_EDBUS_WRONG_SIGNATURE; - continue; - } - } + return handler(conn, msg, data); failed: - if (err) - reply = bluez_new_failure_msg(msg, err); + if (err) { + DBusMessage *reply = bluez_new_failure_msg(msg, err); - if (reply) { - if (!dbus_connection_send (conn, reply, NULL)) - error("Can't send reply message"); + if (reply) { + if (!dbus_connection_send(conn, reply, NULL)) + error("Can't send reply message"); - dbus_message_unref(reply); + dbus_message_unref(reply); + } } return DBUS_HANDLER_RESULT_HANDLED; diff --git a/hcid/dbus-common.c b/hcid/dbus-common.c index 45cc6246..41a9ce3e 100644 --- a/hcid/dbus-common.c +++ b/hcid/dbus-common.c @@ -281,3 +281,19 @@ int name_listener_remove(DBusConnection *connection, const char *name, return 0; } + +service_hanbdler_func_t *find_service_handler(const service_data *handlers, DBusMessage *msg) +{ + struct service_data *current; + const char *name, *sig; + + member = dbus_message_get_member(msg); + + for (current = handlers; current->name != NULL; current++) { + if (!strcmp(current->name, member)) + return current->handler_func; + } + + return NULL; +} + diff --git a/hcid/dbus-manager.c b/hcid/dbus-manager.c index ad04f862..ffbdc943 100644 --- a/hcid/dbus-manager.c +++ b/hcid/dbus-manager.c @@ -127,53 +127,35 @@ static DBusMessage *handle_mgr_default_device_req(DBusMessage *msg, void *data) } static const struct service_data mgr_services[] = { - { MGR_LIST_ADAPTERS, handle_mgr_list_devices_req, MGR_LIST_ADAPTERS_SIGNATURE }, - { MGR_DEFAULT_ADAPTER, handle_mgr_default_device_req, MGR_DEFAULT_ADAPTER_SIGNATURE }, - { NULL, NULL, NULL } + { MGR_LIST_ADAPTERS, handle_mgr_list_devices_req }, + { MGR_DEFAULT_ADAPTER, handle_mgr_default_device_req }, + { NULL, NULL } }; -DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data) +static DBusHandlerResult handle_manager_method(DBusConnection *conn, + DBusMessage *msg, void *data) { - const struct service_data *handlers; - DBusMessage *reply = NULL; - const char *iface; - const char *method; - const char *signature; - uint32_t err = BLUEZ_EDBUS_UNKNOWN_METHOD; - DBusHandlerResult ret = DBUS_HANDLER_RESULT_NOT_YET_HANDLED; - - iface = dbus_message_get_interface(msg); - method = dbus_message_get_member(msg); - signature = dbus_message_get_signature(msg); + service_handler_func_t *handler; - info("Manager path:%s method:%s", dbus_message_get_path(msg), method); + handler = find_service_handler(mgr_services, msg); - if (strcmp(iface, MANAGER_INTERFACE)) - return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; + if (handler) + return handler(conn, msg, data); - for (handlers = mgr_services; handlers->name != NULL; handlers++) { - if (strcmp(handlers->name, method)) - continue; - - if (strcmp(handlers->signature, signature) != 0) - err = BLUEZ_EDBUS_WRONG_SIGNATURE; - else { - reply = handlers->handler_func(msg, data); - err = 0; - } + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} - ret = DBUS_HANDLER_RESULT_HANDLED; - } +DBusHandlerResult msg_func_manager(DBusConnection *conn, DBusMessage *msg, void *data) +{ + const char *iface; - if (err) - reply = bluez_new_failure_msg(msg, err); + iface = dbus_message_get_interface(msg); - if (reply) { - if (!dbus_connection_send (conn, reply, NULL)) - error("Can't send reply message"); + if (!strcmp(iface, MANAGER_INTERFACE)) + return handle_manager_method(conn, msg, data); - dbus_message_unref(reply); - } + if (!strcmp(iface, SECURITY_INTERFACE)) + return handle_security_method(conn, msg, data); - return ret; + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } diff --git a/hcid/dbus-security.c b/hcid/dbus-security.c index f3bf47c4..eec34272 100644 --- a/hcid/dbus-security.c +++ b/hcid/dbus-security.c @@ -27,3 +27,162 @@ #include <stdio.h> #include <errno.h> + +#include <dbus/dbus.h> + +#include "dbus.h" +#include "dbus-error.h" +#include "dbus-common.h" + +static struct passkey_agent *default_agent = NULL; + +static const struct service_data sec_services[] = { + { "RegisterDefault", register_default_agent }, + { "UnregisterDefault", unregister_default_agent }, + { NULL, NULL } +}; + +static void default_agent_exited(const char *name, void *data) +{ + debug("%s exited without unregistering the default passkey agent", name); + + if (!default_agent || strcmp(name, default_agent->name)) { + /* This should never happen (there's a bug in the code if it does */ + debug("default_agent_exited: mismatch with actual default_agent"); + return; + } + + free(default_agent->path); + free(default_agent->name); + free(default_agent); + default_agent = NULL; +} + +static DBusHandlerResult register_default_agent(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + char *path; + DBusMessage *reply; + + if (default_agent) { + reply = error_passkey_agent_already_exists(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + goto done; + } + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID)) { + reply = error_invalid_arguments(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + goto done; + } + + default_agent = malloc(sizeof(struct passkey_agent)); + if (!default_agent) + goto need_memory; + + memset(default_agent, 0, sizeof(struct passkey_agent)); + + default_agent->name = strdup(dbus_message_get_sender(msg)); + if (!default_agent->name) + goto need_memory; + + default_agent->path = strdup(path); + if (!default_agent->path) + goto need_memory; + + reply = dbus_message_new_method_return(); + if (!reply) + goto need_memory; + + name_listener_add(conn, default_agent->name, + (name_cb_t)default_agent_exited, NULL); + + info("Default passkey agent (%s, %s) registered", + default_agent->name, default_agent->path); + +done: + dbus_connection_send(conn, reply, NULL); + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; + +need_memory: + if (default_agent) { + if (default_agent->name) + free(default_agent->name); + if (default_agent->path) + free(default_agent->path); + free(default_agent); + default_agent = NULL; + } + + return DBUS_HANDLER_RESULT_NEED_MEMORY; +} + +static DBusHandlerResult unregister_default_agent(DBusConnection *conn, + DBusMessage *msg, void *data) +{ + DBusMessage *reply; + char *name, *path; + + if (!default_agent) { + reply = error_does_not_exist(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + goto done; + } + + if (!dbus_message_get_args(msg, NULL, + DBUS_TYPE_STRING, &path, + DBUS_TYPE_INVALID)) { + reply = error_invalid_arguments(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + goto done; + } + + if (strcmp(name, default_agent->name) || strcmp(path, default_agent->path)) { + reply = error_does_not_exist(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + goto done; + } + + reply = dbus_message_new_method_return(msg); + if (!reply) + return DBUS_HANDLER_RESULT_NEED_MEMORY; + + name_listener_remove(conn, default_agent->name, + (name_cb_t)default_agent_exited, NULL); + + info("Default passkey agent (%s, %s) unregistered", + default_agent->name, default_agent->path); + + free(default_agent->path); + free(default_agent->name); + free(default_agent); + default_agent = NULL; + +done: + dbus_connection_send(conn, reply, NULL); + dbus_message_unref(reply); + + return DBUS_HANDLER_RESULT_HANDLED; +} + +DBusHandlerResult handle_security_method(DBusConnection *conn, DBusMessage *msg, void *data) +{ + service_handler_func_t *handler; + + handler = find_service_handler(sec_services, msg); + + if (handler) + return handler(conn, msg, data); + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + diff --git a/hcid/dbus.h b/hcid/dbus.h index f833a421..3ae122fb 100644 --- a/hcid/dbus.h +++ b/hcid/dbus.h @@ -56,12 +56,13 @@ #define MAX_PATH_LENGTH 64 -typedef DBusMessage* (service_handler_func_t) (DBusMessage *, void *); +typedef DBusMessage* (service_handler_func_t) (DBusConnection *conn, + DBusMessage *msg, + void *user_data); struct service_data { const char *name; service_handler_func_t *handler_func; - const char *signature; }; typedef int (timeout_handler_func_t) (void *data); @@ -121,6 +122,9 @@ int name_listener_add(DBusConnection *connection, const char *name, int name_listener_remove(DBusConnection *connection, const char *name, name_cb_t func, void *user_data); +DBusHandlerResult handle_security_method(DBusConnection *conn, DBusMessage *msg, void *data); + +service_hanbdler_func_t *find_service_handler(service_data *services, DBusMessage *msg); /*======================================================================== BlueZ D-Bus Manager service definitions "/org/bluez/Manager" |