[evolution-patches] 68583, soup SSL/proxy cert validation problem



This fixes 68583 (SSL certificate validation through a proxy always
fails) and also includes part of the fix for 64414 (most SSL errors show
up as "Connection terminated unexpectedly" rather than something
useful), which was supposed to have been committed for 2.2.1, but due to
some CVS lossage on my part, was not.


Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/libsoup/ChangeLog,v
retrieving revision 1.444.2.3
diff -u -r1.444.2.3 ChangeLog
--- ChangeLog	6 Oct 2004 17:30:50 -0000	1.444.2.3
+++ ChangeLog	20 Oct 2004 17:12:53 -0000
@@ -1,3 +1,16 @@
+2004-10-20  Dan Winship  <danw novell com>
+
+	* libsoup/soup-gnutls.c: Commit the alleged changes from the 10-06
+	commit, which somehow did not actually get committed then.
+
+	* libsoup/soup-socket.c (soup_socket_start_proxy_ssl): New, starts
+	SSL and lets the caller pass the expected hostname.
+
+	* libsoup/soup-connection.c (tunnel_connect_finished): Use
+	soup_socket_start_proxy_ssl() rather than soup_socket_start_ssl(),
+	so that we don't compare the certificate against the *proxy*'s
+	hostname. (68583)
+
 2004-10-06  Dan Winship  <danw novell com>
 
 	* configure.in: Bump version to 2.2.1
Index: libsoup/soup-connection.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-connection.c,v
retrieving revision 1.27
diff -u -r1.27 soup-connection.c
--- libsoup/soup-connection.c	26 Aug 2004 15:33:33 -0000	1.27
+++ libsoup/soup-connection.c	20 Oct 2004 17:12:53 -0000
@@ -355,7 +355,8 @@
 	clear_current_request (conn);
 
 	if (SOUP_STATUS_IS_SUCCESSFUL (status)) {
-		if (!soup_socket_start_ssl (conn->priv->socket))
+		if (!soup_socket_start_proxy_ssl (conn->priv->socket,
+						  conn->priv->origin_uri->host))
 			status = SOUP_STATUS_SSL_FAILED;
 	}
 
Index: libsoup/soup-gnutls.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-gnutls.c,v
retrieving revision 1.15.2.1
diff -u -r1.15.2.1 soup-gnutls.c
--- libsoup/soup-gnutls.c	4 Oct 2004 15:16:02 -0000	1.15.2.1
+++ libsoup/soup-gnutls.c	20 Oct 2004 17:12:53 -0000
@@ -49,14 +49,16 @@
 } SoupGNUTLSChannel;
 
 static gboolean
-verify_certificate (gnutls_session session, const char *hostname)
+verify_certificate (gnutls_session session, const char *hostname, GError **err)
 {
 	int status;
 
 	status = gnutls_certificate_verify_peers (session);
 
 	if (status == GNUTLS_E_NO_CERTIFICATE_FOUND) {
-		g_warning ("No certificate was sent.");
+		g_set_error (err, SOUP_SSL_ERROR,
+			     SOUP_SSL_ERROR_CERTIFICATE,
+			     "No SSL certificate was sent.");
 		return FALSE;
 	}
 
@@ -64,17 +66,23 @@
 	    status & GNUTLS_CERT_NOT_TRUSTED ||
 	    status & GNUTLS_CERT_REVOKED)
 	{
-		g_warning ("The certificate is not trusted.");
+		g_set_error (err, SOUP_SSL_ERROR,
+			     SOUP_SSL_ERROR_CERTIFICATE,
+			     "The SSL certificate is not trusted.");
 		return FALSE;
 	}
 
 	if (gnutls_certificate_expiration_time_peers (session) < time (0)) {
-		g_warning ("The certificate has expired.");
+		g_set_error (err, SOUP_SSL_ERROR,
+			     SOUP_SSL_ERROR_CERTIFICATE,
+			     "The SSL certificate has expired.");
 		return FALSE;
 	}
 
 	if (gnutls_certificate_activation_time_peers (session) > time (0)) {
-		g_warning ("The certificate is not yet activated.");
+		g_set_error (err, SOUP_SSL_ERROR,
+			     SOUP_SSL_ERROR_CERTIFICATE,
+			     "The SSL certificate is not yet activated.");
 		return FALSE;
 	}
 
@@ -84,7 +92,9 @@
 		gnutls_x509_crt cert;
 
 		if (gnutls_x509_crt_init (&cert) < 0) {
-			g_warning ("Error initializing certificate.");
+			g_set_error (err, SOUP_SSL_ERROR,
+				     SOUP_SSL_ERROR_CERTIFICATE,
+				     "Error initializing SSL certificate.");
 			return FALSE;
 		}
       
@@ -92,22 +102,28 @@
 			session, &cert_list_size);
 
 		if (cert_list == NULL) {
-			g_warning ("No certificate was found.");
+			g_set_error (err, SOUP_SSL_ERROR,
+				     SOUP_SSL_ERROR_CERTIFICATE,
+				     "No SSL certificate was found.");
 			return FALSE;
 		}
 
 		if (gnutls_x509_crt_import (cert, &cert_list[0],
 					    GNUTLS_X509_FMT_DER) < 0) {
-			g_warning ("The certificate could not be parsed.");
+			g_set_error (err, SOUP_SSL_ERROR,
+				     SOUP_SSL_ERROR_CERTIFICATE,
+				     "The SSL certificate could not be parsed.");
 			return FALSE;
 		}
 
 		if (!gnutls_x509_crt_check_hostname (cert, hostname)) {
-			g_warning ("The certificate does not match hostname.");
+			g_set_error (err, SOUP_SSL_ERROR,
+				     SOUP_SSL_ERROR_CERTIFICATE,
+				     "The SSL certificate does not match the hostname.");
 			return FALSE;
 		}
 	}
-   
+
 	return TRUE;
 }
 
@@ -135,15 +151,9 @@
 		return G_IO_STATUS_ERROR;
 	}
 
-	if (chan->type == SOUP_SSL_TYPE_CLIENT &&
-	    chan->cred->have_ca_file) {
-		if (!verify_certificate (chan->session, chan->hostname)) {
-			g_set_error (err, G_IO_CHANNEL_ERROR,
-				     G_IO_CHANNEL_ERROR_FAILED,
-				     "Unable to verify certificate");
-			return G_IO_STATUS_ERROR;
-		}
-	}
+	if (chan->type == SOUP_SSL_TYPE_CLIENT && chan->cred->have_ca_file &&
+	    !verify_certificate (chan->session, chan->hostname, err))
+		return G_IO_STATUS_ERROR;
 
 	return G_IO_STATUS_NORMAL;
 }
Index: libsoup/soup-socket.c
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-socket.c,v
retrieving revision 1.53.2.1
diff -u -r1.53.2.1 soup-socket.c
--- libsoup/soup-socket.c	6 Oct 2004 17:22:17 -0000	1.53.2.1
+++ libsoup/soup-socket.c	20 Oct 2004 17:12:54 -0000
@@ -600,14 +600,29 @@
 gboolean
 soup_socket_start_ssl (SoupSocket *sock)
 {
+	return soup_socket_start_proxy_ssl (sock, soup_address_get_name (sock->priv->remote_addr));
+}
+	
+/**
+ * soup_socket_start_proxy_ssl:
+ * @sock: the socket
+ * @ssl_host: hostname of the SSL server
+ *
+ * Starts using SSL on @socket, expecting to find a host named
+ * @ssl_host.
+ *
+ * Return value: success or failure
+ **/
+gboolean
+soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host)
+{
 	GIOChannel *ssl_chan;
 
 	get_iochannel (sock);
 	ssl_chan = soup_ssl_wrap_iochannel (
 		sock->priv->iochannel, sock->priv->is_server ?
 		SOUP_SSL_TYPE_SERVER : SOUP_SSL_TYPE_CLIENT,
-		soup_address_get_name (sock->priv->remote_addr),
-		sock->priv->ssl_creds);
+		ssl_host, sock->priv->ssl_creds);
 
 	if (!ssl_chan)
 		return FALSE;
Index: libsoup/soup-socket.h
===================================================================
RCS file: /cvs/gnome/libsoup/libsoup/soup-socket.h,v
retrieving revision 1.25
diff -u -r1.25 soup-socket.h
--- libsoup/soup-socket.h	15 Dec 2003 14:04:14 -0000	1.25
+++ libsoup/soup-socket.h	20 Oct 2004 17:12:54 -0000
@@ -51,6 +51,8 @@
 gboolean       soup_socket_listen             (SoupSocket         *sock,
 					       SoupAddress        *local_addr);
 gboolean       soup_socket_start_ssl          (SoupSocket         *sock);
+gboolean       soup_socket_start_proxy_ssl    (SoupSocket         *sock,
+					       const char         *ssl_host);
 
 void           soup_socket_disconnect         (SoupSocket         *sock);
 gboolean       soup_socket_is_connected       (SoupSocket         *sock);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]