[glib-networking/mcatanzaro/tls-thread: 13/24] progress
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/tls-thread: 13/24] progress
- Date: Sat, 28 Dec 2019 21:04:34 +0000 (UTC)
commit e21c7b3fe741863443884cd8a9f54d11e079e620
Author: Michael Catanzaro <mcatanzaro gnome org>
Date: Sun Dec 22 15:16:14 2019 -0600
progress
tls/base/gtlsconnection-base.c | 58 ++++--------
tls/base/gtlsconnection-base.h | 7 +-
tls/base/gtlsoperationsthread-base.c | 154 +++++++++++++++++++++++++------
tls/base/gtlsoperationsthread-base.h | 11 +++
tls/gnutls/gtlsoperationsthread-gnutls.c | 10 +-
5 files changed, 160 insertions(+), 80 deletions(-)
---
diff --git a/tls/base/gtlsconnection-base.c b/tls/base/gtlsconnection-base.c
index a79ae93..71667ca 100644
--- a/tls/base/gtlsconnection-base.c
+++ b/tls/base/gtlsconnection-base.c
@@ -90,8 +90,6 @@ typedef struct
GTlsInteraction *interaction;
GTlsCertificate *certificate;
- gboolean missing_requested_client_certificate;
- GError *interaction_error;
GTlsCertificate *peer_certificate;
GTlsCertificateFlags peer_certificate_errors;
@@ -248,7 +246,9 @@ g_tls_connection_base_initable_init (GInitable *initable,
priv->thread = G_TLS_CONNECTION_BASE_GET_CLASS (tls)->create_op_thread (tls);
if (priv->certificate)
- g_tls_operations_thread_base_set_own_certificate (priv->certificate);
+ g_tls_operations_thread_base_set_own_certificate (priv->thread, priv->certificate);
+ if (priv->interaction)
+ g_tls_operations_thread_base_set_interaction (priv->thread, priv->interaction);
return TRUE;
}
@@ -269,7 +269,6 @@ g_tls_connection_base_finalize (GObject *object)
g_clear_object (&priv->database);
g_clear_object (&priv->certificate);
- g_clear_error (&priv->interaction_error);
g_clear_object (&priv->peer_certificate);
g_mutex_clear (&priv->verify_certificate_mutex);
@@ -454,12 +453,17 @@ g_tls_connection_base_set_property (GObject *object,
priv->certificate = g_value_dup_object (value);
if (priv->thread)
- g_tls_operations_thread_base_set_own_certificate (priv->certificate);
+ g_tls_operations_thread_base_set_own_certificate (priv->thread,
+ priv->certificate);
break;
case PROP_INTERACTION:
g_clear_object (&priv->interaction);
priv->interaction = g_value_dup_object (value);
+
+ if (priv->thread)
+ g_tls_operations_thread_base_set_interaction (priv->thread,
+ priv->interaction);
break;
case PROP_ADVERTISED_PROTOCOLS:
@@ -798,11 +802,15 @@ g_tls_connection_base_real_pop_io (GTlsConnectionBase *tls,
return G_TLS_CONNECTION_BASE_TIMED_OUT;
}
- if (priv->missing_requested_client_certificate &&
+ if (g_tls_operations_thread_base_get_is_missing_requested_client_certificate (priv->thread) &&
!priv->successful_posthandshake_op)
{
+ GError *interaction_error;
+
g_assert (G_IS_TLS_CLIENT_CONNECTION (tls));
+ interaction_error = g_tls_operations_thread_base_take_interaction_error (priv->thread);
+
/* Probably the server requires a client certificate, but we failed to
* provide one. With TLS 1.3 the server is no longer able to tell us
* this, so we just have to guess. If there is an error from the TLS
@@ -812,10 +820,9 @@ g_tls_connection_base_real_pop_io (GTlsConnectionBase *tls,
* connections where a client cert is requested but not provided, and then
* then only if the client has never successfully read or written.
*/
- if (priv->interaction_error)
+ if (interaction_error)
{
- g_propagate_error (error, priv->interaction_error);
- priv->interaction_error = NULL;
+ g_propagate_error (error, interaction_error);
}
else
{
@@ -1434,7 +1441,6 @@ handshake (GTlsConnectionBase *tls,
g_tls_log_debug (tls, "TLS handshake starts");
priv->started_handshake = FALSE;
- priv->missing_requested_client_certificate = FALSE;
/* FIXME: I don't like this mismatch. If we claim here, let's yield at the
* bottom. Otherwise, move claim to the caller.
@@ -2426,38 +2432,6 @@ g_tls_connection_base_get_base_iostream (GTlsConnectionBase *tls)
return priv->base_io_stream;
}
-void
-g_tls_connection_base_handshake_thread_set_missing_requested_client_certificate (GTlsConnectionBase *tls)
-{
- GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
-
- priv->missing_requested_client_certificate = TRUE;
-}
-
-gboolean
-g_tls_connection_base_handshake_thread_request_certificate (GTlsConnectionBase *tls)
-{
- GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
- GTlsInteractionResult res = G_TLS_INTERACTION_UNHANDLED;
- GTlsInteraction *interaction;
- GTlsConnection *conn;
-
- g_return_val_if_fail (G_IS_TLS_CONNECTION_BASE (tls), FALSE);
-
- conn = G_TLS_CONNECTION (tls);
-
- g_clear_error (&priv->interaction_error);
-
- interaction = g_tls_connection_get_interaction (conn);
- if (!interaction)
- return FALSE;
-
- res = g_tls_interaction_invoke_request_certificate (interaction, conn, 0,
- /* FIXME: priv->read_cancellable */ NULL,
- &priv->interaction_error);
- return res != G_TLS_INTERACTION_FAILED;
-}
-
GTlsOperationsThreadBase *
g_tls_connection_base_get_op_thread (GTlsConnectionBase *tls)
{
diff --git a/tls/base/gtlsconnection-base.h b/tls/base/gtlsconnection-base.h
index 3f1f5bf..938ce11 100644
--- a/tls/base/gtlsconnection-base.h
+++ b/tls/base/gtlsconnection-base.h
@@ -73,6 +73,7 @@ struct _GTlsConnectionBaseClass
GList *accepted_cas);
};
+/* FIXME: no handshake_thread stuff */
gboolean g_tls_connection_base_handshake_thread_verify_certificate
(GTlsConnectionBase *tls);
@@ -123,11 +124,7 @@ GDatagramBased *g_tls_connection_base_get_base_socket (GTlsCon
GIOStream *g_tls_connection_base_get_base_iostream (GTlsConnectionBase *tls);
-void g_tls_connection_base_handshake_thread_set_missing_requested_client_certificate
- (GTlsConnectionBase *tls);
-
-gboolean g_tls_connection_base_handshake_thread_request_certificate
- (GTlsConnectionBase *tls);
+/* FIXME: no handshake_thread stuff */
void g_tls_connection_base_handshake_thread_buffer_application_data
(GTlsConnectionBase *tls,
diff --git a/tls/base/gtlsoperationsthread-base.c b/tls/base/gtlsoperationsthread-base.c
index 63910a9..62efc40 100644
--- a/tls/base/gtlsoperationsthread-base.c
+++ b/tls/base/gtlsoperationsthread-base.c
@@ -76,9 +76,18 @@ typedef struct {
GAsyncQueue *queue;
- /* This mutex guards everything below. */
+ /* This mutex guards everything below. It's a bit of a failure of design.
+ * Ideally we wouldn't need to share this data between threads and would
+ * instead return data from the op thread to the calling thread using the op
+ * struct.
+ *
+ * TODO: some of this could move into the op struct?
+ */
GMutex mutex;
gchar *own_certificate_pem;
+ GTlsInteraction *interaction;
+ GError *interaction_error;
+ gboolean missing_requested_client_certificate;
} GTlsOperationsThreadBasePrivate;
typedef enum {
@@ -158,6 +167,114 @@ g_tls_operations_thread_base_get_connection (GTlsOperationsThreadBase *self)
return priv->connection;
}
+void
+g_tls_operations_thread_base_set_own_certificate (GTlsOperationsThreadBase *self,
+ GTlsCertificate *cert)
+{
+ GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+
+ g_mutex_lock (&priv->mutex);
+ g_clear_pointer (&priv->own_certificate_pem, g_free);
+ g_object_get (cert,
+ "certificate-pem", &priv->own_certificate_pem,
+ NULL);
+ g_mutex_unlock (&priv->mutex);
+}
+
+gchar *
+g_tls_operations_thread_base_get_own_certificate_pem (GTlsOperationsThreadBase *self)
+{
+ GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+ gchar *copy;
+
+ g_mutex_lock (&priv->mutex);
+ copy = g_strdup (priv->own_certificate_pem);
+ g_mutex_unlock (&priv->mutex);
+
+ return copy;
+}
+
+void
+g_tls_operations_thread_base_set_interaction (GTlsOperationsThreadBase *self,
+ GTlsInteraction *interaction)
+{
+ GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+
+ g_mutex_lock (&priv->mutex);
+ g_clear_object (&priv->interaction);
+ priv->interaction = g_object_ref (interaction);
+ g_mutex_unlock (&priv->mutex);
+}
+
+GTlsInteraction *
+g_tls_operations_thread_base_ref_interaction (GTlsOperationsThreadBase *self)
+{
+ GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+ GTlsInteraction *ref = NULL;
+
+ g_mutex_lock (&priv->mutex);
+ if (priv->interaction)
+ ref = g_object_ref (priv->interaction);
+ g_mutex_unlock (&priv->mutex);
+
+ return ref;
+}
+
+GError *
+g_tls_operations_thread_base_take_interaction_error (GTlsOperationsThreadBase *self)
+{
+ GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+ GError *error;
+
+ g_mutex_lock (&priv->mutex);
+ error = g_steal_pointer (&priv->interaction_error);
+ g_mutex_unlock (&priv->mutex);
+
+ return error;
+}
+
+gboolean
+g_tls_operations_thread_base_request_certificate (GTlsOperationsThreadBase *self,
+ GCancellable *cancellable)
+{
+ GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+ GTlsInteractionResult res = G_TLS_INTERACTION_UNHANDLED;
+
+ g_mutex_lock (&priv->mutex);
+ g_clear_error (&priv->interaction_error);
+ res = g_tls_interaction_invoke_request_certificate (priv->interaction,
+ G_TLS_CONNECTION (priv->connection),
+ 0,
+ cancellable,
+ &priv->interaction_error);
+ g_mutex_unlock (&priv->mutex);
+
+ return res != G_TLS_INTERACTION_FAILED;
+}
+
+void
+g_tls_operations_thread_base_set_is_missing_requested_client_certificate (GTlsOperationsThreadBase *self)
+{
+ GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+
+ g_mutex_lock (&priv->mutex);
+ priv->missing_requested_client_certificate = TRUE;
+ g_mutex_unlock (&priv->mutex);
+}
+
+gboolean
+g_tls_operations_thread_base_get_is_missing_requested_client_certificate (GTlsOperationsThreadBase *self)
+{
+ GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+ gboolean ret;
+
+ g_mutex_lock (&priv->mutex);
+ ret = priv->missing_requested_client_certificate;
+ g_mutex_unlock (&priv->mutex);
+
+ return ret;
+}
+
static GTlsThreadOperation *
g_tls_thread_copy_client_session_state_operation_new (GTlsOperationsThreadBase *thread,
GTlsConnectionBase *connection,
@@ -419,33 +536,6 @@ execute_op (GTlsOperationsThreadBase *self,
return result;
}
-void
-g_tls_operations_thread_base_set_own_certificate (GTlsOperationsThreadBase *self,
- GTlsCertificate *cert)
-{
- GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
-
- g_mutex_lock (&priv->mutex);
- g_clear_pointer (&priv->own_certificate_pem, g_free);
- g_object_get (cert,
- "certificate-pem", &priv->own_certificate_pem,
- NULL);
- g_mutex_unlock (&priv->mutex);
-}
-
-gchar *
-g_tls_operations_thread_base_get_own_certificate_pem (GTlsOperationsThreadBase *self)
-{
- GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
- gchar *copy;
-
- g_mutex_lock (&priv->mutex);
- copy = g_strdup (priv->own_certificate_pem);
- g_mutex_unlock (&priv->mutex);
-
- return copy;
-}
-
void
g_tls_operations_thread_base_copy_client_session_state (GTlsOperationsThreadBase *self,
GTlsOperationsThreadBase *source)
@@ -486,6 +576,10 @@ g_tls_operations_thread_base_handshake (GTlsOperationsThreadBase *self,
GTlsConnectionBaseStatus status;
GTlsThreadOperation *op;
+ g_mutex_lock (&priv->mutex);
+ priv->missing_requested_client_certificate = FALSE;
+ g_mutex_unlock (&priv->mutex);
+
op = g_tls_thread_handshake_operation_new (self,
priv->connection,
advertised_protocols,
@@ -1122,7 +1216,9 @@ g_tls_operations_thread_base_finalize (GObject *object)
g_mutex_clear (&priv->mutex);
- g_clear_pointer (&priv->own_certificate);
+ g_clear_pointer (&priv->own_certificate_pem, g_free);
+ g_clear_object (&priv->interaction);
+ g_clear_error (&priv->interaction_error);
G_OBJECT_CLASS (g_tls_operations_thread_base_parent_class)->finalize (object);
}
diff --git a/tls/base/gtlsoperationsthread-base.h b/tls/base/gtlsoperationsthread-base.h
index 5980b41..6658108 100644
--- a/tls/base/gtlsoperationsthread-base.h
+++ b/tls/base/gtlsoperationsthread-base.h
@@ -101,6 +101,17 @@ void g_tls_operations_thread_base_set_own_certificate
GTlsCertificate
*cert);
gchar *g_tls_operations_thread_base_get_own_certificate_pem (GTlsOperationsThreadBase
*self);
+void g_tls_operations_thread_base_set_interaction (GTlsOperationsThreadBase
*self,
+ GTlsInteraction
*interaction);
+GTlsInteraction *g_tls_operations_thread_base_ref_interaction (GTlsOperationsThreadBase
*self);
+GError *g_tls_operations_thread_base_take_interaction_error (GTlsOperationsThreadBase
*self);
+
+gboolean g_tls_operations_thread_base_request_certificate (GTlsOperationsThreadBase
*self,
+ GCancellable
*cancellable);
+
+void g_tls_operations_thread_base_set_is_missing_requested_client_certificate
(GTlsOperationsThreadBase *self);
+gboolean g_tls_operations_thread_base_get_is_missing_requested_client_certificate
(GTlsOperationsThreadBase *self);
+
void g_tls_operations_thread_base_copy_client_session_state (GTlsOperationsThreadBase
*self,
GTlsOperationsThreadBase
*source);
diff --git a/tls/gnutls/gtlsoperationsthread-gnutls.c b/tls/gnutls/gtlsoperationsthread-gnutls.c
index aa98265..570900a 100644
--- a/tls/gnutls/gtlsoperationsthread-gnutls.c
+++ b/tls/gnutls/gtlsoperationsthread-gnutls.c
@@ -1100,7 +1100,7 @@ pin_request_cb (void *userdata,
size_t pin_max)
{
GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (userdata);
- GTlsInteraction *interaction = g_tls_connection_get_interaction (connection);
+ GTlsInteraction *interaction = g_tls_operations_thread_base_ref_interaction (G_TLS_OPERATIONS_THREAD_BASE
(self));
GTlsInteractionResult result;
GTlsPassword *password;
GTlsPasswordFlags password_flags = 0;
@@ -1124,6 +1124,7 @@ pin_request_cb (void *userdata,
self->op_cancellable,
&error);
g_free (description);
+ g_object_unref (interaction);
switch (result)
{
@@ -1244,7 +1245,8 @@ retrieve_certificate_cb (gnutls_session_t session,
{
g_tls_certificate_gnutls_copy_free (*pcert, *pcert_length, *pkey);
- if (g_tls_connection_base_handshake_thread_request_certificate (tls))
+ if (g_tls_operations_thread_base_request_certificate (G_TLS_OPERATIONS_THREAD_BASE (self),
+ self->op_cancellable))
get_own_certificate (self, pcert, pcert_length, pkey);
if (*pcert_length == 0)
@@ -1256,7 +1258,7 @@ retrieve_certificate_cb (gnutls_session_t session,
* be optional, e.g. if the server is using
* G_TLS_AUTHENTICATION_REQUESTED, not G_TLS_AUTHENTICATION_REQUIRED.
*/
- g_tls_connection_base_handshake_thread_set_missing_requested_client_certificate (tls);
+ g_tls_operations_thread_base_set_is_missing_requested_client_certificate
(G_TLS_OPERATIONS_THREAD_BASE (self));
return 0;
}
}
@@ -1268,7 +1270,7 @@ retrieve_certificate_cb (gnutls_session_t session,
/* No private key. GnuTLS expects it to be non-null if pcert_length is
* nonzero, so we have to abort now.
*/
- g_tls_connection_base_handshake_thread_set_missing_requested_client_certificate (tls);
+ g_tls_operations_thread_base_set_is_missing_requested_client_certificate
(G_TLS_OPERATIONS_THREAD_BASE (self));
return -1;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]