diff options
Diffstat (limited to 'src/ephy-certificate-manager.c')
-rw-r--r-- | src/ephy-certificate-manager.c | 517 |
1 files changed, 517 insertions, 0 deletions
diff --git a/src/ephy-certificate-manager.c b/src/ephy-certificate-manager.c new file mode 100644 index 000000000..48721b3b2 --- /dev/null +++ b/src/ephy-certificate-manager.c @@ -0,0 +1,517 @@ +/* + * Copyright (C) 2003 Robert Marcano + * Copyright (C) 2005 Crispin Flowerday + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * $Id$ + */ + +#include "config.h" + +#include "ephy-certificate-manager.h" +#include "ephy-shell.h" +#include "ephy-embed-shell.h" +#include "ephy-gui.h" +#include "ephy-x509-cert.h" +#include "ephy-certificate-manager.h" +#include "ephy-embed-single.h" +#include "ephy-file-helpers.h" +#include "ephy-file-chooser.h" + +#include <gtk/gtkdialog.h> +#include <gtk/gtkbutton.h> +#include <gtk/gtkcellrenderertext.h> +#include <gtk/gtktreeview.h> +#include <gtk/gtktreeselection.h> +#include <gtk/gtkliststore.h> + +#include <glib/gi18n.h> +#include <glib.h> + +/* Glade callbacks */ +void +certs_manager_dialog_response_cb (GtkDialog *dialog, + gint response_id, + CertsManagerDialog *cm_dialog); +void +certs_manager_dialog_remove_button_clicked_cb (GtkButton *button, + CertsManagerDialog *dialog); +static void +tree_view_selection_changed_cb (GtkTreeSelection *selection, + CertsManagerDialog *dialog); + +static GObjectClass *parent_class = NULL; + +#define EPHY_CERTIFICATE_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_CERTS_MANAGER_DIALOG, CertsManagerDialogPrivate)) + +struct _CertsManagerDialogPrivate +{ + EphyCertificateManager *certs_manager; +}; + +enum +{ + RESPONSE_IMPORT = 1 +}; + +enum +{ + PROP_WINDOW, + PERSONAL_TREE_VIEW, + PERSONAL_REMOVE_BUTTON, + PERSONAL_VIEW_BUTTON, + PERSONAL_EXPORT_BUTTON, + SERVER_TREE_VIEW, + SERVER_REMOVE_BUTTON, + SERVER_VIEW_BUTTON, + SERVER_PROPS_BUTTON, + CA_TREE_VIEW, + CA_REMOVE_BUTTON, + CA_VIEW_BUTTON, + CA_PROPS_BUTTON +}; + +static const +EphyDialogProperty properties [] = +{ + { "certs_manager_dialog", NULL, PT_NORMAL, 0 }, + { "personal_treeview", NULL, PT_NORMAL, 0 }, + { "personal_remove_button", NULL, PT_NORMAL, 0 }, + { "personal_view_button", NULL, PT_NORMAL, 0 }, + { "personal_export_button", NULL, PT_NORMAL, 0 }, + { "server_treeview", NULL, PT_NORMAL, 0 }, + { "server_remove_button", NULL, PT_NORMAL, 0 }, + { "server_view_button", NULL, PT_NORMAL, 0 }, + { "server_props_button", NULL, PT_NORMAL, 0 }, + { "ca_treeview", NULL, PT_NORMAL, 0 }, + { "ca_remove_button", NULL, PT_NORMAL, 0 }, + { "ca_view_button", NULL, PT_NORMAL, 0 }, + { "ca_props_button", NULL, PT_NORMAL, 0 }, + + { NULL } +}; + +enum +{ + COL_NAME, + COL_CERT, + N_COLUMNS +}; + +static void +init_tree_view (CertsManagerDialog *dialog, GtkTreeView *tree_view) +{ + GtkCellRenderer *renderer; + GtkTreeSelection *selection; + GtkTreeViewColumn * column; + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_set_headers_visible (tree_view, TRUE); + gtk_tree_view_insert_column_with_attributes (tree_view, + -1, + _("Name"), + renderer, + "text", COL_NAME, + NULL); + column = gtk_tree_view_get_column (tree_view, COL_NAME); + gtk_tree_view_column_set_sort_column_id (column, COL_NAME); + selection = gtk_tree_view_get_selection (tree_view); + g_signal_connect (selection, + "changed", + G_CALLBACK (tree_view_selection_changed_cb), + dialog); + + +} + + +static void +append_cert (EphyX509Cert* cert, GtkListStore *list_store) +{ + GtkTreeIter iter; + const char *title; + + title = ephy_x509_cert_get_title (cert); + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, + COL_NAME, title, + COL_CERT, cert, + -1); +} + +static void +fill_tree_view_from_list (GtkTreeView *tree_view, + GList *list) +{ + GtkListStore *list_store; + + list_store = gtk_list_store_new (N_COLUMNS, + G_TYPE_STRING, + G_TYPE_OBJECT); + g_list_foreach (list, (GFunc)append_cert, list_store); + gtk_tree_view_set_model(tree_view, GTK_TREE_MODEL (list_store)); +} + +static void +set_buttons_sensitive (CertsManagerDialog *dialog, + gint button1, + gint button2, + gint button3, + gboolean value) +{ + GtkWidget *widget; + + widget = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[button1].id); + gtk_widget_set_sensitive (widget, value); + + widget = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[button2].id); + gtk_widget_set_sensitive (widget, value); + + widget = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[button3].id); + gtk_widget_set_sensitive (widget, value); +} + + +static void +chooser_response_cb (EphyFileChooser *chooser, + int response, + CertsManagerDialog *dialog) +{ + CertsManagerDialogPrivate *priv = dialog->priv; + if (response == GTK_RESPONSE_ACCEPT) + { + char *file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (chooser)); + + ephy_certificate_manager_import (priv->certs_manager, file); + + g_free (file); + } + + gtk_widget_destroy (GTK_WIDGET (chooser)); +} + +static void +import (GtkDialog *dialog, CertsManagerDialog *cm_dialog) +{ + EphyFileChooser *chooser; + + chooser = ephy_file_chooser_new (_("Import Certificate"), + GTK_WIDGET (dialog), + GTK_FILE_CHOOSER_ACTION_OPEN, + NULL, + EPHY_FILE_FILTER_ALL); + + g_signal_connect (chooser, "response", G_CALLBACK (chooser_response_cb), cm_dialog); + + gtk_widget_show (GTK_WIDGET (chooser)); +} + +void +certs_manager_dialog_response_cb (GtkDialog *widget, + int response, + CertsManagerDialog *dialog) +{ + if (response == GTK_RESPONSE_HELP) + { + /* TODO open help */ + return; + } + else if (response == RESPONSE_IMPORT) + { + import (widget, dialog); + return; + } + + g_object_unref (dialog); +} + +void +certs_manager_dialog_remove_button_clicked_cb (GtkButton *button, + CertsManagerDialog *dialog) +{ + CertsManagerDialogPrivate *priv = dialog->priv; + GtkTreeView *tree_view = NULL; + GtkTreeModel *model; + GtkTreeSelection *tree_selection; + EphyDialog *ephy_dialog; + GtkButton *personal_button; + GtkButton *server_button; + GtkButton *ca_button; + GList *selected_list, *remove_list = NULL, *l, *r; + GtkTreeIter iter; + GtkTreePath *path; + + ephy_dialog = EPHY_DIALOG (dialog); + personal_button = GTK_BUTTON (ephy_dialog_get_control + (ephy_dialog, + properties[PERSONAL_REMOVE_BUTTON].id)); + server_button = GTK_BUTTON (ephy_dialog_get_control + (ephy_dialog, + properties[SERVER_REMOVE_BUTTON].id)); + ca_button = GTK_BUTTON (ephy_dialog_get_control + (ephy_dialog, + properties[CA_REMOVE_BUTTON].id)); + if (button == personal_button) + tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[PERSONAL_TREE_VIEW].id)); + else if (button == server_button) + tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[SERVER_TREE_VIEW].id)); + else if (button == ca_button) + tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[CA_TREE_VIEW].id)); + g_assert (tree_view != NULL); + tree_selection = gtk_tree_view_get_selection (tree_view); + selected_list = gtk_tree_selection_get_selected_rows (tree_selection, &model); + + for (l = selected_list; l != NULL; l = l->next) + { + remove_list = g_list_prepend (remove_list, + gtk_tree_row_reference_new (model, + (GtkTreePath *)l->data)); + } + for (r = remove_list; r != NULL; r = r->next) + { + EphyX509Cert *cert; + GValue val = {0, }; + path = gtk_tree_row_reference_get_path ((GtkTreeRowReference *)r->data); + + gtk_tree_model_get_iter (model, &iter, path); + gtk_tree_model_get_value (model, &iter, COL_CERT, &val); + cert = EPHY_X509_CERT (g_value_dup_object (&val)); + g_value_unset (&val); + + // TODO check return value and notify if an error ocurred + ephy_certificate_manager_remove_certificate (priv->certs_manager, + cert); + g_object_unref (cert); + + gtk_list_store_remove (GTK_LIST_STORE (model), + &iter); + + gtk_tree_row_reference_free ((GtkTreeRowReference *)r->data); + gtk_tree_path_free (path); + } + g_list_free (selected_list); + g_list_free (remove_list); +} + +static void +tree_view_selection_changed_cb (GtkTreeSelection *selection, + CertsManagerDialog *dialog) +{ + gint count; + EphyDialog *ephy_dialog; + GtkTreeView *tree_view; + GtkTreeView *personal_tree_view; + GtkTreeView *server_tree_view; + GtkTreeView *ca_tree_view; + gboolean has_selection; + + ephy_dialog = EPHY_DIALOG (dialog); + tree_view = gtk_tree_selection_get_tree_view (selection); + personal_tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[PERSONAL_TREE_VIEW].id)); + server_tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[SERVER_TREE_VIEW].id)); + ca_tree_view = GTK_TREE_VIEW (ephy_dialog_get_control + (ephy_dialog, + properties[CA_TREE_VIEW].id)); + count = gtk_tree_selection_count_selected_rows (selection); + has_selection = count == 0 ? FALSE : TRUE; + if (tree_view == personal_tree_view) + set_buttons_sensitive (dialog, + PERSONAL_REMOVE_BUTTON, + PERSONAL_VIEW_BUTTON, + PERSONAL_EXPORT_BUTTON, + has_selection); + else if (tree_view == server_tree_view) + set_buttons_sensitive (dialog, + SERVER_REMOVE_BUTTON, + SERVER_VIEW_BUTTON, + SERVER_PROPS_BUTTON, + has_selection); + else if (tree_view == ca_tree_view) + set_buttons_sensitive (dialog, + CA_REMOVE_BUTTON, + CA_VIEW_BUTTON, + CA_PROPS_BUTTON, + has_selection); +} + + +static void +certs_manager_dialog_init (CertsManagerDialog *dialog) +{ + CertsManagerDialogPrivate *priv; + EphyEmbedShell *shell; + GtkWidget *window; + GtkTreeView *personal_treeview; + GtkTreeView *server_treeview; + GtkTreeView *ca_treeview; + GList *personalCerts; + GList *serverCerts; + GList *caCerts; + GtkWidget *button; + + priv = dialog->priv = EPHY_CERTIFICATE_MANAGER_GET_PRIVATE (dialog); + + shell = ephy_embed_shell_get_default (); + g_object_ref (shell); + + priv->certs_manager = EPHY_CERTIFICATE_MANAGER (ephy_embed_shell_get_embed_single (shell)); + + ephy_dialog_construct (EPHY_DIALOG (dialog), + properties, + ephy_file ("certs-manager.glade"), + "certs_manager_dialog", + NULL); + + window = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[PROP_WINDOW].id); + g_signal_connect (window, "response", + G_CALLBACK (certs_manager_dialog_response_cb), dialog); + + button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[PERSONAL_REMOVE_BUTTON].id); + g_signal_connect (button, "clicked", + G_CALLBACK (certs_manager_dialog_remove_button_clicked_cb), dialog); + button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[CA_REMOVE_BUTTON].id); + g_signal_connect (button, "clicked", + G_CALLBACK (certs_manager_dialog_remove_button_clicked_cb), dialog); + button = ephy_dialog_get_control (EPHY_DIALOG (dialog), properties[SERVER_REMOVE_BUTTON].id); + g_signal_connect (button, "clicked", + G_CALLBACK (certs_manager_dialog_remove_button_clicked_cb), dialog); + + /* disabling buttons until a certificate is selected */ + set_buttons_sensitive (dialog, + PERSONAL_REMOVE_BUTTON, + PERSONAL_VIEW_BUTTON, + PERSONAL_EXPORT_BUTTON, + FALSE); + set_buttons_sensitive (dialog, + SERVER_REMOVE_BUTTON, + SERVER_VIEW_BUTTON, + SERVER_PROPS_BUTTON, + FALSE); + set_buttons_sensitive (dialog, + CA_REMOVE_BUTTON, + CA_VIEW_BUTTON, + CA_PROPS_BUTTON, + FALSE); + + /* filling personal treeview */ + personalCerts = ephy_certificate_manager_get_certificates (priv->certs_manager, + PERSONAL_CERTIFICATE); + + personal_treeview = GTK_TREE_VIEW (ephy_dialog_get_control + (EPHY_DIALOG(dialog), + properties[PERSONAL_TREE_VIEW].id)); + init_tree_view (dialog, personal_treeview); + fill_tree_view_from_list (personal_treeview, personalCerts); + /* filling server treeview */ + serverCerts = ephy_certificate_manager_get_certificates (priv->certs_manager, + SERVER_CERTIFICATE); + server_treeview = GTK_TREE_VIEW (ephy_dialog_get_control + (EPHY_DIALOG(dialog), + properties[SERVER_TREE_VIEW].id)); + init_tree_view (dialog, server_treeview); + fill_tree_view_from_list (server_treeview, serverCerts); + /* filling ca treeview */ + caCerts = ephy_certificate_manager_get_certificates (priv->certs_manager, + CA_CERTIFICATE); + ca_treeview = GTK_TREE_VIEW (ephy_dialog_get_control + (EPHY_DIALOG(dialog), + properties[CA_TREE_VIEW].id)); + init_tree_view (dialog, ca_treeview); + fill_tree_view_from_list (ca_treeview, caCerts); + + g_list_foreach (personalCerts, (GFunc)g_object_unref, NULL); + g_list_free (personalCerts); + + g_list_foreach (serverCerts, (GFunc)g_object_unref, NULL); + g_list_free (serverCerts); + + g_list_foreach (caCerts, (GFunc)g_object_unref, NULL); + g_list_free (caCerts); +} + +static void +certs_manager_dialog_finalize (GObject *object) +{ + //CertsManagerDialog *dialog = EPHY_CERTS_MANAGER_DIALOG (object); + //CertsManagerDialogPrivate *priv = dialog->priv; + EphyEmbedShell *shell; + + /* TODO free certs in the treeviews */ + + G_OBJECT_CLASS (parent_class)->finalize (object); + + shell = ephy_embed_shell_get_default (); + g_object_unref (shell); +} + +static void +certs_manager_dialog_class_init (CertsManagerDialogClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object_class->finalize = certs_manager_dialog_finalize; + + g_type_class_add_private (object_class, sizeof (CertsManagerDialogPrivate)); +} + +/* public functions */ + +GType +certs_manager_dialog_get_type (void) +{ + static GType certs_manager_dialog_type = 0; + + if (certs_manager_dialog_type == 0) + { + static const GTypeInfo our_info = + { + sizeof (CertsManagerDialogClass), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc) certs_manager_dialog_class_init, + NULL, + NULL, /* class_data */ + sizeof (CertsManagerDialog), + 0, /* n_preallocs */ + (GInstanceInitFunc) certs_manager_dialog_init + }; + + certs_manager_dialog_type = g_type_register_static (EPHY_TYPE_DIALOG, + "CertsManagerDialog", + &our_info, 0); + } + + return certs_manager_dialog_type; + +} + +EphyDialog * +certs_manager_dialog_new (void) +{ + return g_object_new (EPHY_TYPE_CERTS_MANAGER_DIALOG, NULL); +} |