[libsoup/carlosgc/ssl: 5/5] message: add SoupMessage::accept-certificate signal




commit caec297088b6ee463c0006416863205c9c278fa1
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Tue Nov 3 13:59:12 2020 +0100

    message: add SoupMessage::accept-certificate signal
    
    And remove the SoupSession:ssl-strict property, apps can connect to
    accept-certificate and return TRUE to accept certificates with errors.
    soup_message_get_https_status has been replaced by property getters and
    both properties are now read only.

 docs/reference/libsoup-3.0-sections.txt |   3 +-
 libsoup/hsts/soup-hsts-enforcer.c       |   2 +-
 libsoup/soup-connection.c               |  95 +++++++++++++--
 libsoup/soup-connection.h               |   2 +
 libsoup/soup-message-io.c               |   2 +-
 libsoup/soup-message-private.h          |   7 --
 libsoup/soup-message.c                  | 206 +++++++++++++++++++++-----------
 libsoup/soup-message.h                  |   9 +-
 libsoup/soup-session.c                  |  74 +-----------
 libsoup/soup-socket-properties.c        |   2 -
 libsoup/soup-socket-properties.h        |   2 -
 tests/no-ssl-test.c                     |   8 +-
 tests/proxy-test.c                      |  11 +-
 tests/ssl-test.c                        |  22 ++--
 14 files changed, 260 insertions(+), 185 deletions(-)
---
diff --git a/docs/reference/libsoup-3.0-sections.txt b/docs/reference/libsoup-3.0-sections.txt
index cac66b2f..60858556 100644
--- a/docs/reference/libsoup-3.0-sections.txt
+++ b/docs/reference/libsoup-3.0-sections.txt
@@ -24,7 +24,8 @@ soup_message_get_response_headers
 soup_message_set_status
 soup_message_set_status_full
 soup_message_is_keepalive
-soup_message_get_https_status
+soup_message_get_tls_certificate
+soup_message_get_tls_certificate_errors
 <SUBSECTION>
 soup_message_set_first_party
 soup_message_get_first_party
diff --git a/libsoup/hsts/soup-hsts-enforcer.c b/libsoup/hsts/soup-hsts-enforcer.c
index 25b89a50..3deb0c63 100644
--- a/libsoup/hsts/soup-hsts-enforcer.c
+++ b/libsoup/hsts/soup-hsts-enforcer.c
@@ -511,7 +511,7 @@ on_sts_known_host_message_starting (SoupMessage *msg, SoupHSTSEnforcer *hsts_enf
           any errors with the underlying secure transport for STS
           known hosts. */
 
-       soup_message_get_https_status (msg, NULL, &errors);
+       errors = soup_message_get_tls_certificate_errors (msg);
        if (errors)
                soup_session_cancel_message (priv->session, msg, SOUP_STATUS_CANCELLED);
 }
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index b9870971..9b50054c 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -43,6 +43,7 @@ G_DEFINE_TYPE_WITH_PRIVATE (SoupConnection, soup_connection, G_TYPE_OBJECT)
 
 enum {
        EVENT,
+       ACCEPT_CERTIFICATE,
        DISCONNECTED,
        LAST_SIGNAL
 };
@@ -56,6 +57,8 @@ enum {
        PROP_SOCKET_PROPERTIES,
        PROP_STATE,
        PROP_SSL,
+       PROP_TLS_CERTIFICATE,
+       PROP_TLS_CERTIFICATE_ERRORS,
 
        LAST_PROP
 };
@@ -154,6 +157,12 @@ soup_connection_get_property (GObject *object, guint prop_id,
        case PROP_SSL:
                g_value_set_boolean (value, priv->ssl);
                break;
+       case PROP_TLS_CERTIFICATE:
+               g_value_set_object (value, soup_connection_get_tls_certificate (SOUP_CONNECTION (object)));
+               break;
+       case PROP_TLS_CERTIFICATE_ERRORS:
+               g_value_set_flags (value, soup_connection_get_tls_certificate_errors (SOUP_CONNECTION 
(object)));
+               break;
        default:
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                break;
@@ -182,6 +191,16 @@ soup_connection_class_init (SoupConnectionClass *connection_class)
                              G_TYPE_NONE, 2,
                              G_TYPE_SOCKET_CLIENT_EVENT,
                              G_TYPE_IO_STREAM);
+       signals[ACCEPT_CERTIFICATE] =
+               g_signal_new ("accept-certificate",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_LAST,
+                              0,
+                              g_signal_accumulator_true_handled, NULL,
+                              NULL,
+                              G_TYPE_BOOLEAN, 2,
+                              G_TYPE_TLS_CERTIFICATE,
+                              G_TYPE_TLS_CERTIFICATE_FLAGS);
        signals[DISCONNECTED] =
                g_signal_new ("disconnected",
                              G_OBJECT_CLASS_TYPE (object_class),
@@ -223,6 +242,22 @@ soup_connection_class_init (SoupConnectionClass *connection_class)
                                      "Whether the connection should use TLS",
                                      FALSE,G_PARAM_READWRITE |
                                      G_PARAM_STATIC_STRINGS));
+       g_object_class_install_property (
+                object_class, PROP_TLS_CERTIFICATE,
+               g_param_spec_object ("tls-certificate",
+                                     "TLS Certificate",
+                                     "The TLS certificate associated with the connection",
+                                     G_TYPE_TLS_CERTIFICATE,
+                                     G_PARAM_READABLE |
+                                    G_PARAM_STATIC_STRINGS));
+       g_object_class_install_property (
+                object_class, PROP_TLS_CERTIFICATE_ERRORS,
+                g_param_spec_flags ("tls-certificate-errors",
+                                    "TLS Certificate Errors",
+                                    "The verification errors on the connections's TLS certificate",
+                                    G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
+                                    G_PARAM_READABLE |
+                                    G_PARAM_STATIC_STRINGS));
 }
 
 static void
@@ -378,12 +413,21 @@ new_socket_client (SoupConnection *conn)
 }
 
 static gboolean
-tls_connection_accept_certificate (GTlsConnection      *conn,
-                                   GTlsCertificate     *cert,
-                                   GTlsCertificateFlags errors,
-                                   gpointer             user_data)
+tls_connection_accept_certificate (SoupConnection      *conn,
+                                   GTlsCertificate     *tls_certificate,
+                                   GTlsCertificateFlags tls_errors)
 {
-        return TRUE;
+       gboolean accept = FALSE;
+
+        g_signal_emit (conn, signals[ACCEPT_CERTIFICATE], 0,
+                      tls_certificate, tls_errors, &accept);
+        return accept;
+}
+
+static void
+tls_connection_peer_certificate_changed (SoupConnection *conn)
+{
+       g_object_notify (G_OBJECT (conn), "tls-certificate");
 }
 
 static GTlsClientConnection *
@@ -405,11 +449,12 @@ new_tls_connection (SoupConnection    *conn,
         if (!tls_connection)
                 return NULL;
 
-        if (!priv->socket_props->ssl_strict) {
-                g_signal_connect_object (tls_connection, "accept-certificate",
-                                         G_CALLBACK (tls_connection_accept_certificate),
-                                         conn, 0);
-        }
+       g_signal_connect_object (tls_connection, "accept-certificate",
+                                G_CALLBACK (tls_connection_accept_certificate),
+                                conn, G_CONNECT_SWAPPED);
+       g_signal_connect_object (tls_connection, "notify::peer-certificate",
+                                G_CALLBACK (tls_connection_peer_certificate_changed),
+                                conn, G_CONNECT_SWAPPED);
 
         return tls_connection;
 }
@@ -1014,3 +1059,33 @@ soup_connection_send_request (SoupConnection           *conn,
 
        soup_message_send_request (item, completion_cb, user_data);
 }
+
+GTlsCertificate *
+soup_connection_get_tls_certificate (SoupConnection *conn)
+{
+       SoupConnectionPrivate *priv;
+
+       g_return_val_if_fail (SOUP_IS_CONNECTION (conn), NULL);
+
+       priv = soup_connection_get_instance_private (conn);
+
+       if (!G_IS_TLS_CONNECTION (priv->connection))
+               return NULL;
+
+       return g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (priv->connection));
+}
+
+GTlsCertificateFlags
+soup_connection_get_tls_certificate_errors (SoupConnection *conn)
+{
+       SoupConnectionPrivate *priv;
+
+       g_return_val_if_fail (SOUP_IS_CONNECTION (conn), 0);
+
+       priv = soup_connection_get_instance_private (conn);
+
+       if (!G_IS_TLS_CONNECTION (priv->connection))
+               return 0;
+
+       return g_tls_connection_get_peer_certificate_errors (G_TLS_CONNECTION (priv->connection));
+}
diff --git a/libsoup/soup-connection.h b/libsoup/soup-connection.h
index 53b67337..c372a731 100644
--- a/libsoup/soup-connection.h
+++ b/libsoup/soup-connection.h
@@ -70,6 +70,8 @@ void            soup_connection_send_request   (SoupConnection           *conn,
                                                SoupMessageIOCompletionFn completion_cb,
                                                gpointer                  user_data);
 
+GTlsCertificate     *soup_connection_get_tls_certificate        (SoupConnection *conn);
+GTlsCertificateFlags soup_connection_get_tls_certificate_errors (SoupConnection *conn);
 G_END_DECLS
 
 #endif /* __SOUP_CONNECTION_H__ */
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index 9859c0ef..6a83d37a 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -776,7 +776,7 @@ io_run_until (SoupMessage *msg, gboolean blocking,
                                               "wrote %" G_GOFFSET_FORMAT "B, "
                                               "Last-Modified: %s, "
                                               "ETag: %s",
-                                              soup_message_get_https_status (msg, NULL, NULL) ? "HTTPS" : 
"HTTP",
+                                              soup_message_get_tls_certificate (msg) ? "HTTPS" : "HTTP",
                                               uri_str, io->read_length, io->write_length,
                                               (last_modified != NULL) ? last_modified : "(unset)",
                                               (etag != NULL) ? etag : "(unset)");
diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h
index a7436f8c..21fae495 100644
--- a/libsoup/soup-message-private.h
+++ b/libsoup/soup-message-private.h
@@ -109,13 +109,6 @@ gboolean soup_message_disables_feature (SoupMessage *msg,
 
 GList *soup_message_get_disabled_features (SoupMessage *msg);
 
-void soup_message_set_https_status (SoupMessage    *msg,
-                                   SoupConnection *conn);
-
-void soup_message_network_event (SoupMessage         *msg,
-                                GSocketClientEvent   event,
-                                GIOStream           *connection);
-
 GInputStream *soup_message_setup_body_istream (GInputStream *body_stream,
                                               SoupMessage *msg,
                                               SoupSession *session,
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index 48b87ce5..9ef8e362 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -86,7 +86,7 @@ typedef struct {
        SoupURI           *site_for_cookies;
 
        GTlsCertificate      *tls_certificate;
-       GTlsCertificateFlags  tls_errors;
+       GTlsCertificateFlags  tls_certificate_errors;
 
        SoupMessagePriority priority;
 
@@ -111,6 +111,7 @@ enum {
 
        AUTHENTICATE,
        NETWORK_EVENT,
+       ACCEPT_CERTIFICATE,
 
        LAST_SIGNAL
 };
@@ -130,7 +131,7 @@ enum {
        PROP_REQUEST_HEADERS,
        PROP_RESPONSE_HEADERS,
        PROP_TLS_CERTIFICATE,
-       PROP_TLS_ERRORS,
+       PROP_TLS_CERTIFICATE_ERRORS,
        PROP_PRIORITY,
        PROP_SITE_FOR_COOKIES,
        PROP_IS_TOP_LEVEL_NAVIGATION,
@@ -156,6 +157,8 @@ soup_message_finalize (GObject *object)
        SoupMessage *msg = SOUP_MESSAGE (object);
        SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
 
+       soup_message_set_connection (msg, NULL);
+
        soup_client_message_io_data_free (priv->io_data);
 
        g_clear_pointer (&priv->uri, soup_uri_free);
@@ -214,22 +217,6 @@ soup_message_set_property (GObject *object, guint prop_id,
        case PROP_FIRST_PARTY:
                soup_message_set_first_party (msg, g_value_get_boxed (value));
                break;
-       case PROP_TLS_CERTIFICATE:
-               if (priv->tls_certificate)
-                       g_object_unref (priv->tls_certificate);
-               priv->tls_certificate = g_value_dup_object (value);
-               if (priv->tls_errors)
-                       priv->msg_flags &= ~SOUP_MESSAGE_CERTIFICATE_TRUSTED;
-               else if (priv->tls_certificate)
-                       priv->msg_flags |= SOUP_MESSAGE_CERTIFICATE_TRUSTED;
-               break;
-       case PROP_TLS_ERRORS:
-               priv->tls_errors = g_value_get_flags (value);
-               if (priv->tls_errors)
-                       priv->msg_flags &= ~SOUP_MESSAGE_CERTIFICATE_TRUSTED;
-               else if (priv->tls_certificate)
-                       priv->msg_flags |= SOUP_MESSAGE_CERTIFICATE_TRUSTED;
-               break;
        case PROP_PRIORITY:
                priv->priority = g_value_get_enum (value);
                break;
@@ -283,8 +270,8 @@ soup_message_get_property (GObject *object, guint prop_id,
        case PROP_TLS_CERTIFICATE:
                g_value_set_object (value, priv->tls_certificate);
                break;
-       case PROP_TLS_ERRORS:
-               g_value_set_flags (value, priv->tls_errors);
+       case PROP_TLS_CERTIFICATE_ERRORS:
+               g_value_set_flags (value, priv->tls_certificate_errors);
                break;
        case PROP_PRIORITY:
                g_value_set_enum (value, priv->priority);
@@ -572,6 +559,32 @@ soup_message_class_init (SoupMessageClass *message_class)
                              G_TYPE_SOCKET_CLIENT_EVENT,
                              G_TYPE_IO_STREAM);
 
+       /**
+        * SoupMessage::accept-certificate:
+        * @msg: the message
+        * @tls_certificate: the peer's #GTlsCertificate
+        * @tls_errors: the tls errors of @tls_certificate
+        *
+        * Emitted during the @msg's connection TLS handshake
+        * after an unacceptable TLS certificate has been received.
+        * You can return %TRUE to accept @tls_certificate despite
+        * @tls_errors.
+        *
+        * Returns: %TRUE to accept the TLS certificate and stop other
+        *     handlers from being invoked, or %FALSE to propagate the
+        *     event further.
+        */
+       signals[ACCEPT_CERTIFICATE] =
+               g_signal_new ("accept-certificate",
+                             G_OBJECT_CLASS_TYPE (object_class),
+                             G_SIGNAL_RUN_LAST,
+                             0,
+                             g_signal_accumulator_true_handled, NULL,
+                             NULL,
+                             G_TYPE_BOOLEAN, 2,
+                             G_TYPE_TLS_CERTIFICATE,
+                             G_TYPE_TLS_CERTIFICATE_FLAGS);
+
        /* properties */
        g_object_class_install_property (
                object_class, PROP_METHOD,
@@ -689,29 +702,29 @@ soup_message_class_init (SoupMessageClass *message_class)
         * The #GTlsCertificate associated with the message
         *
         * Since: 2.34
-        */      
+        */
        g_object_class_install_property (
                object_class, PROP_TLS_CERTIFICATE,
                g_param_spec_object ("tls-certificate",
                                     "TLS Certificate",
                                     "The TLS certificate associated with the message",
                                     G_TYPE_TLS_CERTIFICATE,
-                                    G_PARAM_READWRITE |
+                                    G_PARAM_READABLE |
                                     G_PARAM_STATIC_STRINGS));
        /**
-        * SoupMessage:tls-errors:
+        * SoupMessage:tls-certificate-errors:
         *
         * The verification errors on #SoupMessage:tls-certificate
         *
         * Since: 2.34
-        */      
+        */
        g_object_class_install_property (
-               object_class, PROP_TLS_ERRORS,
-               g_param_spec_flags ("tls-errors",
-                                   "TLS Errors",
+               object_class, PROP_TLS_CERTIFICATE_ERRORS,
+               g_param_spec_flags ("tls-certificate-errors",
+                                   "TLS Certificate Errors",
                                    "The verification errors on the message's TLS certificate",
                                    G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
-                                   G_PARAM_READWRITE |
+                                   G_PARAM_READABLE |
                                    G_PARAM_STATIC_STRINGS));
        /**
         SoupMessage:priority:
@@ -919,15 +932,6 @@ soup_message_finished (SoupMessage *msg)
        g_signal_emit (msg, signals[FINISHED], 0);
 }
 
-void
-soup_message_network_event (SoupMessage         *msg,
-                           GSocketClientEvent   event,
-                           GIOStream           *connection)
-{
-       g_signal_emit (msg, signals[NETWORK_EVENT], 0,
-                      event, connection);
-}
-
 gboolean
 soup_message_authenticate (SoupMessage *msg,
                           SoupAuth    *auth,
@@ -1136,13 +1140,79 @@ soup_message_get_connection (SoupMessage *msg)
        return priv->connection;
 }
 
+static void
+re_emit_connection_event (SoupMessage       *msg,
+                          GSocketClientEvent event,
+                          GIOStream         *connection)
+{
+       g_signal_emit (msg, signals[NETWORK_EVENT], 0,
+                      event, connection);
+}
+
+static gboolean
+re_emit_accept_certificate (SoupMessage          *msg,
+                           GTlsCertificate      *tls_certificate,
+                           GTlsCertificateFlags *tls_errors)
+{
+       gboolean accept = FALSE;
+
+       g_signal_emit (msg, signals[ACCEPT_CERTIFICATE], 0,
+                      tls_certificate, tls_errors, &accept);
+       return accept;
+}
+
+static void
+re_emit_tls_certificate_changed (SoupMessage    *msg,
+                                GParamSpec     *pspec,
+                                SoupConnection *conn)
+{
+       SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
+       GTlsCertificate *tls_certificate;
+       GTlsCertificateFlags tls_errors;
+
+       tls_certificate = soup_connection_get_tls_certificate (conn);
+       tls_errors = soup_connection_get_tls_certificate_errors (conn);
+       if (priv->tls_certificate == tls_certificate && priv->tls_certificate_errors == tls_errors)
+               return;
+
+       g_clear_object (&priv->tls_certificate);
+       priv->tls_certificate = tls_certificate ? g_object_ref (tls_certificate) : NULL;
+       priv->tls_certificate_errors = tls_errors;
+       if (priv->tls_certificate_errors)
+               priv->msg_flags &= ~SOUP_MESSAGE_CERTIFICATE_TRUSTED;
+       else if (priv->tls_certificate)
+               priv->msg_flags |= SOUP_MESSAGE_CERTIFICATE_TRUSTED;
+       g_object_notify (G_OBJECT (msg), "tls-certificate");
+       g_object_notify (G_OBJECT (msg), "tls-certificate-errors");
+}
+
 void
 soup_message_set_connection (SoupMessage    *msg,
                             SoupConnection *conn)
 {
        SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
 
+       if (priv->connection) {
+               g_signal_handlers_disconnect_by_data (priv->connection, msg);
+               g_object_remove_weak_pointer (G_OBJECT (priv->connection), (gpointer*)&priv->connection);
+       }
+
        priv->connection = conn;
+       if (!priv->connection)
+               return;
+
+       g_object_add_weak_pointer (G_OBJECT (priv->connection), (gpointer*)&priv->connection);
+       re_emit_tls_certificate_changed (msg, NULL, conn);
+
+       g_signal_connect_object (priv->connection, "event",
+                                G_CALLBACK (re_emit_connection_event),
+                                msg, G_CONNECT_SWAPPED);
+       g_signal_connect_object (priv->connection, "accept-certificate",
+                                G_CALLBACK (re_emit_accept_certificate),
+                                msg, G_CONNECT_SWAPPED);
+       g_signal_connect_object (priv->connection, "notify::tls-certificate",
+                                G_CALLBACK (re_emit_tls_certificate_changed),
+                                msg, G_CONNECT_SWAPPED);
 }
 
 /**
@@ -1174,7 +1244,7 @@ soup_message_cleanup_response (SoupMessage *msg)
        g_object_notify (G_OBJECT (msg), "http-version");
        g_object_notify (G_OBJECT (msg), "flags");
        g_object_notify (G_OBJECT (msg), "tls-certificate");
-       g_object_notify (G_OBJECT (msg), "tls-errors");
+       g_object_notify (G_OBJECT (msg), "tls-certificate-errors");
 }
 
 /**
@@ -1697,53 +1767,49 @@ soup_message_get_is_top_level_navigation (SoupMessage *msg)
        return priv->is_top_level_navigation;
 }
 
-void
-soup_message_set_https_status (SoupMessage *msg, SoupConnection *conn)
+/**
+ * soup_message_get_tls_certificate:
+ * @msg: a #SoupMessage
+ *
+ * Gets the #GTlsCertificate associated with @msg's connection.
+ * Note that this is not set yet during the emission of
+ * SoupMessage::accept-certificate signal.
+ *
+ * Returns: (transfer none) (nullable): @msg's TLS certificate,
+ *    or %NULL if @msg's connection is not SSL.
+ */
+GTlsCertificate *
+soup_message_get_tls_certificate (SoupMessage *msg)
 {
-       GTlsCertificate *certificate = NULL;
-       GTlsCertificateFlags errors = 0;
+       SoupMessagePrivate *priv;
 
-       if (conn)
-               soup_connection_get_tls_info (conn, &certificate, &errors);
+       g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
+
+       priv = soup_message_get_instance_private (msg);
 
-       g_object_set (msg,
-                     "tls-certificate", certificate,
-                     "tls-errors", errors,
-                     NULL);
+       return priv->tls_certificate;
 }
 
 /**
- * soup_message_get_https_status:
+ * soup_message_get_tls_certificate_errors:
  * @msg: a #SoupMessage
- * @certificate: (out) (transfer none): @msg's TLS certificate
- * @errors: (out): the verification status of @certificate
- *
- * If @msg is using https (or attempted to use https but got
- * %SOUP_STATUS_SSL_FAILED), this retrieves the #GTlsCertificate
- * associated with its connection, and the #GTlsCertificateFlags
- * showing what problems, if any, have been found with that
- * certificate.
  *
- * Return value: %TRUE if @msg used/attempted https, %FALSE if not
+ * Gets the errors associated with validating @msg's TLS certificate.
+ * Note that this is not set yet during the emission of
+ * SoupMessage::accept-certificate signal.
  *
- * Since: 2.34
+ * Returns: a #GTlsCertificateFlags with @msg's TLS certificate errors.
  */
-gboolean
-soup_message_get_https_status (SoupMessage           *msg,
-                              GTlsCertificate      **certificate,
-                              GTlsCertificateFlags  *errors)
+GTlsCertificateFlags
+soup_message_get_tls_certificate_errors (SoupMessage *msg)
 {
-       SoupMessagePrivate *priv;
+        SoupMessagePrivate *priv;
 
-       g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
+        g_return_val_if_fail (SOUP_IS_MESSAGE (msg), 0);
 
        priv = soup_message_get_instance_private (msg);
 
-       if (certificate)
-               *certificate = priv->tls_certificate;
-       if (errors)
-               *errors = priv->tls_errors;
-       return priv->tls_certificate != NULL;
+       return priv->tls_certificate_errors;
 }
 
 /**
diff --git a/libsoup/soup-message.h b/libsoup/soup-message.h
index d6fa92aa..3e70dfbc 100644
--- a/libsoup/soup-message.h
+++ b/libsoup/soup-message.h
@@ -80,10 +80,11 @@ void             soup_message_set_flags           (SoupMessage           *msg,
 SOUP_AVAILABLE_IN_2_4
 SoupMessageFlags soup_message_get_flags           (SoupMessage           *msg);
 
-SOUP_AVAILABLE_IN_2_34
-gboolean         soup_message_get_https_status    (SoupMessage           *msg,
-                                                  GTlsCertificate      **certificate,
-                                                  GTlsCertificateFlags  *errors);
+SOUP_AVAILABLE_IN_ALL
+GTlsCertificate     *soup_message_get_tls_certificate        (SoupMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+GTlsCertificateFlags soup_message_get_tls_certificate_errors (SoupMessage *msg);
 
 
 /* Specialized signal handlers */
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 0c244495..c4e29502 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -89,7 +89,6 @@ typedef struct {
 
        GTlsDatabase *tlsdb;
        GTlsInteraction *tls_interaction;
-       gboolean ssl_strict;
        gboolean tlsdb_use_default;
 
        guint io_timeout, idle_timeout;
@@ -175,7 +174,6 @@ enum {
        PROP_MAX_CONNS_PER_HOST,
        PROP_SSL_USE_SYSTEM_CA_FILE,
        PROP_TLS_DATABASE,
-       PROP_SSL_STRICT,
        PROP_ASYNC_CONTEXT,
        PROP_TIMEOUT,
        PROP_USER_AGENT,
@@ -248,9 +246,6 @@ soup_session_init (SoupSession *session)
 
         soup_session_add_feature_by_type (session, SOUP_TYPE_CONTENT_DECODER);
 
-       priv->ssl_strict = TRUE;
-
-
         /* If the user overrides the proxy or tlsdb during construction,
                 * we don't want to needlessly resolve the extension point. So
                 * we just set flags saying to do it later.
@@ -333,7 +328,6 @@ ensure_socket_props (SoupSession *session)
                                                         priv->local_addr,
                                                         priv->tlsdb,
                                                         priv->tls_interaction,
-                                                        priv->ssl_strict,
                                                         priv->io_timeout,
                                                         priv->idle_timeout);
 }
@@ -467,10 +461,6 @@ soup_session_set_property (GObject *object, guint prop_id,
                priv->tls_interaction = g_value_dup_object (value);
                socket_props_changed = TRUE;
                break;
-       case PROP_SSL_STRICT:
-               priv->ssl_strict = g_value_get_boolean (value);
-               socket_props_changed = TRUE;
-               break;
        case PROP_TIMEOUT:
                priv->io_timeout = g_value_get_uint (value);
                socket_props_changed = TRUE;
@@ -580,9 +570,6 @@ soup_session_get_property (GObject *object, guint prop_id,
        case PROP_TLS_INTERACTION:
                g_value_set_object (value, priv->tls_interaction);
                break;
-       case PROP_SSL_STRICT:
-               g_value_set_boolean (value, priv->ssl_strict);
-               break;
        case PROP_TIMEOUT:
                g_value_set_uint (value, priv->io_timeout);
                break;
@@ -904,36 +891,15 @@ redirect_handler (SoupMessage *msg,
                soup_session_redirect_message (session, msg);
 }
 
-static void
-re_emit_connection_event (SoupConnection      *conn,
-                         GSocketClientEvent   event,
-                         GIOStream           *connection,
-                         gpointer             user_data)
-{
-       SoupMessageQueueItem *item = user_data;
-
-       soup_message_network_event (item->msg, event, connection);
-}
-
 static void
 soup_session_set_item_connection (SoupSession          *session,
                                  SoupMessageQueueItem *item,
                                  SoupConnection       *conn)
 {
-       if (item->conn) {
-               g_signal_handlers_disconnect_by_func (item->conn, re_emit_connection_event, item);
-               g_object_unref (item->conn);
-       }
-
-       item->conn = conn;
+       g_clear_object (&item->conn);
+       item->conn = conn ? g_object_ref (conn) : NULL;
        item->conn_is_dedicated = FALSE;
        soup_message_set_connection (item->msg, conn);
-
-       if (item->conn) {
-               g_object_ref (item->conn);
-               g_signal_connect (item->conn, "event",
-                                 G_CALLBACK (re_emit_connection_event), item);
-       }
 }
 
 static void
@@ -1335,7 +1301,6 @@ tunnel_complete (SoupMessageQueueItem *tunnel_item,
 
        if (soup_message_get_status (item->msg))
                item->state = SOUP_MESSAGE_FINISHING;
-       soup_message_set_https_status (item->msg, item->conn);
 
        item->error = error;
        if (!status)
@@ -1443,8 +1408,6 @@ connect_complete (SoupMessageQueueItem *item, SoupConnection *conn, GError *erro
        SoupSession *session = item->session;
        guint status;
 
-       soup_message_set_https_status (item->msg, item->conn);
-
        if (!error) {
                item->state = SOUP_MESSAGE_CONNECTED;
                return;
@@ -1629,7 +1592,6 @@ get_connection (SoupMessageQueueItem *item, gboolean *should_cleanup)
 
        if (soup_connection_get_state (item->conn) != SOUP_CONNECTION_NEW) {
                item->state = SOUP_MESSAGE_READY;
-               soup_message_set_https_status (item->msg, item->conn);
                return TRUE;
        }
 
@@ -2536,38 +2498,6 @@ soup_session_class_init (SoupSessionClass *session_class)
                                     G_TYPE_TLS_DATABASE,
                                     G_PARAM_READWRITE |
                                     G_PARAM_STATIC_STRINGS));
-       /**
-        * SoupSession:ssl-strict:
-        *
-        * Normally, if #SoupSession:tls-database is set (including if
-        * it was set via #SoupSession:ssl-use-system-ca-file),
-        * then libsoup will reject any
-        * certificate that is invalid (ie, expired) or that is not
-        * signed by one of the given CA certificates, and the
-        * #SoupMessage will fail with the status
-        * %SOUP_STATUS_SSL_FAILED.
-        *
-        * If you set #SoupSession:ssl-strict to %FALSE, then all
-        * certificates will be accepted, and you will need to call
-        * soup_message_get_https_status() to distinguish valid from
-        * invalid certificates. (This can be used, eg, if you want to
-        * accept invalid certificates after giving some sort of
-        * warning.)
-        *
-        * For a plain #SoupSession, if the session has no CA file or
-        * TLS database, and this property is %TRUE, then all
-        * certificates will be rejected.
-        *
-        * Since: 2.30
-        */
-       g_object_class_install_property (
-               object_class, PROP_SSL_STRICT,
-               g_param_spec_boolean ("ssl-strict",
-                                     "Strictly validate SSL certificates",
-                                     "Whether certificate errors should be considered a connection error",
-                                     TRUE,
-                                     G_PARAM_READWRITE |
-                                     G_PARAM_STATIC_STRINGS));
 
        /**
         * SoupSession:timeout:
diff --git a/libsoup/soup-socket-properties.c b/libsoup/soup-socket-properties.c
index bbd55076..622d69d4 100644
--- a/libsoup/soup-socket-properties.c
+++ b/libsoup/soup-socket-properties.c
@@ -15,7 +15,6 @@ soup_socket_properties_new (GProxyResolver     *proxy_resolver,
                            GInetSocketAddress *local_addr,
                            GTlsDatabase       *tlsdb,
                            GTlsInteraction    *tls_interaction,
-                           gboolean            ssl_strict,
                            guint               io_timeout,
                            guint               idle_timeout)
 {
@@ -29,7 +28,6 @@ soup_socket_properties_new (GProxyResolver     *proxy_resolver,
 
        props->tlsdb = tlsdb ? g_object_ref (tlsdb) : NULL;
        props->tls_interaction = tls_interaction ? g_object_ref (tls_interaction) : NULL;
-       props->ssl_strict = ssl_strict;
 
        props->io_timeout = io_timeout;
        props->idle_timeout = idle_timeout;
diff --git a/libsoup/soup-socket-properties.h b/libsoup/soup-socket-properties.h
index 9a43184c..68b26f7f 100644
--- a/libsoup/soup-socket-properties.h
+++ b/libsoup/soup-socket-properties.h
@@ -14,7 +14,6 @@ typedef struct {
 
        GTlsDatabase *tlsdb;
        GTlsInteraction *tls_interaction;
-       gboolean ssl_strict;
 
        guint io_timeout;
        guint idle_timeout;
@@ -30,7 +29,6 @@ SoupSocketProperties *soup_socket_properties_new   (GProxyResolver     *proxy_re
                                                    GInetSocketAddress *local_addr,
                                                    GTlsDatabase       *tlsdb,
                                                    GTlsInteraction    *tls_interaction,
-                                                   gboolean            ssl_strict,
                                                    guint               io_timeout,
                                                    guint               idle_timeout);
 
diff --git a/tests/no-ssl-test.c b/tests/no-ssl-test.c
index 02bec973..43c7a9bb 100644
--- a/tests/no-ssl-test.c
+++ b/tests/no-ssl-test.c
@@ -6,18 +6,12 @@ static void
 do_ssl_test_for_session (SoupSession *session, SoupURI *uri)
 {
        SoupMessage *msg;
-       GTlsCertificate *cert = NULL;
-       GTlsCertificateFlags flags;
-       gboolean is_https;
 
        msg = soup_message_new_from_uri ("GET", uri);
        soup_test_session_send_message (session, msg);
        soup_test_assert_message_status (msg, SOUP_STATUS_SSL_FAILED);
 
-       is_https = soup_message_get_https_status (msg, &cert, &flags);
-       soup_test_assert (!is_https, "get_http_status() returned TRUE? (flags %x)", flags);
-
-       g_assert_null (cert);
+       g_assert_null (soup_message_get_tls_certificate (msg));
        g_assert_false (soup_message_get_flags (msg) & SOUP_MESSAGE_CERTIFICATE_TRUSTED);
 
        g_object_unref (msg);
diff --git a/tests/proxy-test.c b/tests/proxy-test.c
index 57a2e95f..ca947e42 100644
--- a/tests/proxy-test.c
+++ b/tests/proxy-test.c
@@ -90,6 +90,14 @@ set_close_on_connect (SoupMessage *msg,
        }
 }
 
+static gboolean
+accept_certificate (SoupMessage         *msg,
+                   GTlsCertificate     *certificate,
+                   GTlsCertificateFlags errors)
+{
+       return TRUE;
+}
+
 static void
 test_url (const char *url, int proxy, guint expected, gboolean close)
 {
@@ -110,7 +118,6 @@ test_url (const char *url, int proxy, guint expected, gboolean close)
         */
        session = soup_test_session_new (SOUP_TYPE_SESSION,
                                         "proxy-resolver", proxy_resolvers[proxy],
-                                        "ssl-strict", FALSE,
                                         NULL);
 
        msg = soup_message_new (SOUP_METHOD_GET, url);
@@ -121,6 +128,8 @@ test_url (const char *url, int proxy, guint expected, gboolean close)
 
        g_signal_connect (msg, "authenticate",
                           G_CALLBACK (authenticate), NULL);
+       g_signal_connect (msg, "accept-certificate",
+                         G_CALLBACK (accept_certificate), NULL);
 
        if (close) {
                /* FIXME g_test_bug ("611663") */
diff --git a/tests/ssl-test.c b/tests/ssl-test.c
index 3be48ea3..764d0433 100644
--- a/tests/ssl-test.c
+++ b/tests/ssl-test.c
@@ -22,6 +22,14 @@ static const StrictnessTest strictness_tests[] = {
          FALSE, FALSE, SOUP_STATUS_OK },
 };
 
+static gboolean
+accept_certificate (SoupMessage *msg,
+                   GTlsCertificate *certificate,
+                   GTlsCertificateFlags errors)
+{
+       return TRUE;
+}
+
 static void
 do_strictness_test (gconstpointer data)
 {
@@ -34,11 +42,6 @@ do_strictness_test (gconstpointer data)
 
        session = soup_test_session_new (SOUP_TYPE_SESSION,
                                         NULL);
-       if (!test->strict) {
-               g_object_set (G_OBJECT (session),
-                             "ssl-strict", FALSE,
-                             NULL);
-       }
        if (!test->with_ca_list) {
                g_object_set (G_OBJECT (session),
                              "ssl-use-system-ca-file", TRUE,
@@ -46,11 +49,16 @@ do_strictness_test (gconstpointer data)
        }
 
        msg = soup_message_new_from_uri ("GET", uri);
+       if (!test->strict) {
+               g_signal_connect (msg, "accept-certificate",
+                                 G_CALLBACK (accept_certificate), NULL);
+       }
        soup_test_session_send_message (session, msg);
        soup_test_assert_message_status (msg, test->expected_status);
 
        g_test_bug ("690176");
-       g_assert_true (soup_message_get_https_status (msg, NULL, &flags));
+       g_assert_nonnull (soup_message_get_tls_certificate (msg));
+       flags = soup_message_get_tls_certificate_errors (msg);
 
        g_test_bug ("665182");
        if (test->with_ca_list && SOUP_STATUS_IS_SUCCESSFUL (soup_message_get_status (msg)))
@@ -225,7 +233,7 @@ do_tls_interaction_test (void)
        msg = soup_message_new_from_uri ("GET", test_uri);
        body = soup_test_session_async_send (session, msg);
        soup_test_assert_message_status (msg, SOUP_STATUS_OK);
-       g_assert_true (soup_message_get_https_status (msg, NULL, NULL));
+       g_assert_nonnull (soup_message_get_tls_certificate (msg));
        g_bytes_unref (body);
        g_object_unref (msg);
 


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