[libsoup] Use GTlsDatabase, add new SoupSession properties for it



commit 74d9cd866e2f4aac42663e55a97d992fce47fd60
Author: Dan Winship <danw gnome org>
Date:   Mon Sep 12 20:33:39 2011 -0400

    Use GTlsDatabase, add new SoupSession properties for it
    
    Now that we have GTlsFileDatabase, we can use that to validate
    certificates when the caller sets SoupSession:ssl-ca-file, rather than
    doing it the slow hacky way we had been.
    
    Also, add two new properties, SoupSession:tlsdb, to set an arbitrary
    GTlsDatabase on the session, and SoupSession:use-system-ca-file, to
    tell it to use the default GTlsDatabase.

 configure.ac              |    4 +-
 libsoup/Makefile.am       |    2 -
 libsoup/soup-connection.c |   43 ++++++++----
 libsoup/soup-connection.h |    1 +
 libsoup/soup-message-io.c |    1 -
 libsoup/soup-misc.c       |    2 +
 libsoup/soup-misc.h       |   11 +---
 libsoup/soup-server.c     |   20 +++---
 libsoup/soup-session.c    |  177 +++++++++++++++++++++++++++++++++++----------
 libsoup/soup-session.h    |    2 +
 libsoup/soup-socket.c     |   38 +++-------
 libsoup/soup-ssl.c        |  149 --------------------------------------
 libsoup/soup-ssl.h        |   30 --------
 13 files changed, 197 insertions(+), 283 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 4d693b5..a0d0f7d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -72,9 +72,9 @@ dnl ***********************
 dnl *** Checks for glib ***
 dnl ***********************
 
-AM_PATH_GLIB_2_0(2.27.5,,,gobject gthread gio)
+AM_PATH_GLIB_2_0(2.30.0,,,gobject gthread gio)
 if test "$GLIB_LIBS" = ""; then
-   AC_MSG_ERROR(GLIB 2.27.5 or later is required to build libsoup)
+   AC_MSG_ERROR(GLIB 2.30.0 or later is required to build libsoup)
 fi
 GLIB_CFLAGS="$GLIB_CFLAGS -DG_DISABLE_SINGLE_INCLUDES"
 
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index 8dc8507..096f0fb 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -172,8 +172,6 @@ libsoup_2_4_la_SOURCES =		\
 	soup-session-private.h		\
 	soup-session-sync.c		\
 	soup-socket.c			\
-	soup-ssl.h			\
-	soup-ssl.c	     		\
 	soup-status.c			\
 	soup-uri.c			\
 	soup-value-utils.c		\
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 514640f..d82832f 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -26,7 +26,6 @@
 #include "soup-misc.h"
 #include "soup-misc-private.h"
 #include "soup-socket.h"
-#include "soup-ssl.h"
 #include "soup-uri.h"
 #include "soup-enum-types.h"
 
@@ -35,9 +34,8 @@ typedef struct {
 
 	SoupAddress *remote_addr, *tunnel_addr;
 	SoupURI     *proxy_uri;
-	gpointer     ssl_creds;
-	gboolean     ssl_strict;
-	gboolean     ssl_fallback;
+	GTlsDatabase *tlsdb;
+	gboolean     ssl, ssl_strict, ssl_fallback;
 
 	GMainContext      *async_context;
 
@@ -64,6 +62,7 @@ enum {
 	PROP_REMOTE_ADDRESS,
 	PROP_TUNNEL_ADDRESS,
 	PROP_PROXY_URI,
+	PROP_SSL,
 	PROP_SSL_CREDS,
 	PROP_SSL_STRICT,
 	PROP_SSL_FALLBACK,
@@ -181,12 +180,20 @@ soup_connection_class_init (SoupConnectionClass *connection_class)
 				    SOUP_TYPE_URI,
 				    G_PARAM_READWRITE));
 	g_object_class_install_property (
-		object_class, PROP_SSL_CREDS,
-		g_param_spec_pointer (SOUP_CONNECTION_SSL_CREDENTIALS,
-				      "SSL credentials",
-				      "Opaque SSL credentials for this connection",
+		object_class, PROP_SSL,
+		g_param_spec_boolean (SOUP_CONNECTION_SSL,
+				      "SSL",
+				      "Whether this is an SSL connection",
+				      FALSE,
 				      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
 	g_object_class_install_property (
+		object_class, PROP_SSL_CREDS,
+		g_param_spec_object (SOUP_CONNECTION_SSL_CREDENTIALS,
+				     "SSL credentials",
+				     "SSL credentials for this connection",
+				     G_TYPE_TLS_DATABASE,
+				     G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+	g_object_class_install_property (
 		object_class, PROP_SSL_STRICT,
 		g_param_spec_boolean (SOUP_CONNECTION_SSL_STRICT,
 				      "Strictly validate SSL certificates",
@@ -269,8 +276,13 @@ set_property (GObject *object, guint prop_id,
 			soup_uri_free (priv->proxy_uri);
 		priv->proxy_uri = g_value_dup_boxed (value);
 		break;
+	case PROP_SSL:
+		priv->ssl = g_value_get_boolean (value);
+		break;
 	case PROP_SSL_CREDS:
-		priv->ssl_creds = g_value_get_pointer (value);
+		if (priv->tlsdb)
+			g_object_unref (priv->tlsdb);
+		priv->tlsdb = g_value_dup_object (value);
 		break;
 	case PROP_SSL_STRICT:
 		priv->ssl_strict = g_value_get_boolean (value);
@@ -314,8 +326,11 @@ get_property (GObject *object, guint prop_id,
 	case PROP_PROXY_URI:
 		g_value_set_boxed (value, priv->proxy_uri);
 		break;
+	case PROP_SSL:
+		g_value_set_boolean (value, priv->ssl);
+		break;
 	case PROP_SSL_CREDS:
-		g_value_set_pointer (value, priv->ssl_creds);
+		g_value_set_object (value, priv->tlsdb);
 		break;
 	case PROP_SSL_STRICT:
 		g_value_set_boolean (value, priv->ssl_strict);
@@ -478,7 +493,7 @@ socket_connect_result (SoupSocket *sock, guint status, gpointer user_data)
 	SoupConnectionPrivate *priv = SOUP_CONNECTION_GET_PRIVATE (data->conn);
 
 	if (SOUP_STATUS_IS_SUCCESSFUL (status) &&
-	    priv->ssl_creds && !priv->tunnel_addr) {
+	    priv->ssl && !priv->tunnel_addr) {
 		if (soup_socket_start_ssl (sock, data->cancellable)) {
 			soup_socket_handshake_async (sock, data->cancellable,
 						     socket_connect_finished, data);
@@ -514,7 +529,7 @@ soup_connection_connect_async (SoupConnection *conn,
 
 	priv->socket =
 		soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, priv->remote_addr,
-				 SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds,
+				 SOUP_SOCKET_SSL_CREDENTIALS, priv->tlsdb,
 				 SOUP_SOCKET_SSL_STRICT, priv->ssl_strict,
 				 SOUP_SOCKET_SSL_FALLBACK, priv->ssl_fallback,
 				 SOUP_SOCKET_ASYNC_CONTEXT, priv->async_context,
@@ -539,7 +554,7 @@ soup_connection_connect_sync (SoupConnection *conn, GCancellable *cancellable)
 
 	priv->socket =
 		soup_socket_new (SOUP_SOCKET_REMOTE_ADDRESS, priv->remote_addr,
-				 SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds,
+				 SOUP_SOCKET_SSL_CREDENTIALS, priv->tlsdb,
 				 SOUP_SOCKET_SSL_STRICT, priv->ssl_strict,
 				 SOUP_SOCKET_SSL_FALLBACK, priv->ssl_fallback,
 				 SOUP_SOCKET_FLAG_NONBLOCKING, FALSE,
@@ -552,7 +567,7 @@ soup_connection_connect_sync (SoupConnection *conn, GCancellable *cancellable)
 	if (!SOUP_STATUS_IS_SUCCESSFUL (status))
 		goto fail;
 		
-	if (priv->ssl_creds && !priv->tunnel_addr) {
+	if (priv->ssl && !priv->tunnel_addr) {
 		if (!soup_socket_start_ssl (priv->socket, cancellable))
 			status = SOUP_STATUS_SSL_FAILED;
 		else {
diff --git a/libsoup/soup-connection.h b/libsoup/soup-connection.h
index ef304e7..cd663a8 100644
--- a/libsoup/soup-connection.h
+++ b/libsoup/soup-connection.h
@@ -42,6 +42,7 @@ typedef void  (*SoupConnectionCallback)        (SoupConnection   *conn,
 #define SOUP_CONNECTION_REMOTE_ADDRESS  "remote-address"
 #define SOUP_CONNECTION_TUNNEL_ADDRESS  "tunnel-address"
 #define SOUP_CONNECTION_PROXY_URI       "proxy-uri"
+#define SOUP_CONNECTION_SSL             "ssl"
 #define SOUP_CONNECTION_SSL_CREDENTIALS "ssl-creds"
 #define SOUP_CONNECTION_SSL_STRICT      "ssl-strict"
 #define SOUP_CONNECTION_SSL_FALLBACK    "ssl-fallback"
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index a489788..aa33187 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -18,7 +18,6 @@
 #include "soup-message-queue.h"
 #include "soup-misc.h"
 #include "soup-socket.h"
-#include "soup-ssl.h"
 
 typedef enum {
 	SOUP_MESSAGE_IO_CLIENT,
diff --git a/libsoup/soup-misc.c b/libsoup/soup-misc.c
index 3136645..5c09526 100644
--- a/libsoup/soup-misc.c
+++ b/libsoup/soup-misc.c
@@ -16,6 +16,8 @@
  *
  **/
 
+const gboolean soup_ssl_supported = TRUE;
+
 /**
  * soup_str_case_hash:
  * @key: ASCII string to hash
diff --git a/libsoup/soup-misc.h b/libsoup/soup-misc.h
index 45c8883..0807b5f 100644
--- a/libsoup/soup-misc.h
+++ b/libsoup/soup-misc.h
@@ -54,16 +54,7 @@ extern const char soup_char_attributes[];
 
 extern const gboolean soup_ssl_supported;
 
-#define SOUP_SSL_ERROR soup_ssl_error_quark()
-
-GQuark soup_ssl_error_quark (void);
-
-typedef enum {
-	SOUP_SSL_ERROR_HANDSHAKE_NEEDS_READ,
-	SOUP_SSL_ERROR_HANDSHAKE_NEEDS_WRITE,
-	SOUP_SSL_ERROR_CERTIFICATE,
-	SOUP_SSL_ERROR_HANDSHAKE_FAILED
-} SoupSSLError;
+/* Part of a debugging API */
 
 typedef enum {
 	SOUP_CONNECTION_NEW,
diff --git a/libsoup/soup-server.c b/libsoup/soup-server.c
index aa73580..e44d716 100644
--- a/libsoup/soup-server.c
+++ b/libsoup/soup-server.c
@@ -24,7 +24,6 @@
 #include "soup-marshal.h"
 #include "soup-path-map.h" 
 #include "soup-socket.h"
-#include "soup-ssl.h"
 
 /**
  * SECTION:soup-server
@@ -99,7 +98,7 @@ typedef struct {
 	guint              port;
 
 	char              *ssl_cert_file, *ssl_key_file;
-	SoupSSLCredentials *ssl_creds;
+	GTlsCertificate   *ssl_cert;
 
 	char              *server_header;
 
@@ -169,8 +168,8 @@ finalize (GObject *object)
 
 	g_free (priv->ssl_cert_file);
 	g_free (priv->ssl_key_file);
-	if (priv->ssl_creds)
-		soup_ssl_free_server_credentials (priv->ssl_creds);
+	if (priv->ssl_cert)
+		g_object_unref (priv->ssl_cert);
 
 	g_free (priv->server_header);
 
@@ -469,10 +468,13 @@ constructor (GType                  type,
 	}
 
 	if (priv->ssl_cert_file && priv->ssl_key_file) {
-		priv->ssl_creds = soup_ssl_get_server_credentials (
-			priv->ssl_cert_file,
-			priv->ssl_key_file);
-		if (!priv->ssl_creds) {
+		GError *error = NULL;
+
+		priv->ssl_cert = g_tls_certificate_new_from_files (priv->ssl_cert_file, priv->ssl_key_file, &error);
+		if (!priv->ssl_cert) {
+			g_warning ("Could not read SSL certificate from '%s': %s",
+				   priv->ssl_cert_file, error->message);
+			g_error_free (error);
 			g_object_unref (server);
 			return NULL;
 		}
@@ -480,7 +482,7 @@ constructor (GType                  type,
 
 	priv->listen_sock =
 		soup_socket_new (SOUP_SOCKET_LOCAL_ADDRESS, priv->iface,
-				 SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_creds,
+				 SOUP_SOCKET_SSL_CREDENTIALS, priv->ssl_cert,
 				 SOUP_SOCKET_ASYNC_CONTEXT, priv->async_context,
 				 NULL);
 	if (!soup_socket_listen (priv->listen_sock)) {
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index cd4bbdd..75d6b1c 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -29,7 +29,6 @@
 #include "soup-session-feature.h"
 #include "soup-session-private.h"
 #include "soup-socket.h"
-#include "soup-ssl.h"
 #include "soup-uri.h"
 
 #define HOST_KEEP_ALIVE 5 * 60 * 1000 /* 5 min in msecs */
@@ -76,8 +75,8 @@ typedef struct {
 } SoupSessionHost;
 
 typedef struct {
+	GTlsDatabase *tlsdb;
 	char *ssl_ca_file;
-	SoupSSLCredentials *ssl_creds;
 	gboolean ssl_strict;
 
 	SoupMessageQueue *queue;
@@ -151,6 +150,8 @@ enum {
 	PROP_MAX_CONNS_PER_HOST,
 	PROP_USE_NTLM,
 	PROP_SSL_CA_FILE,
+	PROP_SSL_USE_SYSTEM_CA_FILE,
+	PROP_TLS_DATABASE,
 	PROP_SSL_STRICT,
 	PROP_ASYNC_CONTEXT,
 	PROP_TIMEOUT,
@@ -236,10 +237,9 @@ finalize (GObject *object)
 	g_free (priv->user_agent);
 	g_free (priv->accept_language);
 
-	if (priv->ssl_ca_file)
-		g_free (priv->ssl_ca_file);
-	if (priv->ssl_creds)
-		soup_ssl_free_client_credentials (priv->ssl_creds);
+	if (priv->tlsdb)
+		g_object_unref (priv->tlsdb);
+	g_free (priv->ssl_ca_file);
 
 	if (priv->async_context)
 		g_main_context_unref (priv->async_context);
@@ -542,10 +542,21 @@ soup_session_class_init (SoupSessionClass *session_class)
 				      FALSE,
 				      G_PARAM_READWRITE));
 	/**
+	 * #SoupSession:ssl-ca-file:
+	 *
+	 * File containing SSL CA certificates.
+	 *
+	 * Deprecated: use #SoupSession:ssl-use-system-ca-file or
+	 * #SoupSession:tls-database instead
+	 **/
+	/**
 	 * SOUP_SESSION_SSL_CA_FILE:
 	 *
 	 * Alias for the #SoupSession:ssl-ca-file property. (File
-	 * containing SSL CA certificates.)
+	 * containing SSL CA certificates.).
+	 *
+	 * Deprecated: use #SoupSession:ssl-use-system-ca-file or
+	 * #SoupSession:tls-database instead
 	 **/
 	g_object_class_install_property (
 		object_class, PROP_SSL_CA_FILE,
@@ -555,6 +566,60 @@ soup_session_class_init (SoupSessionClass *session_class)
 				     NULL,
 				     G_PARAM_READWRITE));
 	/**
+	 * SOUP_SESSION_USE_SYSTEM_CA_FILE:
+	 *
+	 * Alias for the #SoupSession:ssl-use-system-ca-file property.
+	 * Setting this to %TRUE overrides #SoupSession:ssl-ca-file
+	 * and #SoupSession:tls-database, and uses the default system
+	 * CA database (which, despite the name, may not actually be a
+	 * file).
+	 *
+	 * Since: 2.36
+	 **/
+	/**
+	 * #SoupSession:ssl-use-system-ca-file:
+	 *
+	 * Setting this to %TRUE overrides #SoupSession:ssl-ca-file
+	 * and #SoupSession:tls-database, and uses the default system
+	 * CA database (which, despite the name, may not actually be a
+	 * file).
+	 *
+	 * Since: 2.36
+	 **/
+	g_object_class_install_property (
+		object_class, PROP_SSL_USE_SYSTEM_CA_FILE,
+		g_param_spec_boolean (SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE,
+				      "Use system CA file",
+				      "Use the system certificate database",
+				      TRUE,
+				      G_PARAM_READWRITE));
+	/**
+	 * SOUP_SESSION_TLS_DATABASE:
+	 *
+	 * Alias for the #SoupSession:tls-database property. Overrides
+	 * #SoupSession:ssl-ca-file and
+	 * #SoupSession:ssl-use-system-ca-file, and uses the provided
+	 * #GTlsDatabase.
+	 *
+	 * Since: 2.36
+	 **/
+	/**
+	 * #SoupSession:tls-database:
+	 *
+	 * Overrides #SoupSession:ssl-ca-file and
+	 * #SoupSession:ssl-use-system-ca-file, and uses the provided
+	 * #GTlsDatabase.
+	 *
+	 * Since: 2.36
+	 **/
+	g_object_class_install_property (
+		object_class, PROP_TLS_DATABASE,
+		g_param_spec_object (SOUP_SESSION_TLS_DATABASE,
+				     "TLS Database",
+				     "TLS database to use",
+				     G_TYPE_TLS_DATABASE,
+				     G_PARAM_READWRITE));
+	/**
 	 * SOUP_SESSION_SSL_STRICT:
 	 *
 	 * Alias for the #SoupSession:ssl-strict property. By default,
@@ -763,18 +828,6 @@ soup_session_class_init (SoupSessionClass *session_class)
 				    G_PARAM_READWRITE));
 }
 
-static gboolean
-safe_str_equal (const char *a, const char *b)
-{
-	if (!a && !b)
-		return TRUE;
-
-	if ((a && !b) || (b && !a))
-		return FALSE;
-
-	return strcmp (a, b) == 0;
-}
-
 /* Converts a language in POSIX format and to be RFC2616 compliant    */
 /* Based on code from epiphany-webkit (ephy_langs_append_languages()) */
 static gchar *
@@ -859,14 +912,41 @@ accept_languages_from_system (void)
 }
 
 static void
+load_ssl_ca_file (SoupSessionPrivate *priv)
+{
+	GError *error = NULL;
+
+	if (g_path_is_absolute (priv->ssl_ca_file)) {
+		priv->tlsdb = g_tls_file_database_new (priv->ssl_ca_file,
+						       &error);
+	} else {
+		char *path, *cwd;
+
+		cwd = g_get_current_dir ();
+		path = g_build_filename (cwd, priv->ssl_ca_file, NULL);
+		priv->tlsdb = g_tls_file_database_new (path, &error);
+		g_free (path);
+	}
+	if (priv->tlsdb)
+		return;
+
+	if (!g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE)) {
+		g_warning ("Could not set SSL credentials from '%s': %s",
+			   priv->ssl_ca_file, error->message);
+
+		priv->tlsdb = g_tls_file_database_new ("/dev/null", NULL);
+	}
+	g_error_free (error);
+}
+
+static void
 set_property (GObject *object, guint prop_id,
 	      const GValue *value, GParamSpec *pspec)
 {
 	SoupSession *session = SOUP_SESSION (object);
 	SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
 	SoupURI *uri;
-	gboolean ca_file_changed = FALSE;
-	const char *new_ca_file, *user_agent;
+	const char *user_agent;
 	SoupSessionFeature *feature;
 
 	switch (prop_id) {
@@ -900,19 +980,34 @@ set_property (GObject *object, guint prop_id,
 			g_warning ("Trying to set use-ntlm on session with no auth-manager");
 		break;
 	case PROP_SSL_CA_FILE:
-		new_ca_file = g_value_get_string (value);
-
-		if (!safe_str_equal (priv->ssl_ca_file, new_ca_file))
-			ca_file_changed = TRUE;
+		if (priv->tlsdb) {
+			g_object_unref (priv->tlsdb);
+			priv->tlsdb = NULL;
+		}
+		g_free (priv->ssl_ca_file);
 
+		priv->ssl_ca_file = g_value_dup_string (value);
+		load_ssl_ca_file (priv);
+		break;
+	case PROP_SSL_USE_SYSTEM_CA_FILE:
+		if (priv->tlsdb) {
+			g_object_unref (priv->tlsdb);
+			priv->tlsdb = NULL;
+		}
 		g_free (priv->ssl_ca_file);
-		priv->ssl_ca_file = g_strdup (new_ca_file);
+		priv->ssl_ca_file = NULL;
 
-		if (ca_file_changed && priv->ssl_creds) {
-			soup_ssl_free_client_credentials (priv->ssl_creds);
-			priv->ssl_creds = NULL;
+		priv->tlsdb = g_tls_backend_get_default_database (g_tls_backend_get_default ());
+		break;
+	case PROP_TLS_DATABASE:
+		if (priv->tlsdb) {
+			g_object_unref (priv->tlsdb);
+			priv->tlsdb = NULL;
 		}
+		g_free (priv->ssl_ca_file);
+		priv->ssl_ca_file = NULL;
 
+		priv->tlsdb = g_value_dup_object (value);
 		break;
 	case PROP_SSL_STRICT:
 		priv->ssl_strict = g_value_get_boolean (value);
@@ -981,6 +1076,7 @@ get_property (GObject *object, guint prop_id,
 	SoupSession *session = SOUP_SESSION (object);
 	SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
 	SoupSessionFeature *feature;
+	GTlsDatabase *tlsdb;
 
 	switch (prop_id) {
 	case PROP_PROXY_URI:
@@ -1008,6 +1104,14 @@ get_property (GObject *object, guint prop_id,
 	case PROP_SSL_CA_FILE:
 		g_value_set_string (value, priv->ssl_ca_file);
 		break;
+	case PROP_SSL_USE_SYSTEM_CA_FILE:
+		tlsdb = g_tls_backend_get_default_database (g_tls_backend_get_default ());
+		g_value_set_boolean (value, priv->tlsdb == tlsdb);
+		g_object_unref (tlsdb);
+		break;
+	case PROP_TLS_DATABASE:
+		g_value_set_object (value, priv->tlsdb);
+		break;
 	case PROP_SSL_STRICT:
 		g_value_set_boolean (value, priv->ssl_strict);
 		break;
@@ -1388,7 +1492,6 @@ soup_session_get_connection (SoupSession *session,
 	SoupConnection *conn;
 	SoupSessionHost *host;
 	SoupAddress *remote_addr, *tunnel_addr;
-	SoupSSLCredentials *ssl_creds;
 	GSList *conns;
 	int num_pending = 0;
 	SoupURI *uri;
@@ -1439,21 +1542,15 @@ soup_session_get_connection (SoupSession *session,
 	}
 
 	uri = soup_message_get_uri (item->msg);
-	if (uri->scheme == SOUP_URI_SCHEME_HTTPS) {
-		if (!priv->ssl_creds)
-			priv->ssl_creds = soup_ssl_get_client_credentials (priv->ssl_ca_file);
-		ssl_creds = priv->ssl_creds;
-
-		if (item->proxy_addr)
-			tunnel_addr = host->addr;
-	} else
-		ssl_creds = NULL;
+	if (uri->scheme == SOUP_URI_SCHEME_HTTPS && item->proxy_addr)
+		tunnel_addr = host->addr;
 
 	conn = soup_connection_new (
 		SOUP_CONNECTION_REMOTE_ADDRESS, remote_addr,
 		SOUP_CONNECTION_TUNNEL_ADDRESS, tunnel_addr,
 		SOUP_CONNECTION_PROXY_URI, item->proxy_uri,
-		SOUP_CONNECTION_SSL_CREDENTIALS, ssl_creds,
+		SOUP_CONNECTION_SSL, uri->scheme == SOUP_URI_SCHEME_HTTPS,
+		SOUP_CONNECTION_SSL_CREDENTIALS, priv->tlsdb,
 		SOUP_CONNECTION_SSL_STRICT, priv->ssl_strict,
 		SOUP_CONNECTION_ASYNC_CONTEXT, priv->async_context,
 		SOUP_CONNECTION_TIMEOUT, priv->io_timeout,
diff --git a/libsoup/soup-session.h b/libsoup/soup-session.h
index 7ad1d16..a7aab0e 100644
--- a/libsoup/soup-session.h
+++ b/libsoup/soup-session.h
@@ -64,6 +64,8 @@ GType soup_session_get_type (void);
 #define SOUP_SESSION_MAX_CONNS_PER_HOST     "max-conns-per-host"
 #define SOUP_SESSION_USE_NTLM               "use-ntlm"
 #define SOUP_SESSION_SSL_CA_FILE            "ssl-ca-file"
+#define SOUP_SESSION_SSL_USE_SYSTEM_CA_FILE "ssl-use-system-ca-file"
+#define SOUP_SESSION_TLS_DATABASE           "tls-database"
 #define SOUP_SESSION_SSL_STRICT             "ssl-strict"
 #define SOUP_SESSION_ASYNC_CONTEXT          "async-context"
 #define SOUP_SESSION_TIMEOUT                "timeout"
diff --git a/libsoup/soup-socket.c b/libsoup/soup-socket.c
index 8821cae..19991bd 100644
--- a/libsoup/soup-socket.c
+++ b/libsoup/soup-socket.c
@@ -21,7 +21,6 @@
 #include "soup-marshal.h"
 #include "soup-misc.h"
 #include "soup-misc-private.h"
-#include "soup-ssl.h"
 
 /**
  * SECTION:soup-socket
@@ -79,7 +78,6 @@ typedef struct {
 	guint ssl_fallback:1;
 	guint clean_dispose:1;
 	gpointer ssl_creds;
-	gboolean ssl_ca_in_creds;
 
 	GMainContext   *async_context;
 	GSource        *watch_src;
@@ -346,6 +344,10 @@ soup_socket_class_init (SoupSocketClass *socket_class)
 	 * Alias for the #SoupSocket:ssl-creds property.
 	 * (SSL credential information.)
 	 **/
+	/* For historical reasons, there's only a single property
+	 * here, which is a GTlsDatabase for client sockets, and
+	 * a GTlsCertificate for server sockets. Whee!
+	 */
 	g_object_class_install_property (
 		object_class, PROP_SSL_CREDENTIALS,
 		g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
@@ -882,8 +884,6 @@ soup_socket_peer_certificate_changed (GObject *conn, GParamSpec *pspec,
 	SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
 
 	priv->tls_errors = g_tls_connection_get_peer_certificate_errors (G_TLS_CONNECTION (priv->conn));
-	if (priv->ssl_ca_in_creds)
-		priv->tls_errors &= ~G_TLS_CERTIFICATE_UNKNOWN_CA;
 
 	g_object_notify (sock, "tls-certificate");
 	g_object_notify (sock, "tls-errors");
@@ -893,14 +893,7 @@ static gboolean
 soup_socket_accept_certificate (GTlsConnection *conn, GTlsCertificate *cert,
 				GTlsCertificateFlags errors, gpointer sock)
 {
-	SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
-
-	if (soup_ssl_credentials_verify_certificate (priv->ssl_creds,
-						     cert, errors,
-						     &priv->ssl_ca_in_creds))
-		return TRUE;
-
-	return !priv->ssl_strict;
+	return TRUE;
 }
 
 /**
@@ -940,8 +933,6 @@ soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
 
 	if (G_IS_TLS_CONNECTION (priv->conn))
 		return TRUE;
-	if (!priv->ssl_creds)
-		return FALSE;
 
 	if (!priv->is_server) {
 		GTlsClientConnection *conn;
@@ -952,7 +943,7 @@ soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
 				       NULL, NULL,
 				       "base-io-stream", priv->conn,
 				       "server-identity", identity,
-				       "use-system-certdb", FALSE,
+				       "database", priv->ssl_creds,
 				       "require-close-notify", FALSE,
 				       "use-ssl3", priv->ssl_fallback,
 				       NULL);
@@ -964,16 +955,18 @@ soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
 		g_object_unref (priv->conn);
 		priv->conn = G_IO_STREAM (conn);
 
-		g_signal_connect (conn, "accept-certificate",
-				  G_CALLBACK (soup_socket_accept_certificate),
-				  sock);
+		if (!priv->ssl_strict) {
+			g_signal_connect (conn, "accept-certificate",
+					  G_CALLBACK (soup_socket_accept_certificate),
+					  sock);
+		}
 	} else {
 		GTlsServerConnection *conn;
 
 		conn = g_initable_new (g_tls_backend_get_server_connection_type (backend),
 				       NULL, NULL,
 				       "base-io-stream", priv->conn,
-				       "certificate", soup_ssl_credentials_get_certificate (priv->ssl_creds),
+				       "certificate", priv->ssl_creds,
 				       "use-system-certdb", FALSE,
 				       "require-close-notify", FALSE,
 				       NULL);
@@ -984,7 +977,6 @@ soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
 		priv->conn = G_IO_STREAM (conn);
 	}
 
-	priv->ssl_ca_in_creds = FALSE;
 	g_signal_connect (priv->conn, "notify::peer-certificate",
 			  G_CALLBACK (soup_socket_peer_certificate_changed), sock);
 
@@ -1270,9 +1262,6 @@ read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
 							  cancellable);
 		}
 		return SOUP_SOCKET_WOULD_BLOCK;
-	} else if (g_error_matches (my_err, G_TLS_ERROR, G_TLS_ERROR_HANDSHAKE)) {
-		my_err->domain = SOUP_SSL_ERROR;
-		my_err->code = SOUP_SSL_ERROR_CERTIFICATE;
 	}
 
 	g_propagate_error (error, my_err);
@@ -1536,9 +1525,6 @@ soup_socket_write (SoupSocket *sock, gconstpointer buffer,
 						  G_IO_OUT,
 						  socket_write_watch, sock, cancellable);
 		return SOUP_SOCKET_WOULD_BLOCK;
-	} else if (g_error_matches (my_err, G_TLS_ERROR, G_TLS_ERROR_HANDSHAKE)) {
-		my_err->domain = SOUP_SSL_ERROR;
-		my_err->code = SOUP_SSL_ERROR_CERTIFICATE;
 	}
 
 	g_mutex_unlock (priv->iolock);



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