Example #1
0
static GDBusMessage *
rewrite_default_alias (GkdSecretService *self,
                       GDBusMessage *message)
{
	const char *path = g_dbus_message_get_path (message);
	const char *replace;
	char *collection = NULL, *item = NULL;
	char *collection_path, *item_path;
	GDBusMessage *rewritten;
	GError *error = NULL;

	if (path == NULL)
		return message;

	if (!g_str_has_prefix (path, SECRET_ALIAS_PREFIX))
		return message;

	if (!gkd_secret_util_parse_path (path, &collection, &item))
		return message;

	replace = gkd_secret_service_get_alias (self, collection);
	if (!replace) {
		g_free (item);
		g_free (collection);
		return message;
	}

	rewritten = g_dbus_message_copy (message, &error);
	if (error != NULL) {
		g_error_free (error);
		return message;
	}

	collection_path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX,
						      replace, -1);

	if (item != NULL) {
		item_path = gkd_secret_util_build_path (collection_path,
							item, -1);
		g_dbus_message_set_path (rewritten, item_path);
		g_free (item_path);
	} else {
		g_dbus_message_set_path (rewritten, collection_path);
	}

	g_free (collection_path);
	g_free (item);
	g_free (collection);
	g_object_unref (message);

	return rewritten;
}
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;
}
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 gchar *
object_path_for_item (const gchar *base,
		      GckObject *item)
{
	GError *error = NULL;
	gpointer identifier;
	gsize n_identifier;
	gchar *alloc = NULL;
	gchar *path = NULL;

	if (base == NULL)
		base = alloc = collection_path_for_item (item);

	identifier = gck_object_get_data (item, CKA_ID, NULL, &n_identifier, &error);
	if (identifier == NULL) {
		g_warning ("couldn't get item identifier: %s", egg_error_message (error));
		g_clear_error (&error);
		path = NULL;

	} else {
		path = gkd_secret_util_build_path (base, identifier, n_identifier);
		g_free (identifier);
	}

	g_free (alloc);
	return path;
}
gchar*
gkd_secret_create_with_secret (GckAttributes *attrs, GkdSecretSecret *master,
                               DBusError *derr)
{
	GckAttributes *atts;
	GckObject *cred;
	GckObject *collection;
	GckSession *session;
	GError *error = NULL;
	gpointer identifier;
	gsize n_identifier;
	gboolean token;
	gchar *path;

	if (!gck_attributes_find_boolean (attrs, CKA_TOKEN, &token))
		token = FALSE;

	atts = gck_attributes_new ();
	gck_attributes_add_ulong (atts, CKA_CLASS, CKO_G_CREDENTIAL);
	gck_attributes_add_boolean (atts, CKA_MATE_TRANSIENT, TRUE);
	gck_attributes_add_boolean (atts, CKA_TOKEN, token);

	session = gkd_secret_session_get_pkcs11_session (master->session);
	g_return_val_if_fail (session, NULL);

	/* Create ourselves some credentials */
	cred = gkd_secret_session_create_credential (master->session, session, atts, master, derr);
	gck_attributes_unref (atts);

	if (cred == NULL)
		return FALSE;

	collection = gkd_secret_create_with_credential (session, attrs, cred, &error);

	gck_attributes_unref (atts);
	g_object_unref (cred);

	if (collection == NULL) {
		g_warning ("couldn't create collection: %s", egg_error_message (error));
		g_clear_error (&error);
		dbus_set_error (derr, DBUS_ERROR_FAILED, "Couldn't create new collection");
		return FALSE;
	}

	identifier = gck_object_get_data (collection, CKA_ID, NULL, &n_identifier, &error);
	g_object_unref (collection);

	if (!identifier) {
		g_warning ("couldn't lookup new collection identifier: %s", egg_error_message (error));
		g_clear_error (&error);
		dbus_set_error (derr, DBUS_ERROR_FAILED, "Couldn't find new collection just created");
		return FALSE;
	}

	path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
	g_free (identifier);
	return path;
}
void
gkd_secret_objects_foreach_collection (GkdSecretObjects *self,
				       const gchar *caller,
				       GkdSecretObjectsForeach callback,
				       gpointer user_data)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GckSession *session;
	GError *error = NULL;
	GList *collections, *l;
	gpointer identifier;
	gsize n_identifier;
	gchar *path;

	g_return_if_fail (GKD_SECRET_IS_OBJECTS (self));
	g_return_if_fail (callback);

	/* The session we're using to access the object */
	if (caller == NULL) {
		session = gkd_secret_service_internal_pkcs11_session (self->service);
	} else {
		session = gkd_secret_service_get_pkcs11_session (self->service, caller);
	}

	gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_COLLECTION);

	collections = gck_session_find_objects (session, gck_builder_end (&builder), NULL, &error);

	if (error != NULL) {
		g_warning ("couldn't lookup collections: %s", egg_error_message (error));
		g_clear_error (&error);
		return;
	}

	for (l = collections; l; l = g_list_next (l)) {

		identifier = gck_object_get_data (l->data, CKA_ID, NULL, &n_identifier, &error);
		if (identifier == NULL) {
			g_warning ("couldn't get collection identifier: %s", egg_error_message (error));
			g_clear_error (&error);
			continue;
		}

		path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
		g_free (identifier);

		(callback) (self, path, l->data, user_data);
		g_free (path);
	}

	gck_list_unref_free (collections);
}
gchar*
gkd_secret_create_with_secret (GckAttributes *attrs,
                               GkdSecretSecret *master,
                               GError **error)
{
    GckBuilder builder = GCK_BUILDER_INIT;
    GckAttributes *atts;
    GckObject *cred;
    GckObject *collection;
    GckSession *session;
    gpointer identifier;
    gsize n_identifier;
    gboolean token;
    gchar *path;

    if (!gck_attributes_find_boolean (attrs, CKA_TOKEN, &token))
        token = FALSE;

    gck_builder_add_ulong (&builder, CKA_CLASS, CKO_G_CREDENTIAL);
    gck_builder_add_boolean (&builder, CKA_GNOME_TRANSIENT, TRUE);
    gck_builder_add_boolean (&builder, CKA_TOKEN, token);

    session = gkd_secret_session_get_pkcs11_session (master->session);
    g_return_val_if_fail (session, NULL);

    /* Create ourselves some credentials */
    atts = gck_attributes_ref_sink (gck_builder_end (&builder));
    cred = gkd_secret_session_create_credential (master->session, session,
            atts, master, error);
    gck_attributes_unref (atts);

    if (cred == NULL)
        return FALSE;

    collection = gkd_secret_create_with_credential (session, attrs, cred, error);

    g_object_unref (cred);

    if (collection == NULL)
        return FALSE;

    identifier = gck_object_get_data (collection, CKA_ID, NULL, &n_identifier, error);
    g_object_unref (collection);

    if (!identifier)
        return FALSE;

    path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
    g_free (identifier);
    return path;
}
static gchar *
collection_path_for_item (GckObject *item)
{
	GError *error = NULL;
	gpointer identifier;
	gsize n_identifier;
	gchar *path = NULL;

	identifier = gck_object_get_data (item, CKA_G_COLLECTION, NULL, &n_identifier, &error);
	if (!identifier) {
		g_warning ("couldn't get item collection identifier: %s", egg_error_message (error));
		g_clear_error (&error);
		return NULL;
	}

	path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
	g_free (identifier);
	return path;
}
static gchar *
object_path_for_collection (GckObject *collection)
{
	GError *error = NULL;
	gpointer identifier;
	gsize n_identifier;
	gchar *path = NULL;

	identifier = gck_object_get_data (collection, CKA_ID, NULL, &n_identifier, &error);
	if (identifier == NULL) {
		g_warning ("couldn't get collection identifier: %s", egg_error_message (error));
		g_clear_error (&error);
		path = NULL;

	} else {
		path = gkd_secret_util_build_path (SECRET_COLLECTION_PREFIX, identifier, n_identifier);
		g_free (identifier);
	}

	return path;
}
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;
	}
}