예제 #1
0
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;
}
예제 #2
0
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);
}
예제 #3
0
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;
}
예제 #4
0
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);
	}
}