Blame gck/gck-interaction.c

Packit Service f02b19
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
Packit Service f02b19
/* gck-interaction.c - the GObject PKCS#11 wrapper library
Packit Service f02b19
Packit Service f02b19
   Copyright (C) 2011 Collabora Ltd
Packit Service f02b19
Packit Service f02b19
   The Gnome Keyring Library is free software; you can redistribute it and/or
Packit Service f02b19
   modify it under the terms of the GNU Library General Public License as
Packit Service f02b19
   published by the Free Software Foundation; either version 2 of the
Packit Service f02b19
   License, or (at your option) any later version.
Packit Service f02b19
Packit Service f02b19
   The Gnome Keyring Library is distributed in the hope that it will be useful,
Packit Service f02b19
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service f02b19
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service f02b19
   Library General Public License for more details.
Packit Service f02b19
Packit Service f02b19
   You should have received a copy of the GNU Library General Public
Packit Service f02b19
   License along with the Gnome Library; see the file COPYING.LIB.  If not,
Packit Service f02b19
   see <http://www.gnu.org/licenses/>.
Packit Service f02b19
Packit Service f02b19
   Author: Stef Walter <stefw@collabora.co.uk>
Packit Service f02b19
*/
Packit Service f02b19
Packit Service f02b19
#include "config.h"
Packit Service f02b19
Packit Service f02b19
#include "gck-private.h"
Packit Service f02b19
Packit Service f02b19
#include <string.h>
Packit Service f02b19
Packit Service f02b19
#define GCK_INTERACTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GCK_TYPE_INTERACTION, GckInteraction))
Packit Service f02b19
#define GCK_IS_INTERACTION_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GCK_TYPE_INTERACTION))
Packit Service f02b19
#define GCK_INTERACTION_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GCK_TYPE_INTERACTION, GckInteractionClass))
Packit Service f02b19
Packit Service f02b19
typedef struct _GckInteractionClass GckInteractionClass;
Packit Service f02b19
Packit Service f02b19
struct _GckInteraction {
Packit Service f02b19
	GTlsInteraction interaction;
Packit Service f02b19
	GckModule *module;
Packit Service f02b19
};
Packit Service f02b19
Packit Service f02b19
struct _GckInteractionClass {
Packit Service f02b19
	GTlsInteractionClass parent;
Packit Service f02b19
};
Packit Service f02b19
Packit Service f02b19
enum {
Packit Service f02b19
	PROP_0,
Packit Service f02b19
	PROP_MODULE
Packit Service f02b19
};
Packit Service f02b19
Packit Service f02b19
G_DEFINE_TYPE (GckInteraction, _gck_interaction, G_TYPE_TLS_INTERACTION);
Packit Service f02b19
Packit Service f02b19
static void
Packit Service f02b19
_gck_interaction_init (GckInteraction *self)
Packit Service f02b19
{
Packit Service f02b19
Packit Service f02b19
}
Packit Service f02b19
Packit Service f02b19
static void
Packit Service f02b19
_gck_interaction_get_property (GObject *obj,
Packit Service f02b19
                               guint prop_id,
Packit Service f02b19
                               GValue *value,
Packit Service f02b19
                               GParamSpec *pspec)
Packit Service f02b19
{
Packit Service f02b19
	GckInteraction *self = GCK_INTERACTION (obj);
Packit Service f02b19
Packit Service f02b19
	switch (prop_id) {
Packit Service f02b19
	case PROP_MODULE:
Packit Service f02b19
		g_value_set_object (value, self->module);
Packit Service f02b19
		break;
Packit Service f02b19
	default:
Packit Service f02b19
		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
Packit Service f02b19
		break;
Packit Service f02b19
	}
Packit Service f02b19
}
Packit Service f02b19
Packit Service f02b19
static void
Packit Service f02b19
_gck_interaction_set_property (GObject *obj,
Packit Service f02b19
                             guint prop_id,
Packit Service f02b19
                             const GValue *value,
Packit Service f02b19
                             GParamSpec *pspec)
Packit Service f02b19
{
Packit Service f02b19
	GckInteraction *self = GCK_INTERACTION (obj);
Packit Service f02b19
Packit Service f02b19
	switch (prop_id) {
Packit Service f02b19
	case PROP_MODULE:
Packit Service f02b19
		g_return_if_fail (self->module == NULL);
Packit Service f02b19
		self->module = g_value_dup_object (value);
Packit Service f02b19
		g_return_if_fail (self->module != NULL);
Packit Service f02b19
		break;
Packit Service f02b19
	default:
Packit Service f02b19
		G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, prop_id, pspec);
Packit Service f02b19
		break;
Packit Service f02b19
	}
Packit Service f02b19
}
Packit Service f02b19
Packit Service f02b19
static void
Packit Service f02b19
_gck_interaction_dispose (GObject *obj)
Packit Service f02b19
{
Packit Service f02b19
	GckInteraction *self = GCK_INTERACTION (obj);
Packit Service f02b19
Packit Service f02b19
	g_clear_object (&self->module);
Packit Service f02b19
Packit Service f02b19
	G_OBJECT_CLASS (_gck_interaction_parent_class)->dispose (obj);
Packit Service f02b19
}
Packit Service f02b19
Packit Service f02b19
static GTlsInteractionResult
Packit Service f02b19
_gck_interaction_ask_password (GTlsInteraction *interaction,
Packit Service f02b19
                               GTlsPassword *password,
Packit Service f02b19
                               GCancellable *cancellable,
Packit Service f02b19
                               GError **error)
Packit Service f02b19
{
Packit Service f02b19
	GckInteraction *self = GCK_INTERACTION (interaction);
Packit Service f02b19
	gchar *value = NULL;
Packit Service f02b19
	gboolean ret = FALSE;
Packit Service f02b19
	GckSlot *token;
Packit Service f02b19
	GckObject *key;
Packit Service f02b19
Packit Service f02b19
	if (!self->module)
Packit Service f02b19
		return G_TLS_INTERACTION_UNHANDLED;
Packit Service f02b19
Packit Service f02b19
	token = gck_password_get_token (GCK_PASSWORD (password));
Packit Service f02b19
	if (token != NULL) {
Packit Service f02b19
		g_signal_emit_by_name (self->module, "authenticate-slot", token,
Packit Service f02b19
		                       g_tls_password_get_description (password),
Packit Service f02b19
		                       &value, &ret;;
Packit Service f02b19
		g_object_unref (token);
Packit Service f02b19
Packit Service f02b19
	} else {
Packit Service f02b19
		key = gck_password_get_key (GCK_PASSWORD (password));
Packit Service f02b19
		g_return_val_if_fail (GCK_IS_OBJECT (key), G_TLS_INTERACTION_UNHANDLED);
Packit Service f02b19
Packit Service f02b19
		g_signal_emit_by_name (self->module, "authenticate-object", key,
Packit Service f02b19
		                       g_tls_password_get_description (password),
Packit Service f02b19
		                       &value, &ret;;
Packit Service f02b19
		g_object_unref (key);
Packit Service f02b19
	}
Packit Service f02b19
Packit Service f02b19
	if (ret) {
Packit Service f02b19
		g_tls_password_set_value_full (password, (guchar *)value, -1, g_free);
Packit Service f02b19
		return G_TLS_INTERACTION_HANDLED;
Packit Service f02b19
	} else {
Packit Service f02b19
		return G_TLS_INTERACTION_UNHANDLED;
Packit Service f02b19
	}
Packit Service f02b19
}
Packit Service f02b19
Packit Service f02b19
static void
Packit Service f02b19
_gck_interaction_class_init (GckInteractionClass *klass)
Packit Service f02b19
{
Packit Service f02b19
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
Packit Service f02b19
	GTlsInteractionClass *interaction_class = G_TLS_INTERACTION_CLASS (klass);
Packit Service f02b19
Packit Service f02b19
	object_class->get_property = _gck_interaction_get_property;
Packit Service f02b19
	object_class->set_property = _gck_interaction_set_property;
Packit Service f02b19
	object_class->dispose = _gck_interaction_dispose;
Packit Service f02b19
Packit Service f02b19
	interaction_class->ask_password = _gck_interaction_ask_password;
Packit Service f02b19
Packit Service f02b19
	g_object_class_install_property (object_class, PROP_MODULE,
Packit Service f02b19
		g_param_spec_object ("module", "Module", "PKCS11 Module",
Packit Service f02b19
		                     GCK_TYPE_MODULE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
Packit Service f02b19
}
Packit Service f02b19
Packit Service f02b19
GTlsInteraction *
Packit Service f02b19
_gck_interaction_new (gpointer token_or_key)
Packit Service f02b19
{
Packit Service f02b19
	GTlsInteraction *result;
Packit Service f02b19
	GModule *module = NULL;
Packit Service f02b19
Packit Service f02b19
	g_return_val_if_fail (GCK_IS_SLOT (token_or_key) ||
Packit Service f02b19
	                      GCK_IS_OBJECT (token_or_key), NULL);
Packit Service f02b19
Packit Service f02b19
	g_object_get (token_or_key, "module", &module, NULL);
Packit Service f02b19
	result = g_object_new (GCK_TYPE_INTERACTION, "module", module, NULL);
Packit Service f02b19
	g_object_unref (module);
Packit Service f02b19
Packit Service f02b19
	return result;
Packit Service f02b19
}