|
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 |
}
|