aboutsummaryrefslogtreecommitdiffstats
path: root/smime/gui/certificate-manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'smime/gui/certificate-manager.c')
-rw-r--r--smime/gui/certificate-manager.c323
1 files changed, 267 insertions, 56 deletions
diff --git a/smime/gui/certificate-manager.c b/smime/gui/certificate-manager.c
index 7e4e1b1e1d..e49617a2db 100644
--- a/smime/gui/certificate-manager.c
+++ b/smime/gui/certificate-manager.c
@@ -22,11 +22,7 @@
#define GLADE_FILE_NAME "smime-ui.glade"
-#include <gtk/gtkcontainer.h>
-#include <gtk/gtktreeview.h>
-#include <gtk/gtktreestore.h>
-#include <gtk/gtktreemodelsort.h>
-#include <gtk/gtkcellrenderertext.h>
+#include <gtk/gtk.h>
#include <libgnome/gnome-i18n.h>
@@ -35,6 +31,7 @@
#include "certificate-manager.h"
#include "e-cert.h"
+#include "e-cert-db.h"
#include "nss.h"
#include <cms.h>
@@ -49,6 +46,11 @@ typedef struct {
GtkWidget *yourcerts_treeview;
GtkTreeStore *yourcerts_treemodel;
GHashTable *yourcerts_root_hash;
+ GtkWidget *view_your_button;
+ GtkWidget *backup_your_button;
+ GtkWidget *backup_all_your_button;
+ GtkWidget *import_your_button;
+ GtkWidget *delete_your_button;
GtkWidget *contactcerts_treeview;
GtkTreeStore *contactcerts_treemodel;
@@ -57,18 +59,72 @@ typedef struct {
GtkWidget *authoritycerts_treeview;
GtkTreeStore *authoritycerts_treemodel;
GHashTable *authoritycerts_root_hash;
+ GtkWidget *view_ca_button;
+ GtkWidget *edit_ca_button;
+ GtkWidget *import_ca_button;
+ GtkWidget *delete_ca_button;
+
} CertificateManagerData;
-typedef enum {
- USER_CERT,
- CONTACT_CERT,
- CA_CERT
-} CertType;
+typedef void (*AddCertCb)(CertificateManagerData *cfm, ECert *cert);
+
+static void unload_certs (CertificateManagerData *cfm, ECertType type);
+static void load_certs (CertificateManagerData *cfm, ECertType type, AddCertCb add_cert);
+
+static void add_user_cert (CertificateManagerData *cfm, ECert *cert);
+static void add_contact_cert (CertificateManagerData *cfm, ECert *cert);
+static void add_ca_cert (CertificateManagerData *cfm, ECert *cert);
+
+static void
+handle_selection_changed (GtkTreeSelection *selection,
+ int cert_column,
+ GtkWidget *view_button,
+ GtkWidget *edit_button,
+ GtkWidget *delete_button)
+{
+ GtkTreeIter iter;
+ gboolean cert_selected = FALSE;
+ GtkTreeModel *model;
+
+ if (gtk_tree_selection_get_selected (selection,
+ &model,
+ &iter)) {
+ ECert *cert;
+
+ gtk_tree_model_get (model,
+ &iter,
+ cert_column, &cert,
+ -1);
+
+ if (cert) {
+ cert_selected = TRUE;
+ g_object_unref (cert);
+ }
+ }
+
+ if (delete_button)
+ gtk_widget_set_sensitive (delete_button, cert_selected);
+ if (edit_button)
+ gtk_widget_set_sensitive (edit_button, cert_selected);
+ if (view_button)
+ gtk_widget_set_sensitive (view_button, cert_selected);
+}
+
+static void
+yourcerts_selection_changed (GtkTreeSelection *selection, CertificateManagerData *cfm)
+{
+ handle_selection_changed (gtk_tree_view_get_selection (GTK_TREE_VIEW(cfm->yourcerts_treeview)),
+ 4,
+ cfm->view_your_button,
+ cfm->backup_your_button, /* yes yes, not really "edit", it's a hack :) */
+ cfm->delete_your_button);
+}
static void
initialize_yourcerts_ui (CertificateManagerData *cfm)
{
GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
+ GtkTreeSelection *selection;
gtk_tree_view_append_column (GTK_TREE_VIEW (cfm->yourcerts_treeview),
gtk_tree_view_column_new_with_attributes (_("Certificate Name"),
@@ -94,22 +150,59 @@ initialize_yourcerts_ui (CertificateManagerData *cfm)
"text", 3,
NULL));
- cfm->yourcerts_treemodel = gtk_tree_store_new (4,
+ cfm->yourcerts_treemodel = gtk_tree_store_new (5,
+ G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_STRING,
- G_TYPE_STRING);
+ G_TYPE_OBJECT);
gtk_tree_view_set_model (GTK_TREE_VIEW (cfm->yourcerts_treeview),
GTK_TREE_MODEL (cfm->yourcerts_treemodel));
cfm->yourcerts_root_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cfm->yourcerts_treeview));
+ g_signal_connect (selection, "changed", G_CALLBACK (yourcerts_selection_changed), cfm);
+
+ if (cfm->import_your_button) {
+ /* g_signal_connect */
+ }
+
+ if (cfm->delete_your_button) {
+ /* g_signal_connect */
+ }
+
+ if (cfm->view_your_button) {
+ /* g_signal_connect */
+ }
+
+ if (cfm->backup_your_button) {
+ /* g_signal_connect */
+ }
+
+ if (cfm->backup_all_your_button) {
+ /* g_signal_connect */
+ }
+}
+
+static void
+contactcerts_selection_changed (GtkTreeSelection *selection, CertificateManagerData *cfm)
+{
+#if 0
+ handle_selection_changed (gtk_tree_view_get_selection (GTK_TREE_VIEW(cfm->contactcerts_treeview)),
+ 1 /* XXX */,
+ NULL,
+ NULL,
+ NULL);
+#endif
}
static void
initialize_contactcerts_ui (CertificateManagerData *cfm)
{
GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
+ GtkTreeSelection *selection;
gtk_tree_view_append_column (GTK_TREE_VIEW (cfm->contactcerts_treeview),
gtk_tree_view_column_new_with_attributes (_("Certificate Name"),
@@ -132,12 +225,16 @@ initialize_contactcerts_ui (CertificateManagerData *cfm)
cfm->contactcerts_treemodel = gtk_tree_store_new (3,
G_TYPE_STRING,
G_TYPE_STRING,
- G_TYPE_STRING);
+ G_TYPE_STRING,
+ G_TYPE_OBJECT);
gtk_tree_view_set_model (GTK_TREE_VIEW (cfm->contactcerts_treeview),
GTK_TREE_MODEL (cfm->contactcerts_treemodel));
cfm->contactcerts_root_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cfm->contactcerts_treeview));
+ g_signal_connect (selection, "changed", G_CALLBACK (contactcerts_selection_changed), cfm);
}
static gint
@@ -160,9 +257,84 @@ iter_string_compare (GtkTreeModel *model,
}
static void
+import_ca (GtkWidget *widget, CertificateManagerData *cfm)
+{
+ GtkWidget *filesel = gtk_file_selection_new (_("Select a cert to import..."));
+
+ if (GTK_RESPONSE_OK == gtk_dialog_run (GTK_DIALOG (filesel))) {
+ const char *filename = gtk_file_selection_get_filename (GTK_FILE_SELECTION (filesel));
+
+ if (e_cert_db_import_certs_from_file (e_cert_db_peek (),
+ filename,
+ E_CERT_CA,
+ NULL)) {
+
+ /* there's no telling how many certificates were added during the import,
+ so we blow away the CA cert display and regenerate it. */
+ unload_certs (cfm, E_CERT_CA);
+ load_certs (cfm, E_CERT_CA, add_ca_cert);
+ }
+ }
+
+ gtk_widget_destroy (filesel);
+}
+
+static void
+delete_ca (GtkWidget *widget, CertificateManagerData *cfm)
+{
+ GtkTreeIter iter;
+
+ if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW(cfm->authoritycerts_treeview)),
+ NULL,
+ &iter)) {
+ ECert *cert;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (cfm->authoritycerts_treemodel),
+ &iter,
+ 1, &cert,
+ -1);
+
+ if (cert) {
+ printf ("DELETE\n");
+ e_cert_db_delete_cert (e_cert_db_peek (), cert);
+ gtk_tree_store_remove (cfm->authoritycerts_treemodel,
+ &iter);
+
+ /* we need two unrefs here, one to unref the
+ gtk_tree_model_get above, and one to unref
+ the initial ref when we created the cert
+ and added it to the tree */
+ g_object_unref (cert);
+ g_object_unref (cert);
+ }
+ }
+
+}
+
+static void
+authoritycerts_selection_changed (GtkTreeSelection *selection, CertificateManagerData *cfm)
+{
+ handle_selection_changed (gtk_tree_view_get_selection (GTK_TREE_VIEW(cfm->authoritycerts_treeview)),
+ 1,
+ cfm->view_ca_button,
+ cfm->edit_ca_button,
+ cfm->delete_ca_button);
+}
+
+static GtkTreeStore*
+create_authoritycerts_treemodel (void)
+{
+ return gtk_tree_store_new (2,
+ G_TYPE_STRING,
+ G_TYPE_OBJECT);
+
+}
+
+static void
initialize_authoritycerts_ui (CertificateManagerData *cfm)
{
GtkCellRenderer *cell = gtk_cell_renderer_text_new ();
+ GtkTreeSelection *selection;
gtk_tree_view_append_column (GTK_TREE_VIEW (cfm->authoritycerts_treeview),
gtk_tree_view_column_new_with_attributes (_("Certificate Name"),
@@ -170,9 +342,6 @@ initialize_authoritycerts_ui (CertificateManagerData *cfm)
"text", 0,
NULL));
- cfm->authoritycerts_treemodel = gtk_tree_store_new (1,
- G_TYPE_STRING);
-
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (cfm->authoritycerts_treemodel),
0,
iter_string_compare, NULL, NULL);
@@ -181,35 +350,22 @@ initialize_authoritycerts_ui (CertificateManagerData *cfm)
0,
GTK_SORT_ASCENDING);
- gtk_tree_view_set_model (GTK_TREE_VIEW (cfm->authoritycerts_treeview),
- GTK_TREE_MODEL (cfm->authoritycerts_treemodel));
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (cfm->authoritycerts_treeview));
+ g_signal_connect (selection, "changed", G_CALLBACK (authoritycerts_selection_changed), cfm);
- cfm->authoritycerts_root_hash = g_hash_table_new (g_str_hash, g_str_equal);
-}
-
-static CertType
-get_cert_type (ECert *cert)
-{
- const char *nick = e_cert_get_nickname (cert);
- const char *email = e_cert_get_email (cert);
+ if (cfm->import_ca_button)
+ g_signal_connect (cfm->import_ca_button, "clicked", G_CALLBACK (import_ca), cfm);
- if (e_cert_is_ca_cert (cert))
- return CA_CERT;
-
- /* XXX more stuff in here */
- else
- return USER_CERT;
+ if (cfm->delete_ca_button)
+ g_signal_connect (cfm->delete_ca_button, "clicked", G_CALLBACK (delete_ca), cfm);
}
-typedef void (*AddCertCb)(CertificateManagerData *cfm, ECert *cert);
-
static void
add_user_cert (CertificateManagerData *cfm, ECert *cert)
{
GtkTreeIter iter;
GtkTreeIter *parent_iter = NULL;
const char *organization = e_cert_get_org (cert);
- const char *common_name;
if (organization) {
parent_iter = g_hash_table_lookup (cfm->yourcerts_root_hash, organization);
@@ -229,14 +385,16 @@ add_user_cert (CertificateManagerData *cfm, ECert *cert)
gtk_tree_store_append (GTK_TREE_STORE (cfm->yourcerts_treemodel), &iter, parent_iter);
- common_name = e_cert_get_cn (cert);
- if (common_name) {
+ if (e_cert_get_cn (cert))
gtk_tree_store_set (GTK_TREE_STORE (cfm->yourcerts_treemodel), &iter,
- 0, common_name, -1);
- }
+ 0, e_cert_get_cn (cert),
+ 4, cert,
+ -1);
else
gtk_tree_store_set (GTK_TREE_STORE (cfm->yourcerts_treemodel), &iter,
- 0, e_cert_get_nickname (cert), -1);
+ 0, e_cert_get_nickname (cert),
+ 4, cert,
+ -1);
}
static void
@@ -251,7 +409,6 @@ add_ca_cert (CertificateManagerData *cfm, ECert *cert)
GtkTreeIter iter;
GtkTreeIter *parent_iter = NULL;
const char *organization = e_cert_get_org (cert);
- const char *common_name;
if (organization) {
parent_iter = g_hash_table_lookup (cfm->authoritycerts_root_hash, organization);
@@ -272,19 +429,60 @@ add_ca_cert (CertificateManagerData *cfm, ECert *cert)
gtk_tree_store_append (GTK_TREE_STORE (cfm->authoritycerts_treemodel), &iter, parent_iter);
- common_name = e_cert_get_cn (cert);
- if (common_name) {
+ if (e_cert_get_cn (cert))
gtk_tree_store_set (GTK_TREE_STORE (cfm->authoritycerts_treemodel), &iter,
- 0, common_name, -1);
- }
+ 0, e_cert_get_cn (cert),
+ 1, cert,
+ -1);
else
gtk_tree_store_set (GTK_TREE_STORE (cfm->authoritycerts_treemodel), &iter,
- 0, e_cert_get_nickname (cert), -1);
+ 0, e_cert_get_nickname (cert),
+ 1, cert,
+ -1);
+}
+
+static void
+destroy_key (gpointer data)
+{
+ g_free (data);
+}
+
+static void
+destroy_value (gpointer data)
+{
+ gtk_tree_iter_free (data);
+}
+
+static void
+unload_certs (CertificateManagerData *cfm,
+ ECertType type)
+{
+ switch (type) {
+ case E_CERT_USER:
+ break;
+ case E_CERT_CONTACT:
+ break;
+ case E_CERT_SITE:
+ break;
+ case E_CERT_CA:
+ cfm->authoritycerts_treemodel = create_authoritycerts_treemodel ();
+ gtk_tree_view_set_model (GTK_TREE_VIEW (cfm->authoritycerts_treeview),
+ GTK_TREE_MODEL (cfm->authoritycerts_treemodel));
+
+ if (cfm->authoritycerts_root_hash)
+ g_hash_table_destroy (cfm->authoritycerts_root_hash);
+
+ cfm->authoritycerts_root_hash = g_hash_table_new_full (g_str_hash, g_str_equal,
+ destroy_key, destroy_value);
+
+
+ break;
+ }
}
static void
load_certs (CertificateManagerData *cfm,
- CertType type,
+ ECertType type,
AddCertCb add_cert)
{
CERTCertList *certList;
@@ -298,11 +496,10 @@ load_certs (CertificateManagerData *cfm,
!CERT_LIST_END(node, certList);
node = CERT_LIST_NEXT(node)) {
ECert *cert = e_cert_new ((CERTCertificate*)node->cert);
- if (get_cert_type(cert) == type) {
+ if (e_cert_get_cert_type(cert) == type) {
printf ("cert (nickname = '%s') matches\n", e_cert_get_nickname (cert));
add_cert (cfm, cert);
}
- /* XXX we leak cert */
}
}
@@ -310,9 +507,14 @@ load_certs (CertificateManagerData *cfm,
static void
populate_ui (CertificateManagerData *cfm)
{
- load_certs (cfm, USER_CERT, add_user_cert);
- load_certs (cfm, CONTACT_CERT, add_contact_cert);
- load_certs (cfm, CA_CERT, add_ca_cert);
+ unload_certs (cfm, E_CERT_USER);
+ load_certs (cfm, E_CERT_USER, add_user_cert);
+
+ unload_certs (cfm, E_CERT_CONTACT);
+ load_certs (cfm, E_CERT_CONTACT, add_contact_cert);
+
+ unload_certs (cfm, E_CERT_CA);
+ load_certs (cfm, E_CERT_CA, add_ca_cert);
}
EvolutionConfigControl*
@@ -321,10 +523,8 @@ certificate_manager_config_control_new (void)
CertificateManagerData *cfm_data;
GtkWidget *control_widget;
- /* XXX this should happen someplace else, and shouldn't
- reference my default mozilla profile :) */
- if (SECSuccess != NSS_InitReadWrite ("/home/toshok/.mozilla/default/xuvq7jx3.slt"))
- return NULL;
+ /* We need to peek the db here to make sure it (and NSS) are fully initialized. */
+ e_cert_db_peek ();
cfm_data = g_new0 (CertificateManagerData, 1);
cfm_data->gui = glade_xml_new (EVOLUTION_GLADEDIR "/" GLADE_FILE_NAME, NULL, NULL);
@@ -333,6 +533,17 @@ certificate_manager_config_control_new (void)
cfm_data->contactcerts_treeview = glade_xml_get_widget (cfm_data->gui, "contactcerts-treeview");
cfm_data->authoritycerts_treeview = glade_xml_get_widget (cfm_data->gui, "authoritycerts-treeview");
+ cfm_data->view_your_button = glade_xml_get_widget (cfm_data->gui, "your-view-button");
+ cfm_data->backup_your_button = glade_xml_get_widget (cfm_data->gui, "your-backup-button");
+ cfm_data->backup_all_your_button = glade_xml_get_widget (cfm_data->gui, "your-backup-all-button");
+ cfm_data->import_your_button = glade_xml_get_widget (cfm_data->gui, "your-import-button");
+ cfm_data->delete_your_button = glade_xml_get_widget (cfm_data->gui, "your-delete-button");
+
+ cfm_data->view_ca_button = glade_xml_get_widget (cfm_data->gui, "authority-view-button");
+ cfm_data->edit_ca_button = glade_xml_get_widget (cfm_data->gui, "authority-edit-button");
+ cfm_data->import_ca_button = glade_xml_get_widget (cfm_data->gui, "authority-import-button");
+ cfm_data->delete_ca_button = glade_xml_get_widget (cfm_data->gui, "authority-delete-button");
+
initialize_yourcerts_ui(cfm_data);
initialize_contactcerts_ui(cfm_data);
initialize_authoritycerts_ui(cfm_data);