/* * Copyright © 2003 Robert Marcano * Copyright © 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * $Id$ */ #include "config.h" #include "ephy-cert-manager-dialog.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 #include #include #include #include #include #include #include /* 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); #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 (certs_manager_dialog_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); object_class->finalize = certs_manager_dialog_finalize; g_type_class_add_private (object_class, sizeof (CertsManagerDialogPrivate)); } /* public functions */ G_DEFINE_TYPE (CertsManagerDialog, certs_manager_dialog, EPHY_TYPE_DIALOG) EphyDialog * certs_manager_dialog_new (void) { return g_object_new (EPHY_TYPE_CERTS_MANAGER_DIALOG, NULL); }