[glib-networking/mcatanzaro/tls-thread: 15/26] progress



commit 89fc271db3feca9b3dbebc7a48d91a793f8d1fbd
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 6a7edf8..2eed602 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
         {
@@ -1437,7 +1444,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.
@@ -2429,38 +2435,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]