Blame ui/gcr-pkcs11-import-dialog.c

Packit b00eeb
/*
Packit b00eeb
 * gnome-keyring
Packit b00eeb
 *
Packit b00eeb
 * Copyright (C) 2008 Stefan Walter
Packit b00eeb
 *
Packit b00eeb
 * This program is free software; you can redistribute it and/or modify
Packit b00eeb
 * it under the terms of the GNU Lesser General Public License as
Packit b00eeb
 * published by the Free Software Foundation; either version 2.1 of
Packit b00eeb
 * the License, or (at your option) any later version.
Packit b00eeb
 *
Packit b00eeb
 * This program is distributed in the hope that it will be useful, but
Packit b00eeb
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit b00eeb
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit b00eeb
 * Lesser General Public License for more details.
Packit b00eeb
 *
Packit b00eeb
 * You should have received a copy of the GNU Lesser General Public
Packit b00eeb
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit b00eeb
 */
Packit b00eeb
Packit b00eeb
#include "config.h"
Packit b00eeb
Packit b00eeb
#include "gcr/gcr-icons.h"
Packit b00eeb
Packit b00eeb
#include "gcr-dialog-util.h"
Packit b00eeb
#include "gcr-secure-entry-buffer.h"
Packit b00eeb
#include "gcr-pkcs11-import-dialog.h"
Packit b00eeb
Packit b00eeb
#include "egg/egg-secure-memory.h"
Packit b00eeb
Packit b00eeb
#include <gtk/gtk.h>
Packit b00eeb
Packit b00eeb
#include <glib/gi18n-lib.h>
Packit b00eeb
Packit b00eeb
EGG_SECURE_DECLARE (import_dialog);
Packit b00eeb
Packit b00eeb
#define GCR_PKCS11_IMPORT_DIALOG_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GCR_TYPE_PKCS11_IMPORT_DIALOG, GcrPkcs11ImportDialogClass))
Packit b00eeb
#define GCR_IS_PKCS11_IMPORT_DIALOG_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GCR_TYPE_PKCS11_IMPORT_DIALOG))
Packit b00eeb
#define GCR_PKCS11_IMPORT_DIALOG_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS ((obj), GCR_TYPE_PKCS11_IMPORT_DIALOG, GcrPkcs11ImportDialogClass))
Packit b00eeb
Packit b00eeb
enum {
Packit b00eeb
	PROP_0,
Packit b00eeb
	PROP_IMPORTER
Packit b00eeb
};
Packit b00eeb
Packit b00eeb
struct _GcrPkcs11ImportDialog {
Packit b00eeb
	GtkDialog parent;
Packit b00eeb
	GtkBuilder *builder;
Packit b00eeb
	GtkWidget *password_area;
Packit b00eeb
	GtkLabel *token_label;
Packit b00eeb
	GtkImage *token_image;
Packit b00eeb
	GtkEntry *password_entry;
Packit b00eeb
	GtkEntry *label_entry;
Packit b00eeb
	gboolean label_changed;
Packit b00eeb
};
Packit b00eeb
Packit b00eeb
typedef struct _GcrPkcs11ImportDialogClass GcrPkcs11ImportDialogClass;
Packit b00eeb
Packit b00eeb
struct _GcrPkcs11ImportDialogClass {
Packit b00eeb
	GtkDialogClass parent;
Packit b00eeb
};
Packit b00eeb
Packit b00eeb
G_DEFINE_TYPE (GcrPkcs11ImportDialog, _gcr_pkcs11_import_dialog, GTK_TYPE_DIALOG);
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
on_label_changed (GtkEditable *editable,
Packit b00eeb
                  gpointer user_data)
Packit b00eeb
{
Packit b00eeb
	GcrPkcs11ImportDialog *self = GCR_PKCS11_IMPORT_DIALOG (user_data);
Packit b00eeb
	self->label_changed = TRUE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_pkcs11_import_dialog_constructed (GObject *obj)
Packit b00eeb
{
Packit b00eeb
	GcrPkcs11ImportDialog *self = GCR_PKCS11_IMPORT_DIALOG (obj);
Packit b00eeb
	GError *error = NULL;
Packit b00eeb
	GtkEntryBuffer *buffer;
Packit b00eeb
	GtkWidget *widget;
Packit b00eeb
	GtkBox *contents;
Packit b00eeb
	GtkWidget *button;
Packit b00eeb
Packit b00eeb
	G_OBJECT_CLASS (_gcr_pkcs11_import_dialog_parent_class)->constructed (obj);
Packit b00eeb
Packit b00eeb
	if (!gtk_builder_add_from_resource (self->builder, "/org/gnome/gcr/ui/gcr-pkcs11-import-dialog.ui", &error)) {
Packit b00eeb
		g_warning ("couldn't load ui builder file: %s", error->message);
Packit b00eeb
		return;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	/* Fill in the dialog from builder */
Packit b00eeb
	widget = GTK_WIDGET (gtk_builder_get_object (self->builder, "pkcs11-import-dialog"));
Packit b00eeb
	contents = GTK_BOX (gtk_dialog_get_content_area (GTK_DIALOG (self)));
Packit b00eeb
	gtk_box_pack_start (contents, widget, TRUE, TRUE, 0);
Packit b00eeb
Packit b00eeb
	/* The password area */
Packit b00eeb
	self->password_area = GTK_WIDGET (gtk_builder_get_object (self->builder, "unlock-area"));
Packit b00eeb
	gtk_widget_hide (self->password_area);
Packit b00eeb
Packit b00eeb
	/* Add a secure entry */
Packit b00eeb
	buffer = gcr_secure_entry_buffer_new ();
Packit b00eeb
	self->password_entry = GTK_ENTRY (gtk_builder_get_object (self->builder, "password-entry"));
Packit b00eeb
	gtk_entry_set_buffer (self->password_entry, buffer);
Packit b00eeb
	gtk_entry_set_activates_default (self->password_entry, TRUE);
Packit b00eeb
	g_object_unref (buffer);
Packit b00eeb
Packit b00eeb
	self->token_label = GTK_LABEL (gtk_builder_get_object (self->builder, "token-description"));
Packit b00eeb
	self->token_image = GTK_IMAGE (gtk_builder_get_object (self->builder, "token-image"));
Packit b00eeb
Packit b00eeb
	/* Setup the label */
Packit b00eeb
	self->label_entry = GTK_ENTRY (gtk_builder_get_object (self->builder, "label-entry"));
Packit b00eeb
	g_signal_connect (self->label_entry, "changed", G_CALLBACK (on_label_changed), self);
Packit b00eeb
	gtk_entry_set_activates_default (self->label_entry, TRUE);
Packit b00eeb
Packit b00eeb
	/* Add our various buttons */
Packit b00eeb
	button = gtk_dialog_add_button (GTK_DIALOG (self), _("_Cancel"), GTK_RESPONSE_CANCEL);
Packit b00eeb
	gtk_button_set_use_underline (GTK_BUTTON (button), TRUE);
Packit b00eeb
	button = gtk_dialog_add_button (GTK_DIALOG (self), _("_OK"), GTK_RESPONSE_OK);
Packit b00eeb
	gtk_button_set_use_underline (GTK_BUTTON (button), TRUE);
Packit b00eeb
	gtk_dialog_set_default_response (GTK_DIALOG (self), GTK_RESPONSE_OK);
Packit b00eeb
Packit b00eeb
	gtk_window_set_modal (GTK_WINDOW (self), TRUE);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_pkcs11_import_dialog_init (GcrPkcs11ImportDialog *self)
Packit b00eeb
{
Packit b00eeb
	self->builder = gtk_builder_new ();
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_pkcs11_import_dialog_finalize (GObject *obj)
Packit b00eeb
{
Packit b00eeb
	GcrPkcs11ImportDialog *self = GCR_PKCS11_IMPORT_DIALOG (obj);
Packit b00eeb
Packit b00eeb
	g_object_unref (self->builder);
Packit b00eeb
Packit b00eeb
	G_OBJECT_CLASS (_gcr_pkcs11_import_dialog_parent_class)->finalize (obj);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
static void
Packit b00eeb
_gcr_pkcs11_import_dialog_class_init (GcrPkcs11ImportDialogClass *klass)
Packit b00eeb
{
Packit b00eeb
	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
Packit b00eeb
Packit b00eeb
	gobject_class->constructed = _gcr_pkcs11_import_dialog_constructed;
Packit b00eeb
	gobject_class->finalize = _gcr_pkcs11_import_dialog_finalize;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
GcrPkcs11ImportDialog *
Packit b00eeb
_gcr_pkcs11_import_dialog_new (GtkWindow *parent)
Packit b00eeb
{
Packit b00eeb
	GcrPkcs11ImportDialog *dialog;
Packit b00eeb
Packit b00eeb
	g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);
Packit b00eeb
Packit b00eeb
	dialog = g_object_new (GCR_TYPE_PKCS11_IMPORT_DIALOG,
Packit b00eeb
	                       "transient-for", parent,
Packit b00eeb
	                       NULL);
Packit b00eeb
Packit b00eeb
	return g_object_ref_sink (dialog);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
void
Packit b00eeb
_gcr_pkcs11_import_dialog_get_supplements (GcrPkcs11ImportDialog *self,
Packit b00eeb
                                           GckBuilder *builder)
Packit b00eeb
{
Packit b00eeb
	const gchar *label;
Packit b00eeb
Packit b00eeb
	g_return_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self));
Packit b00eeb
	g_return_if_fail (builder != NULL);
Packit b00eeb
Packit b00eeb
	label = gtk_entry_get_text (self->label_entry);
Packit b00eeb
	if (self->label_changed && label != NULL && label[0])
Packit b00eeb
		gck_builder_set_string (builder, CKA_LABEL, label);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
void
Packit b00eeb
_gcr_pkcs11_import_dialog_set_supplements (GcrPkcs11ImportDialog *self,
Packit b00eeb
                                           GckBuilder *builder)
Packit b00eeb
{
Packit b00eeb
	gchar *label;
Packit b00eeb
Packit b00eeb
	g_return_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self));
Packit b00eeb
	g_return_if_fail (builder != NULL);
Packit b00eeb
Packit b00eeb
	if (!gck_builder_find_string (builder, CKA_LABEL, &label))
Packit b00eeb
		label = NULL;
Packit b00eeb
Packit b00eeb
	if (label == NULL)
Packit b00eeb
		gtk_entry_set_placeholder_text (self->label_entry, _("Automatically chosen"));
Packit b00eeb
	gtk_entry_set_text (self->label_entry, label == NULL ? "" : label);
Packit b00eeb
	g_free (label);
Packit b00eeb
Packit b00eeb
	self->label_changed = FALSE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
gboolean
Packit b00eeb
_gcr_pkcs11_import_dialog_run (GcrPkcs11ImportDialog *self)
Packit b00eeb
{
Packit b00eeb
	gboolean ret = FALSE;
Packit b00eeb
Packit b00eeb
	g_return_val_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self), FALSE);
Packit b00eeb
Packit b00eeb
	if (gtk_dialog_run (GTK_DIALOG (self)) == GTK_RESPONSE_OK) {
Packit b00eeb
		ret = TRUE;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	gtk_widget_hide (GTK_WIDGET (self));
Packit b00eeb
Packit b00eeb
	return ret;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
void
Packit b00eeb
_gcr_pkcs11_import_dialog_run_async (GcrPkcs11ImportDialog *self,
Packit b00eeb
                                     GCancellable *cancellable,
Packit b00eeb
                                     GAsyncReadyCallback callback,
Packit b00eeb
                                     gpointer user_data)
Packit b00eeb
{
Packit b00eeb
	g_return_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self));
Packit b00eeb
Packit b00eeb
	_gcr_dialog_util_run_async (GTK_DIALOG (self), cancellable, callback, user_data);
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
gboolean
Packit b00eeb
_gcr_pkcs11_import_dialog_run_finish (GcrPkcs11ImportDialog *self,
Packit b00eeb
                                      GAsyncResult *result)
Packit b00eeb
{
Packit b00eeb
	gint response;
Packit b00eeb
Packit b00eeb
	g_return_val_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self), FALSE);
Packit b00eeb
Packit b00eeb
	response = _gcr_dialog_util_run_finish (GTK_DIALOG (self), result);
Packit b00eeb
Packit b00eeb
	gtk_widget_hide (GTK_WIDGET (self));
Packit b00eeb
Packit b00eeb
	return (response == GTK_RESPONSE_OK) ? TRUE : FALSE;
Packit b00eeb
}
Packit b00eeb
Packit b00eeb
GTlsInteractionResult
Packit b00eeb
_gcr_pkcs11_import_dialog_run_ask_password (GcrPkcs11ImportDialog *self,
Packit b00eeb
                                            GTlsPassword *password,
Packit b00eeb
                                            GCancellable *cancellable,
Packit b00eeb
                                            GError **error)
Packit b00eeb
{
Packit b00eeb
	GckTokenInfo *token_info;
Packit b00eeb
	const gchar *value;
Packit b00eeb
	GckSlot *slot;
Packit b00eeb
	GIcon *icon;
Packit b00eeb
	gboolean ret;
Packit b00eeb
Packit b00eeb
	g_return_val_if_fail (GCR_IS_PKCS11_IMPORT_DIALOG (self), G_TLS_INTERACTION_UNHANDLED);
Packit b00eeb
	g_return_val_if_fail (G_IS_TLS_PASSWORD (password), G_TLS_INTERACTION_UNHANDLED);
Packit b00eeb
	g_return_val_if_fail (error == NULL || *error == NULL, G_TLS_INTERACTION_UNHANDLED);
Packit b00eeb
Packit b00eeb
	if (GCK_IS_PASSWORD (password)) {
Packit b00eeb
		slot = gck_password_get_token (GCK_PASSWORD (password));
Packit b00eeb
		token_info = gck_slot_get_token_info (slot);
Packit b00eeb
		icon = gcr_icon_for_token (token_info);
Packit b00eeb
		gtk_image_set_from_gicon (self->token_image, icon, GTK_ICON_SIZE_BUTTON);
Packit b00eeb
		gck_token_info_free (token_info);
Packit b00eeb
		g_object_unref (icon);
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	gtk_label_set_text (self->token_label, g_tls_password_get_description (password));
Packit b00eeb
Packit b00eeb
	gtk_widget_show (self->password_area);
Packit b00eeb
Packit b00eeb
	ret = _gcr_pkcs11_import_dialog_run (self);
Packit b00eeb
Packit b00eeb
	gtk_widget_hide (self->password_area);
Packit b00eeb
Packit b00eeb
	if (!ret) {
Packit b00eeb
		g_set_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED,
Packit b00eeb
		             _("The user cancelled the operation"));
Packit b00eeb
		return G_TLS_INTERACTION_FAILED;
Packit b00eeb
	}
Packit b00eeb
Packit b00eeb
	value = gtk_entry_get_text (self->password_entry);
Packit b00eeb
	g_tls_password_set_value_full (password, egg_secure_strdup (value),
Packit b00eeb
	                               -1, egg_secure_free);
Packit b00eeb
	return G_TLS_INTERACTION_HANDLED;
Packit b00eeb
}