changeset 19516:e1751162ab1f

Add certificate UI in finch.
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Wed, 29 Aug 2007 05:18:39 +0000
parents b62683f4120d
children 7bea9c9fd2a5
files finch/Makefile.am finch/gntcertmgr.c finch/gntcertmgr.h finch/gntui.c
diffstat 4 files changed, 375 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/finch/Makefile.am	Tue Aug 28 21:17:28 2007 +0000
+++ b/finch/Makefile.am	Wed Aug 29 05:18:39 2007 +0000
@@ -14,6 +14,7 @@
 finch_SOURCES = \
 	gntaccount.c \
 	gntblist.c \
+	gntcertmgr.c \
 	gntconn.c \
 	gntconv.c \
 	gntdebug.c \
@@ -32,6 +33,7 @@
 finch_headers = \
 	gntaccount.h \
 	gntblist.h \
+	gntcertmgr.h \
 	gntconn.h \
 	gntconv.h \
 	gntdebug.h \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/finch/gntcertmgr.c	Wed Aug 29 05:18:39 2007 +0000
@@ -0,0 +1,338 @@
+/**
+ * @file gntcertmgr.c GNT Certificate Manager API
+ * @ingroup finch
+ *
+ * finch
+ *
+ * Finch is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 of the License, 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
+ *
+ */
+
+#include "certificate.h"
+#include "debug.h"
+#include "notify.h"
+#include "request.h"
+
+#include "finch.h"
+#include "gntcertmgr.h"
+
+#include "gntbutton.h"
+#include "gntlabel.h"
+#include "gnttree.h"
+#include "gntutils.h"
+#include "gntwindow.h"
+
+struct {
+	GntWidget *window;
+	GntWidget *tree;
+	PurpleCertificatePool *pool;
+} certmgr;
+
+/* Pretty much Xerox of gtkcertmgr */
+
+/* Add certificate */
+static void
+tls_peers_mgmt_import_ok2_cb(gpointer data, const char *result)
+{
+	PurpleCertificate *crt = (PurpleCertificate *) data;
+	const char *id = result;
+
+	/* TODO: Perhaps prompt if you're overwriting a cert? */
+
+	purple_certificate_pool_store(purple_certificate_find_pool("x509", "tls_peers"), id, crt);
+	purple_certificate_destroy(crt);
+}
+
+static void
+tls_peers_mgmt_import_cancel2_cb(gpointer data, const char *result)
+{
+	PurpleCertificate *crt = (PurpleCertificate *) data;
+	purple_certificate_destroy(crt);
+}
+
+static void
+tls_peers_mgmt_import_ok_cb(gpointer data, const char *filename)
+{
+	PurpleCertificateScheme *x509;
+	PurpleCertificate *crt;
+
+	x509 = purple_certificate_pool_get_scheme(purple_certificate_find_pool("x509", "tls_peers"));
+
+	crt = purple_certificate_import(x509, filename);
+
+	if (crt != NULL) {
+		gchar *default_hostname;
+		default_hostname = purple_certificate_get_subject_name(crt);
+		purple_request_input(NULL,
+				_("Certificate Import"),
+				_("Specify a hostname"),
+				_("Type the host name this certificate is for."),
+				default_hostname, FALSE, FALSE, NULL,
+				_("OK"), G_CALLBACK(tls_peers_mgmt_import_ok2_cb),
+				_("Cancel"), G_CALLBACK(tls_peers_mgmt_import_cancel2_cb),
+				NULL, NULL, NULL,
+				crt);
+		g_free(default_hostname);
+	} else {
+		gchar * secondary;
+		secondary = g_strdup_printf(_("File %s could not be imported.\nMake sure that the file is readable and in PEM format.\n"), filename);
+		purple_notify_error(NULL,
+				_("Certificate Import Error"),
+				_("X.509 certificate import failed"),
+				secondary);
+		g_free(secondary);
+	}
+}
+
+static void
+add_cert_cb(GntWidget *button, gpointer null)
+{
+	purple_request_file(NULL,
+			_("Select a PEM certificate"),
+			"certificate.pem",
+			FALSE,
+			G_CALLBACK(tls_peers_mgmt_import_ok_cb),
+			NULL,
+			NULL, NULL, NULL, NULL );
+}
+
+/* Save certs in some file */
+static void
+tls_peers_mgmt_export_ok_cb(gpointer data, const char *filename)
+{
+	PurpleCertificate *crt = (PurpleCertificate *) data;
+
+	if (!purple_certificate_export(filename, crt)) {
+		gchar * secondary;
+
+		secondary = g_strdup_printf(_("Export to file %s failed.\nCheck that you have write permission to the target path\n"), filename);
+		purple_notify_error(NULL,
+				    _("Certificate Export Error"),
+				    _("X.509 certificate export failed"),
+				    secondary);
+		g_free(secondary);
+	}
+
+	purple_certificate_destroy(crt);
+}
+
+static void
+save_cert_cb(GntWidget *button, gpointer null)
+{
+	PurpleCertificate *crt;
+	const char *key;
+
+	if (!certmgr.window)
+		return;
+
+	key = gnt_tree_get_selection_data(GNT_TREE(certmgr.tree));
+	if (!key)
+		return;
+
+	crt = purple_certificate_pool_retrieve(certmgr.pool, key);
+	if (!crt) {
+		purple_debug_error("gntcertmgr/tls_peers_mgmt",
+				"Id %s was not in the peers cache?!\n", key);
+		return;
+	}
+
+	purple_request_file((void*)key,
+			_("PEM X.509 Certificate Export"),
+			"certificate.pem", TRUE,
+			G_CALLBACK(tls_peers_mgmt_export_ok_cb),
+			G_CALLBACK(purple_certificate_destroy),
+			NULL, NULL, NULL,
+			crt);
+}
+
+/* Show information about a cert */
+static void
+info_cert_cb(GntWidget *button, gpointer null)
+{
+	const char *key;
+	PurpleCertificate *crt;
+	gchar *subject;
+	GByteArray *fpr_sha1;
+	gchar *fpr_sha1_asc;
+	gchar *primary, *secondary;
+
+	if (!certmgr.window)
+		return;
+
+	key = gnt_tree_get_selection_data(GNT_TREE(certmgr.tree));
+	if (!key)
+		return;
+
+	crt = purple_certificate_pool_retrieve(certmgr.pool, key);
+	g_return_if_fail(crt);
+
+	primary = g_strdup_printf(_("Certificate for %s"), key);
+
+	fpr_sha1 = purple_certificate_get_fingerprint_sha1(crt);
+	fpr_sha1_asc = purple_base16_encode_chunked(fpr_sha1->data,
+						    fpr_sha1->len);
+	subject = purple_certificate_get_subject_name(crt);
+
+	secondary = g_strdup_printf(_("Common name: %s\n\nSHA1 fingerprint:\n%s"), subject, fpr_sha1_asc);
+	
+	purple_notify_info(NULL,
+			   _("SSL Host Certificate"), primary, secondary);
+
+	g_free(primary);
+	g_free(secondary);
+	g_byte_array_free(fpr_sha1, TRUE);
+	g_free(fpr_sha1_asc);
+	g_free(subject);
+	purple_certificate_destroy(crt);
+}
+
+/* Delete a cert */
+static void
+tls_peers_mgmt_delete_confirm_cb(gchar *id, gint dontcare)
+{
+	if (!purple_certificate_pool_delete(certmgr.pool, id)) {
+		purple_debug_warning("gntcertmgr/tls_peers_mgmt",
+				"Deletion failed on id %s\n", id);
+	};
+
+	g_free(id);
+}
+
+static void
+delete_cert_cb(GntWidget *button, gpointer null)
+{
+	gchar *primary;
+	const char *key;
+
+	if (!certmgr.window)
+		return;
+
+	key = gnt_tree_get_selection_data(GNT_TREE(certmgr.tree));
+	if (!key)
+		return;
+
+	primary = g_strdup_printf(_("Really delete certificate for %s?"), key);
+
+	purple_request_close_with_handle((void *)key);
+	purple_request_yes_no((void *)key, _("Confirm certificate delete"),
+			primary, NULL,
+			2,
+			NULL, NULL, NULL,
+			g_strdup(key),
+			tls_peers_mgmt_delete_confirm_cb,
+			g_free);
+
+	g_free(primary);
+}
+
+/* populate the list */
+static void
+populate_cert_list()
+{
+	GList *idlist, *l;
+
+	if (!certmgr.window)
+		return;
+
+	gnt_tree_remove_all(GNT_TREE(certmgr.tree));
+
+	idlist = purple_certificate_pool_get_idlist(purple_certificate_find_pool("x509", "tls_peers"));
+	for (l = idlist; l; l = l->next) {
+		gnt_tree_add_row_last(GNT_TREE(certmgr.tree), g_strdup(l->data),
+				gnt_tree_create_row(GNT_TREE(certmgr.tree), l->data), NULL);
+	}
+	purple_certificate_pool_destroy_idlist(idlist);
+}
+
+static void
+cert_list_added(PurpleCertificatePool *pool, const char *id, gpointer null)
+{
+	g_return_if_fail(certmgr.window);
+	gnt_tree_add_row_last(GNT_TREE(certmgr.tree), g_strdup(id),
+			gnt_tree_create_row(GNT_TREE(certmgr.tree), id), NULL);
+}
+
+static void
+cert_list_removed(PurpleCertificatePool *pool, const char *id, gpointer null)
+{
+	g_return_if_fail(certmgr.window);
+	purple_request_close_with_handle((void*)id);
+	gnt_tree_remove(GNT_TREE(certmgr.tree), (void*)id);
+}
+
+void finch_certmgr_show(void)
+{
+	GntWidget *win, *tree, *box, *button;
+	PurpleCertificatePool *pool;
+
+	if (certmgr.window) {
+		gnt_window_present(certmgr.window);
+		return;
+	}
+
+	certmgr.window = win = gnt_vwindow_new(FALSE);
+	gnt_box_set_title(GNT_BOX(win), _("Certificate Manager"));
+	gnt_box_set_pad(GNT_BOX(win), 0);
+
+	certmgr.tree = tree = gnt_tree_new();
+	gnt_tree_set_hash_fns(GNT_TREE(tree), g_str_hash, g_str_equal, g_free);
+	gnt_tree_set_column_title(GNT_TREE(tree), 0, _("Hostname"));
+	gnt_tree_set_show_title(GNT_TREE(tree), TRUE);
+
+	gnt_box_add_widget(GNT_BOX(win), tree);
+
+	box = gnt_hbox_new(FALSE);
+	gnt_box_add_widget(GNT_BOX(win), box);
+
+	button = gnt_button_new(_("Add"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(add_cert_cb), NULL);
+	gnt_util_set_trigger_widget(GNT_WIDGET(tree), GNT_KEY_INS, button);
+
+	button = gnt_button_new(_("Save"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(save_cert_cb), NULL);
+
+	button = gnt_button_new(_("Info"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(info_cert_cb), NULL);
+
+	button = gnt_button_new(_("Delete"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(delete_cert_cb), NULL);
+	gnt_util_set_trigger_widget(GNT_WIDGET(tree), GNT_KEY_DEL, button);
+
+	button = gnt_button_new(_("Close"));
+	gnt_box_add_widget(GNT_BOX(box), button);
+	g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), win);
+
+	g_signal_connect_swapped(G_OBJECT(win), "destroy", G_CALLBACK(g_nullify_pointer), &certmgr.window);
+
+	populate_cert_list();
+
+	pool = certmgr.pool = purple_certificate_find_pool("x509", "tls_peers");
+	purple_signal_connect(pool, "certificate-stored",
+			      win, PURPLE_CALLBACK(cert_list_added), NULL);
+	purple_signal_connect(pool, "certificate-deleted",
+			      win, PURPLE_CALLBACK(cert_list_removed), NULL);
+	g_signal_connect(G_OBJECT(win), "destroy", G_CALLBACK(purple_signals_disconnect_by_handle), NULL);
+
+	gnt_widget_show(certmgr.window);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/finch/gntcertmgr.h	Wed Aug 29 05:18:39 2007 +0000
@@ -0,0 +1,31 @@
+/**
+ * @file gntcertmgr.h GNT Certificate Manager API
+ * @ingroup finch
+ *
+ * finch
+ *
+ * Finch is the legal property of its developers, whose names are too numerous
+ * to list here.  Please refer to the COPYRIGHT file distributed with this
+ * source distribution.
+ *
+ * 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 of the License, 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
+ *
+ */
+#ifndef _GNT_CERTMGR_H
+#define _GNT_CERTMGR_H
+
+void finch_certmgr_show(void);
+
+#endif
--- a/finch/gntui.c	Tue Aug 28 21:17:28 2007 +0000
+++ b/finch/gntui.c	Wed Aug 29 05:18:39 2007 +0000
@@ -25,6 +25,7 @@
 
 #include "gntaccount.h"
 #include "gntblist.h"
+#include "gntcertmgr.h"
 #include "gntconn.h"
 #include "gntconv.h"
 #include "gntdebug.h"
@@ -37,6 +38,7 @@
 #include "gntstatus.h"
 #include "gntsound.h"
 
+#include <dbus-server.h>
 #include <prefs.h>
 
 void gnt_ui_init()
@@ -81,12 +83,14 @@
 	gnt_register_action(_("Accounts"), finch_accounts_show_all);
 	gnt_register_action(_("Buddy List"), finch_blist_show);
 	gnt_register_action(_("Buddy Pounces"), finch_pounces_manager_show);
+	gnt_register_action(_("Certificates"), finch_certmgr_show);
 	gnt_register_action(_("Debug Window"), finch_debug_window_show);
 	gnt_register_action(_("File Transfers"), finch_xfer_dialog_show);
 	gnt_register_action(_("Plugins"), finch_plugins_show_all);
 	gnt_register_action(_("Sounds"), finch_sounds_show_all);
 	gnt_register_action(_("Preferences"), finch_prefs_show_all);
 	gnt_register_action(_("Statuses"), finch_savedstatus_show_all);
+	gnt_register_action("Disable Dbus", purple_dbus_uninit);
 
 #ifdef STANDALONE