Ejemplo n.º 1
0
static void
lookup_attributes (GckObject *object,
                   GckBuilder *builder)
{
	GckObjectCache *oakey;
	GckAttributes *attrs;

	if (GCK_IS_OBJECT_CACHE (object)) {
		oakey = GCK_OBJECT_CACHE (object);
		attrs = gck_object_cache_get_attributes (oakey);
		if (attrs != NULL) {
			gck_builder_add_all (builder, attrs);
			gck_attributes_unref (attrs);
		}
	}
}
Ejemplo n.º 2
0
static gboolean
collection_method_create_item (GkdExportedCollection *skeleton,
			       GDBusMethodInvocation *invocation,
			       GVariant *properties,
			       GVariant *secret_variant,
			       gboolean replace,
			       GkdSecretObjects *self)
{
	GckBuilder builder = GCK_BUILDER_INIT;
	GckSession *pkcs11_session = NULL;
	GkdSecretSecret *secret = NULL;
	GckAttributes *attrs = NULL;
	const GckAttribute *fields;
	GckObject *item = NULL;
	const gchar *base;
	GError *error = NULL;
	gchar *path = NULL;
	gchar *identifier;
	gboolean created = FALSE;
	GckObject *object;

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

	if (!gkd_secret_property_parse_all (properties, SECRET_ITEM_INTERFACE, &builder)) {
		g_dbus_method_invocation_return_error_literal (invocation, G_DBUS_ERROR,
							       G_DBUS_ERROR_INVALID_ARGS,
							       "Invalid properties argument");
		goto cleanup;
	}

	base = g_dbus_method_invocation_get_object_path (invocation);
	secret = gkd_secret_secret_parse (self->service, g_dbus_method_invocation_get_sender (invocation),
					  secret_variant, &error);

	if (secret == NULL) {
		g_dbus_method_invocation_take_error (invocation, error);
		error = NULL;
		goto cleanup;
	}

	if (!gkd_secret_util_parse_path (base, &identifier, NULL))
		g_return_val_if_reached (FALSE);
	g_return_val_if_fail (identifier, FALSE);

	pkcs11_session = gck_object_get_session (object);
	g_return_val_if_fail (pkcs11_session, FALSE);

	attrs = gck_attributes_ref_sink (gck_builder_end (&builder));

	if (replace) {
		fields = gck_attributes_find (attrs, CKA_G_FIELDS);
		if (fields)
			item = collection_find_matching_item (self, pkcs11_session, identifier, fields);
	}

	/* Replace the item */
	if (item) {
		if (!gck_object_set (item, attrs, NULL, &error))
			goto cleanup;

	/* Create a new item */
	} else {
		gck_builder_add_all (&builder, attrs);
		gck_builder_add_string (&builder, CKA_G_COLLECTION, identifier);
		gck_builder_add_ulong (&builder, CKA_CLASS, CKO_SECRET_KEY);
		item = gck_session_create_object (pkcs11_session, gck_builder_end (&builder), NULL, &error);
		if (item == NULL)
			goto cleanup;
		created = TRUE;
	}

	/* Set the secret */
	if (!gkd_secret_session_set_item_secret (secret->session, item, secret, &error)) {
		if (created) /* If we created, then try to destroy on failure */
			gck_object_destroy (item, NULL, NULL);
		goto cleanup;
	}

	path = object_path_for_item (base, item);
	gkd_secret_objects_emit_item_created (self, object, path);

	gkd_exported_collection_complete_create_item (skeleton, invocation, path, "/");

cleanup:
	if (error) {
		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 create an item in a locked collection");
		else
			g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
							       G_DBUS_ERROR_FAILED,
							       "Couldn't create item: %s",
							       egg_error_message (error));
		g_clear_error (&error);
	}

	gkd_secret_secret_free (secret);
	gck_attributes_unref (attrs);
	if (item)
		g_object_unref (item);
	if (pkcs11_session)
		g_object_unref (pkcs11_session);
	g_free (path);
	g_object_unref (object);

	return TRUE;
}