[glib-networking/glib-2-62] Don't notify accepted-cas property on handshake thread
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/glib-2-62] Don't notify accepted-cas property on handshake thread
- Date: Sun, 22 Sep 2019 21:29:56 +0000 (UTC)
commit 68803c033502f683c551fcc3a21df7d7a165e22f
Author: Michael Catanzaro <mcatanzaro gnome org>
Date: Fri Sep 20 17:51:42 2019 +0000
Don't notify accepted-cas property on handshake thread
This is wrong because application code could wind up running on our
internal thread if it connects to the notify.
Fixes #95
(cherry picked from commit a5edbfce8e87f915679032782dcee85369e23a53)
tls/gnutls/gtlsclientconnection-gnutls.c | 16 +++++++++++++---
tls/openssl/gtlsclientconnection-openssl.c | 22 +++++++++++++++++++++-
2 files changed, 34 insertions(+), 4 deletions(-)
---
diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c
index 384df22..4e2f5b7 100644
--- a/tls/gnutls/gtlsclientconnection-gnutls.c
+++ b/tls/gnutls/gtlsclientconnection-gnutls.c
@@ -58,6 +58,7 @@ struct _GTlsClientConnectionGnutls
GBytes *session_data;
GPtrArray *accepted_cas;
+ gboolean accepted_cas_changed;
gnutls_pcert_st *pcert;
unsigned int pcert_length;
@@ -326,6 +327,7 @@ g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t
GTlsClientConnectionGnutls *gnutls = gnutls_transport_get_ptr (session);
GTlsConnectionGnutls *conn = G_TLS_CONNECTION_GNUTLS (gnutls);
GPtrArray *accepted_cas;
+ gboolean had_accepted_cas;
GByteArray *dn;
int i;
@@ -333,6 +335,8 @@ g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t
* the algorithms given in pk_algos.
*/
+ had_accepted_cas = gnutls->accepted_cas != NULL;
+
accepted_cas = g_ptr_array_new_with_free_func ((GDestroyNotify)g_byte_array_unref);
for (i = 0; i < nreqs; i++)
{
@@ -344,7 +348,8 @@ g_tls_client_connection_gnutls_retrieve_function (gnutls_session_t
if (gnutls->accepted_cas)
g_ptr_array_unref (gnutls->accepted_cas);
gnutls->accepted_cas = accepted_cas;
- g_object_notify (G_OBJECT (gnutls), "accepted-cas");
+
+ gnutls->accepted_cas_changed = gnutls->accepted_cas || had_accepted_cas;
clear_gnutls_certificate_copy (gnutls);
g_tls_connection_gnutls_get_certificate (conn, pcert, pcert_length, pkey);
@@ -445,8 +450,13 @@ g_tls_client_connection_gnutls_complete_handshake (GTlsConnectionBase *tls,
GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (tls);
int resumed;
- G_TLS_CONNECTION_BASE_CLASS (g_tls_client_connection_gnutls_parent_class)->
- complete_handshake (tls, negotiated_protocol, error);
+ G_TLS_CONNECTION_BASE_CLASS (g_tls_client_connection_gnutls_parent_class)->complete_handshake (tls,
negotiated_protocol, error);
+
+ /* It may have changed during the handshake, but we have to wait until here
+ * because we can't emit notifies on the handshake thread.
+ */
+ if (gnutls->accepted_cas_changed)
+ g_object_notify (G_OBJECT (gnutls), "accepted-cas");
resumed = gnutls_session_is_resumed (g_tls_connection_gnutls_get_session (G_TLS_CONNECTION_GNUTLS (tls)));
if (!resumed)
diff --git a/tls/openssl/gtlsclientconnection-openssl.c b/tls/openssl/gtlsclientconnection-openssl.c
index 3926029..06fbd5d 100644
--- a/tls/openssl/gtlsclientconnection-openssl.c
+++ b/tls/openssl/gtlsclientconnection-openssl.c
@@ -52,6 +52,7 @@ struct _GTlsClientConnectionOpenssl
GBytes *session_data;
STACK_OF (X509_NAME) *ca_list;
+ gboolean ca_list_changed;
SSL_SESSION *session;
SSL *ssl;
@@ -235,6 +236,22 @@ g_tls_client_connection_openssl_constructed (GObject *object)
G_OBJECT_CLASS (g_tls_client_connection_openssl_parent_class)->constructed (object);
}
+static void
+g_tls_client_connection_openssl_complete_handshake (GTlsConnectionBase *tls,
+ gchar **negotiated_protocol,
+ GError **error)
+{
+ GTlsClientConnectionOpenssl *client = G_TLS_CLIENT_CONNECTION_OPENSSL (tls);
+
+ G_TLS_CONNECTION_BASE_CLASS (g_tls_client_connection_openssl_parent_class)->complete_handshake (tls,
negotiated_protocol, error);
+
+ /* It may have changed during the handshake, but we have to wait until here
+ * because we can't emit notifies on the handshake thread.
+ */
+ if (client->ca_list_changed)
+ g_object_notify (G_OBJECT (client), "accepted-cas");
+}
+
static GTlsCertificateFlags
verify_ocsp_response (GTlsClientConnectionOpenssl *openssl,
GTlsCertificate *peer_certificate)
@@ -303,6 +320,7 @@ g_tls_client_connection_openssl_class_init (GTlsClientConnectionOpensslClass *kl
gobject_class->set_property = g_tls_client_connection_openssl_set_property;
gobject_class->constructed = g_tls_client_connection_openssl_constructed;
+ base_class->complete_handshake = g_tls_client_connection_openssl_complete_handshake;
base_class->verify_peer_certificate = g_tls_client_connection_openssl_verify_peer_certificate;
openssl_class->get_ssl = g_tls_client_connection_openssl_get_ssl;
@@ -341,12 +359,14 @@ retrieve_certificate (SSL *ssl,
GTlsClientConnectionOpenssl *client;
GTlsConnectionBase *tls;
GTlsCertificate *cert;
+ gboolean had_ca_list;
client = SSL_get_ex_data (ssl, data_index);
tls = G_TLS_CONNECTION_BASE (client);
+ had_ca_list = client->ca_list != NULL;
client->ca_list = SSL_get_client_CA_list (client->ssl);
- g_object_notify (G_OBJECT (client), "accepted-cas");
+ client->ca_list_changed = client->ca_list || had_ca_list;
cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (client));
if (!cert)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]