changeset 19529:7af9aba79a3b

merge of 'b33c072ae9fdbe741dc85fdd8e78e3a1ad8d1378' and 'f0f42aac18e7368c6e2f6455d4e3b9aabd0c0bba'
author William Ehlhardt <williamehlhardt@gmail.com>
date Wed, 29 Aug 2007 19:18:02 +0000
parents c13f0639917d (current diff) b7fa8fa4de5b (diff)
children 82953ee5b3e6
files share/ca-certs/Verisign_Class3_Extended_Validation_CA.pem
diffstat 6 files changed, 380 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/finch/Makefile.am	Wed Aug 29 19:12:52 2007 +0000
+++ b/finch/Makefile.am	Wed Aug 29 19:18:02 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 19:18:02 2007 +0000
@@ -0,0 +1,340 @@
+/**
+ * @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 "internal.h"
+
+#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 19:18:02 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/gntrequest.c	Wed Aug 29 19:12:52 2007 +0000
+++ b/finch/gntrequest.c	Wed Aug 29 19:18:02 2007 +0000
@@ -198,7 +198,7 @@
 
 static void *
 finch_request_choice(const char *title, const char *primary,
-		const char *secondary, unsigned int default_value,
+		const char *secondary, int default_value,
 		const char *ok_text, GCallback ok_cb,
 		const char *cancel_text, GCallback cancel_cb,
 		PurpleAccount *account, const char *who, PurpleConversation *conv,
@@ -244,7 +244,7 @@
 
 static void*
 finch_request_action(const char *title, const char *primary,
-		const char *secondary, unsigned int default_value,
+		const char *secondary, int default_value,
 		PurpleAccount *account, const char *who, PurpleConversation *conv,
 		void *user_data, size_t actioncount,
 		va_list actions)
--- a/finch/gntui.c	Wed Aug 29 19:12:52 2007 +0000
+++ b/finch/gntui.c	Wed Aug 29 19:18:02 2007 +0000
@@ -25,6 +25,7 @@
 
 #include "gntaccount.h"
 #include "gntblist.h"
+#include "gntcertmgr.h"
 #include "gntconn.h"
 #include "gntconv.h"
 #include "gntdebug.h"
@@ -81,6 +82,7 @@
 	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);
--- a/libpurple/certificate.c	Wed Aug 29 19:12:52 2007 +0000
+++ b/libpurple/certificate.c	Wed Aug 29 19:18:02 2007 +0000
@@ -30,6 +30,7 @@
 
 #include "internal.h"
 #include "certificate.h"
+#include "dbus-maybe.h"
 #include "debug.h"
 #include "request.h"
 #include "signals.h"
@@ -1712,6 +1713,7 @@
 
 		/* TODO: Emit a signal that the pool got registered */
 
+		PURPLE_DBUS_REGISTER_POINTER(pool, PurpleCertificatePool);
 		purple_signal_register(pool, /* Signals emitted from pool */
 				       "certificate-stored",
 				       purple_marshal_VOID__POINTER_POINTER,
@@ -1760,6 +1762,7 @@
 	}
 
 	/* Uninit the pool if needed */
+	PURPLE_DBUS_UNREGISTER_POINTER(pool);
 	if (pool->uninit) {
 		pool->uninit();
 	}
@@ -1831,6 +1834,3 @@
 	g_byte_array_free(sha_bin, TRUE);
 }
 
-
-
-