changeset 27631:bff61dad9a6b

Add purple_ssl_connect_with_ssl_cn, which takes a host to connect to in addition to a string with which to validate the SSL certificate. Useful for OSCAR (and XMPP BOSH soon), where we have an IP to connect to, but need to validate the SSL cert.
author Paul Aurich <paul@darkrain42.org>
date Wed, 15 Jul 2009 16:57:33 +0000
parents 38feacee7c86
children 12f5a7916131
files ChangeLog.API libpurple/protocols/oscar/flap_connection.c libpurple/protocols/oscar/oscar.c libpurple/protocols/oscar/oscar.h libpurple/sslconn.c libpurple/sslconn.h
diffstat 6 files changed, 45 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog.API	Wed Jul 15 15:32:11 2009 +0000
+++ b/ChangeLog.API	Wed Jul 15 16:57:33 2009 +0000
@@ -56,6 +56,7 @@
 		* purple_request_field_get_group
 		* purple_request_field_get_ui_data
 		* purple_request_field_set_ui_data
+		* purple_ssl_connect_with_ssl_cn
 		* purple_strequal
 		* purple_utf8_strip_unprintables
 		* purple_util_fetch_url_request_len_with_account
--- a/libpurple/protocols/oscar/flap_connection.c	Wed Jul 15 15:32:11 2009 +0000
+++ b/libpurple/protocols/oscar/flap_connection.c	Wed Jul 15 16:57:33 2009 +0000
@@ -505,7 +505,6 @@
 
 	g_free(conn->error_message);
 	g_free(conn->cookie);
-	g_free(conn->ssl_cert_cn);
 
 	/*
 	 * Free conn->internal, if necessary
--- a/libpurple/protocols/oscar/oscar.c	Wed Jul 15 15:32:11 2009 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Wed Jul 15 16:57:33 2009 +0000
@@ -1246,32 +1246,6 @@
 }
 
 static void
-ssl_proxy_conn_established_cb(gpointer data, gint source, const gchar *error_message)
-{
-	OscarData *od;
-	PurpleConnection *gc;
-	PurpleAccount *account;
-	FlapConnection *conn;
-
-	conn = data;
-	od = conn->od;
-	gc = od->gc;
-	account = purple_connection_get_account(gc);
-
-	conn->connect_data = NULL;
-
-	if (source < 0)
-	{
-		connection_common_error_cb(conn, error_message);
-		return;
-	}
-
-	conn->gsc = purple_ssl_connect_with_host_fd(account, source,
-			ssl_connection_established_cb, ssl_connection_error_cb,
-			conn->ssl_cert_cn, conn);
-}
-
-static void
 flap_connection_established_bos(OscarData *od, FlapConnection *conn)
 {
 	PurpleConnection *gc = od->gc;
@@ -1943,12 +1917,13 @@
 	if (od->use_ssl)
 	{
 		/*
-		 * This shouldn't be hardcoded except that the server isn't sending
-		 * us a name to use for comparing the certificate common name.
+		 * This shouldn't be hardcoded to "bos.oscar.aol.com" except that
+		 * the server isn't sending us a name to use for comparing the
+		 * certificate common name.
 		 */
-		newconn->ssl_cert_cn = g_strdup("bos.oscar.aol.com");
-		newconn->connect_data = purple_proxy_connect(NULL, account, host, port,
-				ssl_proxy_conn_established_cb, newconn);
+		newconn->gsc = purple_ssl_connect_with_ssl_cn(account, host, port,
+				ssl_connection_established_cb, ssl_connection_error_cb,
+				"bos.oscar.aol.com", newconn);
 	}
 	else
 	{
@@ -1957,7 +1932,7 @@
 	}
 
 	g_free(host);
-	if (newconn->connect_data == NULL)
+	if (newconn->gsc == NULL && newconn->connect_data == NULL)
 	{
 		purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_NETWORK_ERROR, _("Unable to connect"));
 		return 0;
@@ -2114,15 +2089,9 @@
 
 	if (redir->use_ssl)
 	{
-		/*
-		 * TODO: It should be possible to specify a certificate common name
-		 * distinct from the host we're passing to purple_ssl_connect. The
-		 * way to work around that is to use purple_proxy_connect +
-		 * purple_ssl_connect_with_host_fd
-		 */
-		newconn->ssl_cert_cn = g_strdup(redir->ssl_cert_cn);
-		newconn->connect_data = purple_proxy_connect(NULL, account, host, port,
-				ssl_proxy_conn_established_cb, newconn);
+		newconn->gsc = purple_ssl_connect_with_ssl_cn(account, host, port,
+				ssl_connection_established_cb, ssl_connection_error_cb,
+				redir->ssl_cert_cn, newconn);
 	}
 	else
 	{
--- a/libpurple/protocols/oscar/oscar.h	Wed Jul 15 15:32:11 2009 +0000
+++ b/libpurple/protocols/oscar/oscar.h	Wed Jul 15 16:57:33 2009 +0000
@@ -429,7 +429,6 @@
 	guint16 cookielen;
 	guint8 *cookie;
 	gpointer new_conn_data;
-	gchar *ssl_cert_cn;
 
 	int fd;
 	PurpleSslConnection *gsc;
--- a/libpurple/sslconn.c	Wed Jul 15 15:32:11 2009 +0000
+++ b/libpurple/sslconn.c	Wed Jul 15 16:57:33 2009 +0000
@@ -100,6 +100,15 @@
 				 PurpleSslInputFunction func, PurpleSslErrorFunction error_func,
 				 void *data)
 {
+	return purple_ssl_connect_with_ssl_cn(account, host, port, func, error_func,
+	                                  NULL, data);
+}
+
+PurpleSslConnection *
+purple_ssl_connect_with_ssl_cn(PurpleAccount *account, const char *host, int port,
+				 PurpleSslInputFunction func, PurpleSslErrorFunction error_func,
+				 const char *ssl_cn, void *data)
+{
 	PurpleSslConnection *gsc;
 
 	g_return_val_if_fail(host != NULL,            NULL);
@@ -116,7 +125,7 @@
 	gsc = g_new0(PurpleSslConnection, 1);
 
 	gsc->fd              = -1;
-	gsc->host            = g_strdup(host);
+	gsc->host            = ssl_cn ? g_strdup(ssl_cn) : g_strdup(host);
 	gsc->port            = port;
 	gsc->connect_cb_data = data;
 	gsc->connect_cb      = func;
--- a/libpurple/sslconn.h	Wed Jul 15 15:32:11 2009 +0000
+++ b/libpurple/sslconn.h	Wed Jul 15 16:57:33 2009 +0000
@@ -186,6 +186,30 @@
 									PurpleSslErrorFunction error_func,
 									void *data);
 
+/**
+ * Makes a SSL connection to the specified host and port, using the separate
+ * name to verify with the certificate.  The caller should keep track of the
+ * returned value and use it to cancel the connection, if needed.
+ *
+ * @param account    The account making the connection.
+ * @param host       The destination host.
+ * @param port       The destination port.
+ * @param func       The SSL input handler function.
+ * @param error_func The SSL error handler function.  This function
+ *                   should <strong>NOT</strong> call purple_ssl_close().  In
+ *                   the event of an error the #PurpleSslConnection will be
+ *                   destroyed for you.
+ * @param ssl_host   The hostname of the other peer (to verify the CN)
+ * @param data       User-defined data.
+ *
+ * @return The SSL connection handle.
+ */
+PurpleSslConnection *purple_ssl_connect_with_ssl_cn(PurpleAccount *account, const char *host,
+									int port, PurpleSslInputFunction func,
+									PurpleSslErrorFunction error_func,
+									const char *ssl_host,
+									void *data);
+
 #if !(defined PURPLE_DISABLE_DEPRECATED) || (defined _PURPLE_SSLCONN_C_)
 /**
  * Makes a SSL connection using an already open file descriptor.