예제 #1
0
static gboolean
method_change_lock_internal (GkdSecretService *self,
			     GDBusMethodInvocation *invocation,
			     const gchar *collection_path)
{
	GkdSecretChange *change;
	const char *caller;
	const gchar *path;
	GckObject *collection;

	caller = g_dbus_method_invocation_get_sender (invocation);

	/* Make sure it exists */
	collection = gkd_secret_objects_lookup_collection (self->objects, caller, collection_path);
	if (!collection) {
		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);

	change = gkd_secret_change_new (self, caller, collection_path);
	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (change));
	gkd_secret_service_publish_dispatch (self, caller,
					     GKD_SECRET_DISPATCH (change));

	g_dbus_method_invocation_return_value (invocation, g_variant_new ("(o)", path));
	g_object_unref (change);

	return TRUE;
}
예제 #2
0
static gboolean
service_method_read_alias (GkdExportedService *skeleton,
			   GDBusMethodInvocation *invocation,
			   gchar *alias,
			   GkdSecretService *self)
{
	gchar *path = NULL;
	const gchar *identifier;
	GckObject  *collection = NULL;

	identifier = gkd_secret_service_get_alias (self, alias);
	if (identifier)
		path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, -1);

	/* Make sure it actually exists */
	if (path)
		collection = gkd_secret_objects_lookup_collection (self->objects,
								   g_dbus_method_invocation_get_sender (invocation),
								   path);
	if (collection == NULL) {
		g_free (path);
		path = NULL;
	} else {
		g_object_unref (collection);
	}

	if (path == NULL)
		path = g_strdup ("/");

	gkd_exported_service_complete_read_alias (skeleton, invocation, path);
	g_free (path);

	return TRUE;
}
예제 #3
0
static DBusMessage*
service_method_change_lock (GkdSecretService *self, DBusMessage *message)
{
	GkdSecretChange *change;
	DBusMessage *reply;
	const char *caller;
	const gchar *path;
	GckObject *collection;

	caller = dbus_message_get_sender (message);
	if (!dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
		return NULL;

	/* Make sure it exists */
	collection = gkd_secret_objects_lookup_collection (self->objects, caller, path);
	if (!collection)
		return dbus_message_new_error (message, SECRET_ERROR_NO_SUCH_OBJECT,
		                               "The collection does not exist");
	g_object_unref (collection);

	change = gkd_secret_change_new (self, caller, path);
	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (change));
	gkd_secret_service_publish_dispatch (self, caller,
	                                     GKD_SECRET_DISPATCH (change));

	reply = dbus_message_new_method_return (message);
	dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);

	g_object_unref (change);
	return reply;
}
예제 #4
0
static gboolean
service_method_lock (GkdExportedService *skeleton,
		     GDBusMethodInvocation *invocation,
		     gchar **objpaths,
		     GkdSecretService *self)
{
	const char *caller;
	GckObject *collection;
	int i;
	char **locked;
	GPtrArray *array;

	caller = g_dbus_method_invocation_get_sender (invocation);
	array = g_ptr_array_new ();
	for (i = 0; objpaths[i] != NULL; ++i) {
		collection = gkd_secret_objects_lookup_collection (self->objects, caller, objpaths[i]);
		if (collection != NULL) {
			if (gkd_secret_lock (collection, NULL)) {
				g_ptr_array_add (array, objpaths[i]);
				gkd_secret_objects_emit_collection_locked (self->objects,
									   collection);
			}
			g_object_unref (collection);
		}
	}

	g_ptr_array_add (array, NULL);

	locked = (gchar **) g_ptr_array_free (array, FALSE);
	gkd_exported_service_complete_lock (skeleton, invocation,
					    (const gchar **) locked, "/");

	return TRUE;
}
예제 #5
0
static DBusMessage*
service_method_read_alias (GkdSecretService *self, DBusMessage *message)
{
	DBusMessage *reply;
	const char *alias;
	gchar *path = NULL;
	const gchar *identifier;
	GckObject  *collection = NULL;

	if (!dbus_message_get_args (message, NULL, DBUS_TYPE_STRING, &alias, DBUS_TYPE_INVALID))
		return NULL;

	identifier = gkd_secret_service_get_alias (self, alias);
	if (identifier)
		path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, -1);

	/* Make sure it actually exists */
	if (path)
		collection = gkd_secret_objects_lookup_collection (self->objects,
		                                                   dbus_message_get_sender (message), path);
	if (collection == NULL) {
		g_free (path);
		path = NULL;
	} else {
		g_object_unref (collection);
	}

	reply = dbus_message_new_method_return (message);
	if (path == NULL)
		path = g_strdup ("/");
	dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
	g_free (path);

	return reply;
}
static DBusMessage*
service_method_change_lock (GkdSecretService *self, DBusMessage *message)
{
	GkdSecretChange *change;
	ServiceClient *client;
	DBusMessage *reply;
	const char *caller;
	const gchar *path;
	GP11Object *collection;

	caller = dbus_message_get_sender (message);
	if (!dbus_message_get_args (message, NULL, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID))
		return NULL;

	/* Make sure it exists */
	collection = gkd_secret_objects_lookup_collection (self->objects, caller, path);
	if (!collection)
		return dbus_message_new_error (message, SECRET_ERROR_NO_SUCH_OBJECT,
		                               "The collection does not exist");
	g_object_unref (collection);

	change = gkd_secret_change_new (self, caller, path);
	client = g_hash_table_lookup (self->clients, caller);
	g_return_val_if_fail (client, NULL);
	path = gkd_secret_dispatch_get_object_path (GKD_SECRET_DISPATCH (change));
	g_hash_table_replace (client->prompts, (gpointer)path, g_object_ref (change));

	reply = dbus_message_new_method_return (message);
	dbus_message_append_args (reply, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);

	g_object_unref (change);
	return reply;
}
예제 #7
0
static gboolean
service_method_change_with_master_password (GkdExportedInternal *skeleton,
					    GDBusMethodInvocation *invocation,
					    gchar *path,
					    GVariant *original_variant,
					    GVariant *master_variant,
					    GkdSecretService *self)
{
	GkdSecretSecret *original, *master;
	GckObject *collection;
	GError *error = NULL;
	const gchar *sender;

	sender = g_dbus_method_invocation_get_sender (invocation);

	/* Parse the incoming message */
	original = gkd_secret_secret_parse (self, sender,
					    original_variant, &error);
	if (original == NULL) {
		g_dbus_method_invocation_take_error (invocation, error);
		return TRUE;
	}

	master = gkd_secret_secret_parse (self, sender,
					  master_variant, &error);
	if (master == NULL) {
		g_dbus_method_invocation_take_error (invocation, error);
		return TRUE;
	}

	/* Make sure we have such a collection */
	collection = gkd_secret_objects_lookup_collection (self->objects, sender,
							   path);

	/* No such collection */
	if (collection == NULL) {
	  g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
							 GKD_SECRET_ERROR_NO_SUCH_OBJECT,
							 "The collection does not exist");
	}

	/* Success */
	else if (gkd_secret_change_with_secrets (collection, NULL, original, master, &error))
		gkd_exported_internal_complete_change_with_master_password
			(skeleton, invocation);

	/* Failure */
	else
		gkd_secret_propagate_error (invocation, "Couldn't change collection password", error);

	gkd_secret_secret_free (original);
	gkd_secret_secret_free (master);

	if (collection)
		g_object_unref (collection);

	return TRUE;
}
예제 #8
0
static DBusMessage*
service_method_change_with_master_password (GkdSecretService *self, DBusMessage *message)
{
	DBusError derr = DBUS_ERROR_INIT;
	GkdSecretSecret *original, *master;
	GckObject *collection;
	DBusMessageIter iter;
	DBusMessage *reply;
	GError *error = NULL;
	const gchar *path;

	/* Parse the incoming message */
	if (!dbus_message_has_signature (message, "o(oayays)(oayays)"))
		return NULL;
	if (!dbus_message_iter_init (message, &iter))
		g_return_val_if_reached (NULL);
	dbus_message_iter_get_basic (&iter, &path);
	dbus_message_iter_next (&iter);
	original = gkd_secret_secret_parse (self, message, &iter, &derr);
	if (original == NULL)
		return gkd_secret_error_to_reply (message, &derr);
	dbus_message_iter_next (&iter);
	master = gkd_secret_secret_parse (self, message, &iter, &derr);
	if (master == NULL) {
		gkd_secret_secret_free (original);
		return gkd_secret_error_to_reply (message, &derr);
	}

	/* Make sure we have such a collection */
	collection = gkd_secret_objects_lookup_collection (self->objects,
	                                                   dbus_message_get_sender (message),
	                                                   path);

	/* No such collection */
	if (collection == NULL)
		reply = dbus_message_new_error (message, SECRET_ERROR_NO_SUCH_OBJECT,
		                                "The collection does not exist");

	/* Success */
	else if (gkd_secret_change_with_secrets (collection, NULL, original, master, &error))
		reply = dbus_message_new_method_return (message);

	/* Failure */
	else
		reply = gkd_secret_propagate_error (message, "Couldn't change collection password", error);

	gkd_secret_secret_free (original);
	gkd_secret_secret_free (master);

	if (collection)
		g_object_unref (collection);

	return reply;
}
예제 #9
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;
}
예제 #10
0
static gboolean
item_method_delete (GkdExportedItem *skeleton,
		    GDBusMethodInvocation *invocation,
		    GkdSecretObjects *self)
{
	GError *error = NULL;
	gchar *collection_path;
	gchar *item_path;
	GckObject *collection;
	GckObject *object;

	object = secret_objects_lookup_gck_object_for_invocation (self, invocation);
	if (!object) {
		return TRUE;
	}

	collection_path = collection_path_for_item (object);
	item_path = object_path_for_item (NULL, object);

	if (gck_object_destroy (object, NULL, &error)) {
		collection = gkd_secret_objects_lookup_collection (self, NULL, collection_path);
		if (collection != NULL) {
			gkd_secret_objects_emit_item_deleted (self, collection, item_path);
			g_object_unref (collection);
		}

		/* No prompt necessary */
		gkd_exported_item_complete_delete (skeleton, invocation, "/");

	} else {
		if (g_error_matches (error, GCK_ERROR, CKR_USER_NOT_LOGGED_IN))
			g_dbus_method_invocation_return_error_literal (invocation, GKD_SECRET_ERROR,
								       GKD_SECRET_ERROR_IS_LOCKED,
								       "Cannot delete a locked item");
		else
			g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
							       G_DBUS_ERROR_FAILED,
							       "Couldn't delete collection: %s",
							       egg_error_message (error));

		g_clear_error (&error);
	}

	g_free (collection_path);
	g_free (item_path);
	g_object_unref (object);

	return TRUE;
}
예제 #11
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);
}
예제 #12
0
static DBusMessage*
service_method_lock (GkdSecretService *self, DBusMessage *message)
{
	DBusMessage *reply;
	const char *caller;
	const gchar *prompt;
	GckObject *collection;
	int n_objpaths, i;
	char **objpaths;
	GPtrArray *array;

	if (!dbus_message_get_args (message, NULL,
	                            DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &objpaths, &n_objpaths,
	                            DBUS_TYPE_INVALID))
		return NULL;

	caller = dbus_message_get_sender (message);
	array = g_ptr_array_new ();
	for (i = 0; i < n_objpaths; ++i) {
		collection = gkd_secret_objects_lookup_collection (self->objects, caller, objpaths[i]);
		if (collection != NULL) {
			if (gkd_secret_lock (collection, NULL)) {
				g_ptr_array_add (array, objpaths[i]);
				gkd_secret_objects_emit_collection_locked (self->objects,
				                                           collection);
			}
			g_object_unref (collection);
		}
	}

	prompt = "/";
	reply = dbus_message_new_method_return (message);
	dbus_message_append_args (reply,
	                          DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH, &array->pdata, array->len,
	                          DBUS_TYPE_OBJECT_PATH, &prompt,
	                          DBUS_TYPE_INVALID);

	dbus_free_string_array (objpaths);
	return reply;
}
예제 #13
0
static gboolean
locate_alias_collection_if_exists (GkdSecretCreate *self)
{
	GkdSecretService *service;
	GkdSecretObjects *objects;
	GckObject *collection;
	const gchar *identifier;
	const gchar *caller;
	gchar *path;

	if (!self->alias)
		return FALSE;

	g_assert (!self->result_path);

	service = gkd_secret_prompt_get_service (GKD_SECRET_PROMPT (self));
	caller = gkd_secret_prompt_get_caller (GKD_SECRET_PROMPT (self));
	objects = gkd_secret_prompt_get_objects (GKD_SECRET_PROMPT (self));

	identifier = gkd_secret_service_get_alias (service, self->alias);
	if (!identifier)
		return FALSE;

	/* Make sure it actually exists */
	path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, -1);
	collection = gkd_secret_objects_lookup_collection (objects, caller, path);

	if (collection) {
		self->result_path = path;
		g_object_unref (collection);
		return TRUE;
	} else {
		g_free (path);
		return FALSE;
	}
}