Use GTlsDatabase, add new SoupSession properties for it
authorDan Winship <danw@gnome.org>
Tue, 13 Sep 2011 00:33:39 +0000 (20:33 -0400)
committerDan Winship <danw@gnome.org>
Thu, 29 Sep 2011 19:14:54 +0000 (15:14 -0400)
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.

13 files changed:
configure.ac
libsoup/Makefile.am
libsoup/soup-connection.c
libsoup/soup-connection.h
libsoup/soup-message-io.c
libsoup/soup-misc.c
libsoup/soup-misc.h
libsoup/soup-server.c
libsoup/soup-session.c
libsoup/soup-session.h
libsoup/soup-socket.c
libsoup/soup-ssl.c [deleted file]
libsoup/soup-ssl.h [deleted file]

index 4d693b5..a0d0f7d 100644 (file)
@@ -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"
 
index 8dc8507..096f0fb 100644 (file)
@@ -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              \
index 514640f..d82832f 100644 (file)
@@ -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 {
index ef304e7..cd663a8 100644 (file)
@@ -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"
index a489788..aa33187 100644 (file)
@@ -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,
index 3136645..5c09526 100644 (file)
@@ -16,6 +16,8 @@
  *
  **/
 
+const gboolean soup_ssl_supported = TRUE;
+
 /**
  * soup_str_case_hash:
  * @key: ASCII string to hash
index 45c8883..0807b5f 100644 (file)
@@ -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,
index aa73580..e44d716 100644 (file)
@@ -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)) {
index cd4bbdd..75d6b1c 100644 (file)
@@ -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,
index 7ad1d16..a7aab0e 100644 (file)
@@ -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"
index 8821cae..19991bd 100644 (file)
@@ -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);
diff --git a/libsoup/soup-ssl.c b/libsoup/soup-ssl.c
deleted file mode 100644 (file)
index 2e0b5fc..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * soup-ssl.c: temporary ssl integration
- *
- * Copyright (C) 2010 Red Hat, Inc.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <gio/gio.h>
-
-#include "soup-ssl.h"
-#include "soup-misc.h"
-
-const gboolean soup_ssl_supported = TRUE;
-
-struct SoupSSLCredentials {
-       GList *ca_list;
-       GTlsCertificateFlags validation_flags;
-       GTlsCertificate *certificate;
-};
-
-SoupSSLCredentials *
-soup_ssl_get_client_credentials (const char *ca_file)
-{
-       SoupSSLCredentials *creds;
-
-       creds = g_slice_new0 (SoupSSLCredentials);
-
-       if (ca_file) {
-               GError *error = NULL;
-
-               creds->ca_list = g_tls_certificate_list_new_from_file (ca_file, &error);
-               if (error) {
-                       if (!g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_UNAVAILABLE)) {
-                               g_warning ("Could not set SSL credentials from '%s': %s",
-                                          ca_file, error->message);
-                       }
-                       g_error_free (error);
-               }
-               creds->validation_flags = G_TLS_CERTIFICATE_VALIDATE_ALL;
-       }
-
-       return creds;
-}
-
-gboolean
-soup_ssl_credentials_verify_certificate (SoupSSLCredentials   *creds,
-                                        GTlsCertificate      *cert,
-                                        GTlsCertificateFlags  errors,
-                                        gboolean             *ca_in_creds)
-{
-       errors = errors & creds->validation_flags;
-
-       *ca_in_creds = FALSE;
-       if (errors & G_TLS_CERTIFICATE_UNKNOWN_CA) {
-               GList *ca;
-
-               for (ca = creds->ca_list; ca; ca = ca->next) {
-                       if ((g_tls_certificate_verify (cert, NULL, ca->data) & G_TLS_CERTIFICATE_UNKNOWN_CA) == 0) {
-                               errors &= ~G_TLS_CERTIFICATE_UNKNOWN_CA;
-                               *ca_in_creds = TRUE;
-                               break;
-                       }
-               }
-       }
-
-       return errors == 0;
-}
-
-void
-soup_ssl_free_client_credentials (SoupSSLCredentials *client_creds)
-{
-       GList *c;
-
-       for (c = client_creds->ca_list; c; c = c->next)
-               g_object_unref (c->data);
-       g_list_free (client_creds->ca_list);
-       g_slice_free (SoupSSLCredentials, client_creds);
-}
-
-SoupSSLCredentials *
-soup_ssl_get_server_credentials (const char *cert_file, const char *key_file)
-{
-       SoupSSLCredentials *creds;
-       GError *error = NULL;
-
-       creds = g_slice_new0 (SoupSSLCredentials);
-
-       creds->certificate = g_tls_certificate_new_from_files (cert_file, key_file, &error);
-       if (!creds->certificate) {
-               g_warning ("Could not read SSL certificate from '%s': %s",
-                          cert_file, error->message);
-               g_error_free (error);
-               g_slice_free (SoupSSLCredentials, creds);
-               return NULL;
-       }
-
-       return creds;
-}
-
-GTlsCertificate *
-soup_ssl_credentials_get_certificate (SoupSSLCredentials *creds)
-{
-       return creds->certificate;
-}
-
-void
-soup_ssl_free_server_credentials (SoupSSLCredentials *server_creds)
-{
-       g_object_unref (server_creds->certificate);
-       g_slice_free (SoupSSLCredentials, server_creds);
-}
-
-/**
- * SOUP_SSL_ERROR:
- *
- * A #GError domain representing an SSL error. Used with #SoupSSLError.
- **/
-/**
- * soup_ssl_error_quark:
- *
- * The quark used as %SOUP_SSL_ERROR
- *
- * Return value: The quark used as %SOUP_SSL_ERROR
- **/
-GQuark
-soup_ssl_error_quark (void)
-{
-       static GQuark error;
-       if (!error)
-               error = g_quark_from_static_string ("soup_ssl_error_quark");
-       return error;
-}
-
-/**
- * SoupSSLError:
- * @SOUP_SSL_ERROR_HANDSHAKE_NEEDS_READ: Internal error. Never exposed
- * outside of libsoup.
- * @SOUP_SSL_ERROR_HANDSHAKE_NEEDS_WRITE: Internal error. Never exposed
- * outside of libsoup.
- * @SOUP_SSL_ERROR_CERTIFICATE: Indicates an error validating an SSL
- * certificate
- * @SOUP_SSL_ERROR_HANDSHAKE_FAILED: Unused
- *
- * SSL-related I/O errors.
- **/
diff --git a/libsoup/soup-ssl.h b/libsoup/soup-ssl.h
deleted file mode 100644 (file)
index eac6de6..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * Copyright (C) 2000-2003, Ximian, Inc.
- */
-
-#ifndef SOUP_SSL_H
-#define SOUP_SSL_H 1
-
-#include "soup-types.h"
-
-typedef enum {
-       SOUP_SSL_TYPE_CLIENT = 0,
-       SOUP_SSL_TYPE_SERVER
-} SoupSSLType;
-
-typedef struct SoupSSLCredentials SoupSSLCredentials;
-
-SoupSSLCredentials   *soup_ssl_get_client_credentials           (const char           *ca_file);
-void                  soup_ssl_free_client_credentials          (SoupSSLCredentials   *creds);
-gboolean              soup_ssl_credentials_verify_certificate   (SoupSSLCredentials   *creds,
-                                                                GTlsCertificate      *cert,
-                                                                GTlsCertificateFlags  errors,
-                                                                gboolean             *ca_in_creds);
-
-SoupSSLCredentials   *soup_ssl_get_server_credentials           (const char           *cert_file,
-                                                                const char           *key_file);
-void                  soup_ssl_free_server_credentials          (SoupSSLCredentials   *creds);
-GTlsCertificate      *soup_ssl_credentials_get_certificate      (SoupSSLCredentials *creds);
-
-#endif /* SOUP_SSL_H */