pidgin: 3b944aaf: gnutls: Use gnutls_priority_init for the...
darkrain42 at pidgin.im
darkrain42 at pidgin.im
Thu Apr 1 02:42:11 EDT 2010
-----------------------------------------------------------------
Revision: 3b944aafdeba3b75bf206536534e8db56c5bd70f
Ancestor: dfecabe492257b96e1cdc59323c35a3605a9f68c
Author: darkrain42 at pidgin.im
Date: 2010-04-01T04:54:43
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/3b944aafdeba3b75bf206536534e8db56c5bd70f
Modified files:
libpurple/plugins/ssl/ssl-gnutls.c
ChangeLog:
gnutls: Use gnutls_priority_init for the default priority.
This contains hacks to work around a memory leak (on invalid priority
strings) in GnuTLS.
-------------- next part --------------
============================================================
--- libpurple/plugins/ssl/ssl-gnutls.c 9857f9843f5fcd823db5632fab9ac824e89f1ccb
+++ libpurple/plugins/ssl/ssl-gnutls.c 7a0c8b54c6bd1e12c9ebddbd9c24fae3758e365e
@@ -43,10 +43,15 @@ static gnutls_certificate_client_credent
static gnutls_certificate_client_credentials xcred = NULL;
#ifdef HAVE_GNUTLS_PRIORITY_FUNCS
-/* Priority strings. The default one is, well, the default (and is always set).
- * The hash table is of the form hostname => priority (both char *)
+/* Priority strings. The default one is, well, the default (and is always
+ * set). The hash table is of the form hostname => priority (both
+ * char *).
+ *
+ * We only use a gnutls_priority_t for the default on the assumption that
+ * that's the more common case. Improvement patches (like matching on
+ * subdomains) welcome.
*/
-static char *default_priority = NULL;
+static gnutls_priority_t default_priority = NULL;
static GHashTable *host_priorities = NULL;
#endif
@@ -104,6 +109,7 @@ ssl_gnutls_init_gnutls(void)
"this. :-(");
#else /* HAVE_GNUTLS_PRIORITY_FUNCS */
char **entries = g_strsplit(host_priorities_str, ";", -1);
+ char *default_priority_str = NULL;
guint i;
host_priorities = g_hash_table_new_full(g_str_hash, g_str_equal,
@@ -126,8 +132,8 @@ ssl_gnutls_init_gnutls(void)
/* TODO: Validate each of these and complain */
if (g_str_equal(host, "*")) {
/* Override the default priority */
- g_free(default_priority);
- default_priority = g_strdup(prio_str);
+ g_free(default_priority_str);
+ default_priority_str = g_strdup(prio_str);
} else
g_hash_table_insert(host_priorities, g_strdup(host),
g_strdup(prio_str));
@@ -135,14 +141,33 @@ ssl_gnutls_init_gnutls(void)
}
}
+ if (default_priority_str) {
+ if (gnutls_priority_init(&default_priority, default_priority_str, NULL)) {
+ purple_debug_warning("gnutls", "Unable to set default priority to %s\n",
+ default_priority_str);
+ /* Versions of GnuTLS as of 2.8.6 (2010-03-31) don't free/NULL
+ * this on error.
+ */
+ gnutls_free(default_priority);
+ default_priority = NULL;
+ }
+
+ g_free(default_priority_str);
+ }
+
g_strfreev(entries);
#endif /* HAVE_GNUTLS_PRIORITY_FUNCS */
}
#ifdef HAVE_GNUTLS_PRIORITY_FUNCS
/* Make sure we set have a default priority! */
- if (!default_priority)
- default_priority = g_strdup("NORMAL:%SSL3_RECORD_VERSION");
+ if (!default_priority) {
+ if (gnutls_priority_init(&default_priority, "NORMAL:%SSL3_RECORD_VERSION", NULL)) {
+ /* See comment above about memory leak */
+ gnutls_free(default_priority);
+ gnutls_priority_init(&default_priority, "NORMAL", NULL);
+ }
+ }
#endif /* HAVE_GNUTLS_PRIORITY_FUNCS */
gnutls_global_init();
@@ -174,7 +199,7 @@ ssl_gnutls_uninit(void)
host_priorities = NULL;
}
- g_free(default_priority);
+ gnutls_priority_deinit(default_priority);
default_priority = NULL;
#endif
}
@@ -356,24 +381,19 @@ ssl_gnutls_connect(PurpleSslConnection *
#ifdef HAVE_GNUTLS_PRIORITY_FUNCS
{
const char *prio_str = NULL;
+ gboolean set = FALSE;
/* Let's see if someone has specified a specific priority */
if (gsc->host && host_priorities)
prio_str = g_hash_table_lookup(host_priorities, gsc->host);
- /* If not, let's use the default! */
- if (!prio_str)
- prio_str = default_priority;
+ if (prio_str)
+ set = (GNUTLS_E_SUCCESS ==
+ gnutls_priority_set_direct(gnutls_data->session, prio_str,
+ NULL));
- /* TODO: Use a gnutls_priority_t cache, so this doesn't require three levels! */
- /* The logic here is to try the specified string, fall back to the default
- * (which may also be user-specified), and if *that* doesn't work, fall back
- * to the default default (which I'm not sure is necessary, but whatever).
- */
- if (gnutls_priority_set_direct(gnutls_data->session,
- prio_str, NULL))
- if (gnutls_priority_set_direct(gnutls_data->session, default_priority, NULL))
- gnutls_priority_set_direct(gnutls_data->session, "NORMAL", NULL);
+ if (!set)
+ gnutls_priority_set(gnutls_data->session, default_priority);
}
#else
gnutls_set_default_priority(gnutls_data->session);
More information about the Commits
mailing list