cpw.ljfisher.ssl_client_auth: 906cc67e: Add login certificate chooser to XMPP ac...

lucas.fisher at gmail.com lucas.fisher at gmail.com
Sun Jul 24 22:50:47 EDT 2011


----------------------------------------------------------------------
Revision: 906cc67e1639e90b18e45725f0fceab926547f25
Parent:   3e73c3929c1826549d70f7dc0d20212b9e8d3652
Author:   lucas.fisher at gmail.com
Date:     07/24/11 22:45:35
Branch:   im.pidgin.cpw.ljfisher.ssl_client_auth
URL: http://d.pidgin.im/viewmtn/revision/info/906cc67e1639e90b18e45725f0fceab926547f25

Changelog: 

Add login certificate chooser to XMPP account options.
prpl.h: Add get_account_options() to PurplePluginProtocolInfo
jabber.h: Add jabber_get_account_options() prototype
jabber.c: Get certificat_id from account settings instead of from PurpleAccount certificate_id field
account.c: Comment out account certificate_id setter/getter since we don't need; add purple_account_get_options()
account.h: Comment out account certificate_id related definitions; add purple_account_get_options()
gtkaccount.c: Use purple_account_get_options() instead of PurplePluginProtocolInfo.protocol_options
libxmpp.c: Move creating of account options from init_plugin() to get_account_options()

Changes against parent 3e73c3929c1826549d70f7dc0d20212b9e8d3652

  patched  libpurple/account.c
  patched  libpurple/account.h
  patched  libpurple/protocols/jabber/jabber.c
  patched  libpurple/protocols/jabber/jabber.h
  patched  libpurple/protocols/jabber/libxmpp.c
  patched  libpurple/prpl.h
  patched  pidgin/gtkaccount.c

-------------- next part --------------
============================================================
--- libpurple/prpl.h	00ddff21fbb760369b95f999cb7ead428862bfb2
+++ libpurple/prpl.h	6652647d4e7ac99128ef4530822f521e7588f282
@@ -210,7 +210,6 @@ typedef enum
 	 * @since 2.8.0
 	 */
 	OPT_PROTO_INVITE_MESSAGE = 0x00000800
-
 } PurpleProtocolOptions;
 
 /**
@@ -647,6 +646,18 @@ struct _PurplePluginProtocolInfo
 	 */
 	void (*add_buddy_with_invite)(PurpleConnection *pc, PurpleBuddy *buddy, PurpleGroup *group, const char *message);
 	void (*add_buddies_with_invite)(PurpleConnection *pc, GList *buddies, GList *groups, const char *message);
+	
+	/**
+	 * Get account options for this protocol. Allows dynamic generation
+	 * of account options or values. Either this or protocol_options (above) should be
+	 * used. It should update protocol_options field with the new list when called.
+	 * Yes, we could call this updateAccountOptions, but it would be nice to move
+	 * away from just a field to a field getter.
+         *
+         * @returns GList of PurpleAccountOption
+	 */
+	GList *(*get_account_options)();
+
 };
 
 #define PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl, member) \
============================================================
--- libpurple/protocols/jabber/jabber.c	502edd564948c65d85032a4af668c89608e12c23
+++ libpurple/protocols/jabber/jabber.c	1630f7d573c13db8d71b9139429bd5d42474ee5f
@@ -851,9 +851,14 @@ static void tls_init(JabberStream *js)
 {
 	purple_input_remove(js->gc->inpa);
 	js->gc->inpa = 0;
-	js->gsc = purple_ssl_connect_with_host_fd_auth(js->gc->account, js->fd,
-			jabber_login_callback_ssl, jabber_ssl_connect_failure, 
-			js->certificate_CN, js->gc->account->certificate_id, js->gc);
+	js->gsc = purple_ssl_connect_with_host_fd_auth(
+			js->gc->account,
+			js->fd,
+			jabber_login_callback_ssl,
+			jabber_ssl_connect_failure, 
+			js->certificate_CN,
+			purple_account_get_string(js->gc->account, "certificate_id", NULL),
+			js->gc);
 	/* The fd is no longer our concern */
 	js->fd = -1;
 }
@@ -1050,10 +1055,15 @@ jabber_stream_connect(JabberStream *js)
 	/* if they've got old-ssl mode going, we probably want to ignore SRV lookups */
 	if (g_str_equal("old_ssl", purple_account_get_string(account, "connection_security", JABBER_DEFAULT_REQUIRE_TLS))) {
 		if(purple_ssl_is_supported()) {
-			js->gsc = purple_ssl_connect_with_ssl_cn_auth(account, js->certificate_CN,
+			js->gsc = purple_ssl_connect_with_ssl_cn_auth(
+					account,
+					js->certificate_CN,
 					purple_account_get_int(account, "port", 5223),
-					jabber_login_callback_ssl, jabber_ssl_connect_failure,
-					NULL, account->certificate_id, gc);
+					jabber_login_callback_ssl,
+					jabber_ssl_connect_failure,
+					NULL,
+					purple_account_get_string(account, "certificate_id", NULL),
+					gc);
 			if (!js->gsc) {
 				purple_connection_error_reason(gc,
 					PURPLE_CONNECTION_ERROR_NO_SSL_SUPPORT,
============================================================
--- libpurple/protocols/jabber/jabber.h	4886d45526932fb189a96ac9ce60e4268952b8de
+++ libpurple/protocols/jabber/jabber.h	7bf436855be2ac71dd40b6637b2885556e1cd935
@@ -416,6 +416,7 @@ gboolean jabber_can_receive_file(PurpleC
 		PurpleMediaSessionType type);
 PurpleMediaCaps jabber_get_media_caps(PurpleAccount *account, const char *who);
 gboolean jabber_can_receive_file(PurpleConnection *gc, const gchar *who);
+GList* jabber_get_account_options();
 
 void jabber_plugin_init(PurplePlugin *plugin);
 void jabber_plugin_uninit(PurplePlugin *plugin);
============================================================
--- libpurple/account.c	72fcf4641395d400d22857465e7d3b6866b9a2fa
+++ libpurple/account.c	01964da0ec06d278bf1b7089e852bfce684001af
@@ -382,12 +382,14 @@ account_to_xmlnode(PurpleAccount *accoun
 		xmlnode_insert_data(child, tmp, -1);
 	}
 
+#if 0
+	/* XXX ljf remove */
 	if ((tmp = purple_account_get_certificate_id(account)) != NULL)
 	{
 		child = xmlnode_new_child(node, "certificateid");
 		xmlnode_insert_data(child, tmp, -1);
 	}
-
+#endif
 	if ((tmp = purple_account_get_alias(account)) != NULL)
 	{
 		child = xmlnode_new_child(node, "alias");
@@ -890,6 +892,8 @@ parse_account(xmlnode *node)
 		g_free(data);
 	}
 
+#if 0
+	/* XXX ljf remove */
 	/* Read the certificate id */
 	child = xmlnode_get_child(node, "certificateid");
 	purple_debug_info("account", "crt id field from accounts.xml: %p\n", child);
@@ -898,7 +902,7 @@ parse_account(xmlnode *node)
 		purple_account_set_certificate_id(ret, data);
 		g_free(data);
 	}
-
+#endif
 	/* Read the alias */
 	child = xmlnode_get_child(node, "alias");
 	if ((child != NULL) && ((data = xmlnode_get_data(child)) != NULL))
@@ -997,6 +1001,7 @@ load_accounts(void)
 	xmlnode_free(node);
 
 	_purple_buddy_icons_account_loaded_cb();
+
 }
 
 
@@ -1664,19 +1669,24 @@ purple_account_set_password(PurpleAccoun
 	schedule_accounts_save();
 }
 
-
+#if 0
+/* XXX ljf */
 void
 purple_account_set_certificate_id(PurpleAccount *account, const char *id)
 {
 	purple_debug_info("account", "Set certificate_id = %s\n", id);
 	g_return_if_fail(account != NULL);
 
+	if (g_strcmp0(id, "None")) {
+		id = NULL;
+	}
+
 	g_free(account->certificate_id);
 	account->certificate_id = g_strdup(id);
 
 	schedule_accounts_save();
 }
-
+#endif
 void
 purple_account_set_alias(PurpleAccount *account, const char *alias)
 {
@@ -2188,7 +2198,7 @@ purple_account_get_password(const Purple
 
 	return account->password;
 }
-
+#if 0 /* XXX ljf */
 const char *
 purple_account_get_certificate_id(const PurpleAccount *account)
 {
@@ -2196,7 +2206,7 @@ purple_account_get_certificate_id(const 
 
 	return account->certificate_id;
 }
-
+#endif
 const char *
 purple_account_get_alias(const PurpleAccount *account)
 {
@@ -2559,6 +2569,18 @@ purple_account_destroy_log(PurpleAccount
 	}
 }
 
+GList*
+purple_account_get_options(PurplePluginProtocolInfo *prpl_info)
+{
+	g_return_val_if_fail(prpl_info != NULL, NULL);
+
+
+	if (PURPLE_PROTOCOL_PLUGIN_HAS_FUNC(prpl_info, get_account_options))
+		return prpl_info->get_account_options();
+	else
+		return NULL;
+}
+
 void
 purple_account_add_buddy(PurpleAccount *account, PurpleBuddy *buddy)
 {
============================================================
--- libpurple/account.h	fdef986f309e02b3a8e599d97cacd581e659c4d6
+++ libpurple/account.h	fa313f6a8bfff1acc949706943e7617cec4d41c5
@@ -129,7 +129,7 @@ struct _PurpleAccount
 	char *alias;                /**< How you appear to yourself.            */
 	char *password;             /**< The account password.                  */
 	char *user_info;            /**< User information.                      */
-	char *certificate_id;       /**< User certificate id.                   */
+//XXX	char *certificate_id;       /**< User certificate id.                   */
 
 	char *buddy_icon_path;      /**< The buddy icon's non-cached path.      */
 
@@ -359,7 +359,7 @@ void purple_account_set_password(PurpleA
  * @param account The account.
  * @param id The user's certificate id.
  */
-void purple_account_set_certificate_id(PurpleAccount *account, const char* id);
+// XXX void purple_account_set_certificate_id(PurpleAccount *account, const char* id);
 
 /**
  * Sets the account's alias.
@@ -670,7 +670,7 @@ const char *purple_account_get_password(
  *
  * @return The certificate id.
  */
-const char *purple_account_get_certificate_id(const PurpleAccount *account);
+// XXX const char *purple_account_get_certificate_id(const PurpleAccount *account);
 
 /**
  * Returns the account's alias.
@@ -1157,6 +1157,17 @@ void purple_accounts_restore_current_sta
  */
 void purple_accounts_restore_current_statuses(void);
 
+/**
+ * Get account options. Prior to version 3.0 this was accessed
+ * via PurplePluginInfo.protocol_options. 
+ *
+ * @param account The account
+ *
+ * @returns List of PurpleAccountOption
+ * @since 3.0
+ */
+GList* purple_account_get_options(PurplePluginProtocolInfo *prpl_info);
+
 /*@}*/
 
 
============================================================
--- pidgin/gtkaccount.c	20f43b6c2ebe78b0d0847448fc4d8c7271377b03
+++ pidgin/gtkaccount.c	c3770158f4d8550a46b15eae9b3efe53a54b1642
@@ -782,6 +782,7 @@ add_protocol_options(AccountPrefsDialog 
 	const char *str_value;
 	gboolean bool_value;
 	ProtocolOptEntry *opt_entry;
+	GList *protocol_options;
 
 	if (dialog->protocol_frame != NULL) {
 		gtk_notebook_remove_page (GTK_NOTEBOOK(dialog->notebook), 1);
@@ -795,12 +796,16 @@ add_protocol_options(AccountPrefsDialog 
 		dialog->protocol_opt_entries = g_list_delete_link(dialog->protocol_opt_entries, dialog->protocol_opt_entries);
 	}
 
-	if (dialog->prpl_info == NULL ||
-			dialog->prpl_info->protocol_options == NULL)
+	account = dialog->account;
+
+	if (dialog->prpl_info == NULL)
 		return;
 
-	account = dialog->account;
+	protocol_options = purple_account_get_options(dialog->prpl_info);
+	if (protocol_options == NULL)
+		return;
 
+
 	/* Main vbox */
 	dialog->protocol_frame = vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
 	gtk_container_set_border_width(GTK_CONTAINER(vbox), PIDGIN_HIG_BORDER);
@@ -811,7 +816,7 @@ add_protocol_options(AccountPrefsDialog 
 	menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(dialog->protocol_menu));
 	item = gtk_menu_get_active(GTK_MENU(menu));
 
-	for (l = dialog->prpl_info->protocol_options; l != NULL; l = l->next)
+	for (l = protocol_options; l != NULL; l = l->next)
 	{
 		option = (PurpleAccountOption *)l->data;
 
============================================================
--- libpurple/protocols/jabber/libxmpp.c	a8d36f925713b21b21fe5aca4b62c01aaf9c207c
+++ libpurple/protocols/jabber/libxmpp.c	83a831eac1c6c3383f1801765030a89e1af08d7e
@@ -48,6 +48,7 @@
 #include "caps.h"
 #include "data.h"
 #include "ibb.h"
+#include "certificate.h"
 
 static PurplePlugin *my_protocol = NULL;
 
@@ -131,7 +132,8 @@ static PurplePluginProtocolInfo prpl_inf
 	NULL, /* set_public_alias */
 	NULL, /* get_public_alias */
 	NULL, /* add_buddy_with_invite */
-	NULL  /* add_buddies_with_invite */
+	NULL, /* add_buddies_with_invite */
+	jabber_get_account_options /* get_account_options */
 };
 
 static gboolean load_plugin(PurplePlugin *plugin)
@@ -249,23 +251,31 @@ static gboolean xmpp_uri_handler(const c
 	return FALSE;
 }
 
+static
+void destroy_account_options(GList *account_options)
+{
+	GList *item = NULL;
 
-static void
-init_plugin(PurplePlugin *plugin)
+	for (item = account_options; item != NULL; item = item->next) {
+		purple_account_option_destroy(item->data);
+	}
+
+	g_list_free(account_options);
+}
+
+GList* jabber_get_account_options()
 {
-	PurpleAccountUserSplit *split;
 	PurpleAccountOption *option;
+	GList *options = NULL;
 	GList *encryption_values = NULL;
+	PurpleCertificatePool *cert_pool = NULL;
+	GList *certificates = NULL;
+	
+	/* Destroy the current option list so we can recreated it. 
+	 * We could just update the changed field, but this is simpler
+	 */
+	destroy_account_options(prpl_info.protocol_options);
 
-	/* Translators: 'domain' is used here in the context of Internet domains, e.g. pidgin.im */
-	split = purple_account_user_split_new(_("Domain"), NULL, '@');
-	purple_account_user_split_set_reverse(split, FALSE);
-	prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
-
-	split = purple_account_user_split_new(_("Resource"), "", '/');
-	purple_account_user_split_set_reverse(split, FALSE);
-	prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
-
 #define ADD_VALUE(list, desc, v) { \
 	PurpleKeyValuePair *kvp = g_new0(PurpleKeyValuePair, 1); \
 	kvp->key = g_strdup((desc)); \
@@ -281,47 +291,91 @@ init_plugin(PurplePlugin *plugin)
 #endif
 	encryption_values = g_list_reverse(encryption_values);
 
-#undef ADD_VALUE
 
 	option = purple_account_option_list_new(_("Connection security"), "connection_security", encryption_values);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
-						   option);
+	options = g_list_append(options, option);
 
-	option = purple_account_option_bool_new(
-						_("Allow plaintext auth over unencrypted streams"),
+	
+	ADD_VALUE(certificates, _("None"), "none"); /* hopefully we don't have a cert id of none */
+	cert_pool = purple_certificate_find_pool("x509", "user");
+	if (cert_pool) {
+		GList *id_list = NULL;
+		GList *item = NULL;
+		PurpleCertificate *cert = NULL;
+
+		id_list = purple_certificate_pool_get_idlist(cert_pool);
+		for (item = id_list; item != NULL; item = item->next) {
+			gchar* id = item->data;
+			cert = purple_certificate_pool_retrieve(cert_pool, id);
+			if (cert) {
+				PurpleKeyValuePair *kvp = g_new0(PurpleKeyValuePair, 1);
+				kvp->key = g_strdup(id);
+				kvp->value = purple_certificate_get_subject_name(cert);
+				certificates = g_list_append(certificates, kvp);
+				purple_debug_info("xmpp/accountopt", "added cert %s to acct opt list\n", id);
+			}
+			else {
+				purple_debug_warning("xmpp/accountopt", "Failed to find cert for id %s\n", id);
+			}
+		}
+		purple_certificate_pool_destroy_idlist(id_list);
+	}
+
+	option = purple_account_option_list_new(_("Login certificate"), "certificate_id", certificates);
+	options = g_list_append(options, option);
+
+#undef ADD_VALUE
+
+	option = purple_account_option_bool_new(_("Allow plaintext auth over unencrypted streams"),
 						"auth_plain_in_clear", FALSE);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
-						   option);
+	options = g_list_append(options, option);
 
 	option = purple_account_option_int_new(_("Connect port"), "port", 5222);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
-						   option);
+	options = g_list_append(options, option);
 
 	option = purple_account_option_string_new(_("Connect server"),
 						  "connect_server", NULL);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
-						  option);
+	options = g_list_append(options, option);
 
 	option = purple_account_option_string_new(_("File transfer proxies"),
 						  "ft_proxies",
 						/* TODO: Is this an acceptable default?
 						 * Also, keep this in sync as they add more servers */
 						  JABBER_DEFAULT_FT_PROXIES);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
-						  option);
+	options = g_list_append(options, option);
 
 	option = purple_account_option_string_new(_("BOSH URL"),
 						  "bosh_url", NULL);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
-						  option);
+	options = g_list_append(options, option);
 
 	/* this should probably be part of global smiley theme settings later on,
 	  shared with MSN */
 	option = purple_account_option_bool_new(_("Show Custom Smileys"),
 		"custom_smileys", TRUE);
-	prpl_info.protocol_options = g_list_append(prpl_info.protocol_options,
-		option);
+	options = g_list_append(options, option);
 
+	/* Required until we stop using the protocol_options field */
+	prpl_info.protocol_options = options;
+
+	return options;
+}
+
+static void
+init_plugin(PurplePlugin *plugin)
+{
+	PurpleAccountUserSplit *split;
+
+	/* Translators: 'domain' is used here in the context of Internet domains, e.g. pidgin.im */
+	split = purple_account_user_split_new(_("Domain"), NULL, '@');
+	purple_account_user_split_set_reverse(split, FALSE);
+	prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
+
+	split = purple_account_user_split_new(_("Resource"), "", '/');
+	purple_account_user_split_set_reverse(split, FALSE);
+	prpl_info.user_splits = g_list_append(prpl_info.user_splits, split);
+
+	prpl_info.protocol_options = jabber_get_account_options();
+
 	my_protocol = plugin;
 
 	purple_prefs_remove("/plugins/prpl/jabber");


More information about the Commits mailing list