aboutsummaryrefslogtreecommitdiffstats
path: root/smime/gui/e-cert-selector.c
diff options
context:
space:
mode:
Diffstat (limited to 'smime/gui/e-cert-selector.c')
-rw-r--r--smime/gui/e-cert-selector.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/smime/gui/e-cert-selector.c b/smime/gui/e-cert-selector.c
index e69de29bb2..b3fcabdc43 100644
--- a/smime/gui/e-cert-selector.c
+++ b/smime/gui/e-cert-selector.c
@@ -0,0 +1,247 @@
+
+/* Copyright 2003, Novell Inc.
+ *
+ * Author(s): Michael Zucchi <notzed@ximian.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * 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.
+ */
+
+#include <libgnome/gnome-i18n.h>
+
+#include <gal/util/e-util.h>
+
+#include <gtk/gtktextview.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkbox.h>
+#include <gtk/gtkstock.h>
+
+#include "nss.h"
+#include "pk11func.h"
+#include "certdb.h"
+#include "cert.h"
+
+#include <glade/glade.h>
+
+#include "e-cert-selector.h"
+
+struct _ECertSelectorPrivate {
+ CERTCertList *certlist;
+
+ GtkWidget *menu, *description;
+};
+
+enum {
+ ECS_SELECTED,
+ ECS_LAST_SIGNAL
+};
+
+static guint ecs_signals[ECS_LAST_SIGNAL];
+
+static GtkDialog *ecs_parent_class;
+
+/* (this is what mozilla shows)
+Issued to:
+ Subject: E=notzed@ximian.com, CN=notzed@ximian.com, O=My Company Ltd, L=Adelaide, ST=SA, C=AU
+ Serial Number: 03
+ Valid from 23/10/03 06:35:29 to 22/10/04 06:35:29
+ Purposes: Sign,Encrypt
+Issued by:
+ Subject: E=notzed@ximian.com, O=company, L=there, ST=Here, C=AU
+*/
+
+static CERTCertListNode *
+ecs_find_current(ECertSelector *ecs)
+{
+ struct _ECertSelectorPrivate *p = ecs->priv;
+ CERTCertListNode *node;
+ int n;
+
+ if (CERT_LIST_EMPTY(p->certlist))
+ return NULL;
+
+ n = gtk_option_menu_get_history((GtkOptionMenu *)p->menu);
+ node = CERT_LIST_HEAD(p->certlist);
+ while (n>0 && !CERT_LIST_END(node, p->certlist)) {
+ n--;
+ node = CERT_LIST_NEXT(node);
+ }
+
+ g_assert(!CERT_LIST_END(node, p->certlist));
+
+ return node;
+}
+
+static void
+ecs_response(GtkDialog *dialog, gint button)
+{
+ CERTCertListNode *node;
+
+ switch (button) {
+ case GTK_RESPONSE_OK:
+ node = ecs_find_current((ECertSelector *)dialog);
+ break;
+ default:
+ node = NULL;
+ break;
+ }
+
+ g_signal_emit(dialog, ecs_signals[ECS_SELECTED], 0, node?node->cert->nickname:NULL);
+}
+
+static void
+ecs_cert_changed(GtkWidget *w, ECertSelector *ecs)
+{
+ struct _ECertSelectorPrivate *p = ecs->priv;
+ CERTCertListNode *node;
+ GtkTextBuffer *buffer;
+ GString *text;
+
+ text = g_string_new("");
+ node = ecs_find_current(ecs);
+ if (node) {
+ /* FIXME: add serial no, validity date, uses */
+ g_string_append_printf(text, _("Issued to:\n Subject: %s\n"), node->cert->subjectName);
+ g_string_append_printf(text, _("Issued by:\n Subject: %s\n"), node->cert->issuerName);
+ }
+
+ buffer = gtk_text_view_get_buffer((GtkTextView *)p->description);
+ gtk_text_buffer_set_text(buffer, text->str, text->len);
+ g_string_free(text, TRUE);
+}
+
+/**
+ * e_cert_selector_new:
+ * @type:
+ * @currentid:
+ *
+ * Create a new ECertSelector dialog. @type specifies which type of cert to
+ * be selected, E_CERT_SELECTOR_SIGNER for signing certs, and
+ * E_CERT_SELECTOR_RECIPIENT for encrypting certs.
+ *
+ * @currentid is the nickname of the cert currently selected for this user.
+ *
+ * You only need to connect to a single signal "selected" which will
+ * be called with either a NULL nickname if cancelled, or the newly
+ * selected nickname otherwise.
+ *
+ * Return value: A dialogue to be shown.
+ **/
+GtkWidget *
+e_cert_selector_new(int type, const char *currentid)
+{
+ ECertSelector *ecs;
+ struct _ECertSelectorPrivate *p;
+ SECCertUsage usage;
+ CERTCertList *certlist;
+ CERTCertListNode *node;
+ GladeXML *gui;
+ GtkWidget *w, *menu;
+ int n=0, active=0;
+
+ ecs = g_object_new(e_cert_selector_get_type(), NULL);
+ p = ecs->priv;
+
+ gui = glade_xml_new(EVOLUTION_GLADEDIR "/smime-ui.glade", "cert_selector_vbox", NULL);
+
+ p->menu = glade_xml_get_widget(gui, "cert_menu");
+ p->description = glade_xml_get_widget(gui, "cert_description");
+
+ w = glade_xml_get_widget(gui, "cert_selector_vbox");
+ gtk_box_pack_start((GtkBox *)((GtkDialog *)ecs)->vbox, w, TRUE, TRUE, 3);
+
+ switch (type) {
+ case E_CERT_SELECTOR_SIGNER:
+ default:
+ usage = certUsageEmailSigner;
+ break;
+ case E_CERT_SELECTOR_RECIPIENT:
+ usage = certUsageEmailRecipient;
+ break;
+ }
+
+ menu = gtk_menu_new();
+
+ certlist = CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(), usage, FALSE, TRUE, NULL);
+ ecs->priv->certlist = certlist;
+ node = CERT_LIST_HEAD(certlist);
+ while (!CERT_LIST_END(node, certlist)) {
+ w = gtk_menu_item_new_with_label(node->cert->nickname);
+ gtk_menu_shell_append((GtkMenuShell *)menu, w);
+ gtk_widget_show(w);
+
+ if (currentid != NULL
+ && (strcmp(node->cert->nickname, currentid) == 0
+ || strcmp(node->cert->emailAddr, currentid) == 0))
+ active = n;
+
+ n++;
+ node = CERT_LIST_NEXT(node);
+ }
+
+ gtk_option_menu_set_menu((GtkOptionMenu *)p->menu, menu);
+ gtk_option_menu_set_history((GtkOptionMenu *)p->menu, active);
+
+ g_signal_connect(p->menu, "changed", G_CALLBACK(ecs_cert_changed), ecs);
+
+ g_object_unref(gui);
+
+ ecs_cert_changed(p->menu, ecs);
+
+ return GTK_WIDGET(ecs);
+}
+
+static void
+ecs_init(ECertSelector *ecs)
+{
+ gtk_dialog_add_buttons((GtkDialog *)ecs,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
+
+ ecs->priv = g_malloc0(sizeof(*ecs->priv));
+}
+
+static void
+ecs_finalise(GObject *o)
+{
+ ECertSelector *ecs = (ECertSelector *)o;
+
+ if (ecs->priv->certlist)
+ CERT_DestroyCertList(ecs->priv->certlist);
+
+ g_free(ecs->priv);
+
+ ((GObjectClass *)ecs_parent_class)->finalize(o);
+}
+
+static void
+ecs_class_init(ECertSelectorClass *klass)
+{
+ ecs_parent_class = g_type_class_ref(gtk_dialog_get_type());
+
+ ((GObjectClass *)klass)->finalize = ecs_finalise;
+ ((GtkDialogClass *)klass)->response = ecs_response;
+
+ ecs_signals[ECS_SELECTED] =
+ g_signal_new("selected",
+ G_OBJECT_CLASS_TYPE(klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET(ECertSelectorClass, selected),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__POINTER,
+ G_TYPE_NONE, 1, G_TYPE_POINTER);
+}
+
+E_MAKE_TYPE(e_cert_selector, "ECertSelector", ECertSelector, ecs_class_init, ecs_init, gtk_dialog_get_type())