diff options
author | Carlos Garcia Campos <cgarcia@igalia.com> | 2020-11-03 13:59:12 +0100 |
---|---|---|
committer | Carlos Garcia Campos <cgarcia@igalia.com> | 2020-11-04 06:25:12 +0100 |
commit | 70c1b907432b8ccf2b5fa161448855f6bc88c663 (patch) | |
tree | 43788d60089a32bb4b6ee72dd9fd01f0fcc95e3d | |
parent | 9f357b2283f20c2f39c6095c56ec1747bc4561ad (diff) | |
download | libsoup-70c1b907432b8ccf2b5fa161448855f6bc88c663.tar.gz |
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.
-rw-r--r-- | docs/reference/libsoup-3.0-sections.txt | 3 | ||||
-rw-r--r-- | libsoup/hsts/soup-hsts-enforcer.c | 2 | ||||
-rw-r--r-- | libsoup/soup-connection.c | 95 | ||||
-rw-r--r-- | libsoup/soup-connection.h | 2 | ||||
-rw-r--r-- | libsoup/soup-message-io.c | 2 | ||||
-rw-r--r-- | libsoup/soup-message-private.h | 7 | ||||
-rw-r--r-- | libsoup/soup-message.c | 206 | ||||
-rw-r--r-- | libsoup/soup-message.h | 9 | ||||
-rw-r--r-- | libsoup/soup-session.c | 74 | ||||
-rw-r--r-- | libsoup/soup-socket-properties.c | 2 | ||||
-rw-r--r-- | libsoup/soup-socket-properties.h | 2 | ||||
-rw-r--r-- | tests/no-ssl-test.c | 8 | ||||
-rw-r--r-- | tests/proxy-test.c | 11 | ||||
-rw-r--r-- | 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 5815594d..8059d6ef 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 2c47aed4..9e024de9 100644 --- a/libsoup/hsts/soup-hsts-enforcer.c +++ b/libsoup/hsts/soup-hsts-enforcer.c @@ -517,7 +517,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 4ce6bb25..5df73063 100644 --- a/libsoup/soup-message-io.c +++ b/libsoup/soup-message-io.c @@ -771,7 +771,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 ffeea9a6..8e5c160b 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 ba034832..4a68af2f 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: @@ -920,15 +933,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, @@ -1137,13 +1141,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); } /** @@ -1175,7 +1245,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"); } /** @@ -1701,53 +1771,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 3646e1ac..e0c0a1bb 100644 --- a/libsoup/soup-session.c +++ b/libsoup/soup-session.c @@ -95,7 +95,6 @@ typedef struct { GTlsDatabase *tlsdb; GTlsInteraction *tls_interaction; - gboolean ssl_strict; gboolean tlsdb_use_default; guint io_timeout, idle_timeout; @@ -181,7 +180,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, @@ -254,9 +252,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. @@ -339,7 +334,6 @@ ensure_socket_props (SoupSession *session) priv->local_addr, priv->tlsdb, priv->tls_interaction, - priv->ssl_strict, priv->io_timeout, priv->idle_timeout); } @@ -473,10 +467,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; @@ -586,9 +576,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; @@ -911,35 +898,14 @@ redirect_handler (SoupMessage *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 @@ -1341,7 +1307,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) @@ -1451,8 +1416,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; @@ -1637,7 +1600,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; } @@ -2546,38 +2508,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); |