static gboolean service_method_set_alias (GkdExportedService *skeleton, GDBusMethodInvocation *invocation, gchar *alias, gchar *path, GkdSecretService *self) { GckObject *collection; gchar *identifier; if (!g_str_equal (alias, "default")) { g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_NOT_SUPPORTED, "Only the 'default' alias is supported"); return TRUE; } /* No default collection */ if (g_str_equal (path, "/")) { identifier = g_strdup (""); /* Find a collection with that path */ } else { if (!object_path_has_prefix (path, SECRET_COLLECTION_PREFIX) || !gkd_secret_util_parse_path (path, &identifier, NULL)) { g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR, G_DBUS_ERROR_INVALID_ARGS, "Invalid collection object path"); return TRUE; } collection = gkd_secret_objects_lookup_collection (self->objects, g_dbus_method_invocation_get_sender (invocation), path); if (collection == NULL) { g_free (identifier); g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR, GKD_SECRET_ERROR_NO_SUCH_OBJECT, "The collection does not exist"); return TRUE; } g_object_unref (collection); } gkd_secret_service_set_alias (self, alias, identifier); g_free (identifier); gkd_exported_service_complete_set_alias (skeleton, invocation); return TRUE; }
static DBusMessage* service_method_set_alias (GkdSecretService *self, DBusMessage *message) { GckObject *collection; gchar *identifier; const char *alias; const char *path; if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &alias, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID)) return NULL; g_return_val_if_fail (alias, NULL); g_return_val_if_fail (path, NULL); if (!g_str_equal (alias, "default")) return dbus_message_new_error (message, DBUS_ERROR_NOT_SUPPORTED, "Only the 'default' alias is supported"); /* No default collection */ if (g_str_equal (path, "/")) { identifier = g_strdup (""); /* Find a collection with that path */ } else { if (!object_path_has_prefix (path, SECRET_COLLECTION_PREFIX) || !gkd_secret_util_parse_path (path, &identifier, NULL)) return dbus_message_new_error (message, DBUS_ERROR_INVALID_ARGS, "Invalid collection object path"); collection = gkd_secret_objects_lookup_collection (self->objects, dbus_message_get_sender (message), path); if (collection == NULL) { g_free (identifier); return dbus_message_new_error (message, SECRET_ERROR_NO_SUCH_OBJECT, "No such collection exists"); } g_object_unref (collection); } gkd_secret_service_set_alias (self, alias, identifier); g_free (identifier); return dbus_message_new_method_return (message); }
static DBusHandlerResult gkd_secret_service_filter_handler (DBusConnection *conn, DBusMessage *message, gpointer user_data) { GkdSecretService *self = user_data; const gchar *object_name; const gchar *old_owner; const gchar *new_owner; const gchar *path; const gchar *interface; g_return_val_if_fail (conn && message, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); g_return_val_if_fail (GKD_SECRET_IS_SERVICE (self), DBUS_HANDLER_RESULT_NOT_YET_HANDLED); /* org.freedesktop.DBus.NameOwnerChanged(STRING name, STRING old_owner, STRING new_owner) */ if (dbus_message_is_signal (message, DBUS_INTERFACE_DBUS, "NameOwnerChanged") && dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &object_name, DBUS_TYPE_STRING, &old_owner, DBUS_TYPE_STRING, &new_owner, DBUS_TYPE_INVALID)) { /* * A peer is connecting or disconnecting from the bus, * remove any client info, when client gone. */ g_return_val_if_fail (object_name && new_owner, DBUS_HANDLER_RESULT_NOT_YET_HANDLED); if (g_str_equal (new_owner, "") && object_name[0] == ':') g_hash_table_remove (self->clients, object_name); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } /* * If the path is a within our object tree, then we do our own dispatch. */ path = dbus_message_get_path (message); switch (dbus_message_get_type (message)) { /* Dispatch any method call on our interfaces, for our objects */ case DBUS_MESSAGE_TYPE_METHOD_CALL: if (object_path_has_prefix (path, SECRET_SERVICE_PATH)) { interface = dbus_message_get_interface (message); if (interface == NULL || g_str_has_prefix (interface, SECRET_INTERFACE_PREFIX) || g_str_equal (interface, DBUS_INTERFACE_PROPERTIES) || g_str_equal (interface, INTERNAL_SERVICE_INTERFACE) || g_str_equal (interface, DBUS_INTERFACE_INTROSPECTABLE)) { service_dispatch_message (self, message); return DBUS_HANDLER_RESULT_HANDLED; } } break; /* Dispatch any signal for one of our objects */ case DBUS_MESSAGE_TYPE_SIGNAL: if (object_path_has_prefix (path, SECRET_SERVICE_PATH)) { service_dispatch_message (self, message); return DBUS_HANDLER_RESULT_HANDLED; } break; default: break; } return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; }
static void service_dispatch_message (GkdSecretService *self, DBusMessage *message) { DBusMessage *reply = NULL; const gchar *caller; ServiceClient *client; const gchar *path; gpointer object; g_assert (GKD_SECRET_IS_SERVICE (self)); g_assert (message); /* The first thing we do is try to allocate a client context */ caller = dbus_message_get_sender (message); if (caller == NULL) { reply = dbus_message_new_error (message, DBUS_ERROR_FAILED, "Could not not identify calling client application"); dbus_connection_send (self->connection, reply, NULL); dbus_message_unref (reply); return; } client = g_hash_table_lookup (self->clients, caller); if (client == NULL) { initialize_service_client (self, message); return; /* This function called again, when client is initialized */ } path = dbus_message_get_path (message); g_return_if_fail (path); /* Dispatched to a session or prompt */ if (object_path_has_prefix (path, SECRET_SESSION_PREFIX) || object_path_has_prefix (path, SECRET_PROMPT_PREFIX)) { object = g_hash_table_lookup (client->dispatch, path); if (object == NULL) reply = gkd_secret_error_no_such_object (message); else reply = gkd_secret_dispatch_message (GKD_SECRET_DISPATCH (object), message); /* Dispatched to a collection, off it goes */ } else if (object_path_has_prefix (path, SECRET_COLLECTION_PREFIX) || object_path_has_prefix (path, SECRET_ALIAS_PREFIX)) { reply = gkd_secret_objects_dispatch (self->objects, message); /* Addressed to the service */ } else if (g_str_equal (path, SECRET_SERVICE_PATH)) { reply = service_message_handler (self, message); } /* Should we send an error? */ if (!reply && dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_METHOD_CALL) { if (!dbus_message_get_no_reply (message)) { reply = dbus_message_new_error_printf (message, DBUS_ERROR_UNKNOWN_METHOD, "Method \"%s\" with signature \"%s\" on interface \"%s\" doesn't exist\n", dbus_message_get_member (message), dbus_message_get_signature (message), dbus_message_get_interface (message)); } } if (reply) { dbus_connection_send (self->connection, reply, NULL); dbus_message_unref (reply); } }