[glib-networking/mcatanzaro/tls-thread] more unstable progress



commit 94316f8fb74eb3827fddab7d8066996ce5d33449
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Sat Dec 21 14:37:35 2019 -0600

    more unstable progress

 tls/base/gtlsoperationsthread-base.c     |  26 +++++-
 tls/base/gtlsoperationsthread-base.h     |  11 ++-
 tls/gnutls/gtlsclientconnection-gnutls.c |  82 +++----------------
 tls/gnutls/gtlsoperationsthread-gnutls.c | 132 ++++++++++++++++++++++++-------
 4 files changed, 148 insertions(+), 103 deletions(-)
---
diff --git a/tls/base/gtlsoperationsthread-base.c b/tls/base/gtlsoperationsthread-base.c
index fc37fd2..e0dd51f 100644
--- a/tls/base/gtlsoperationsthread-base.c
+++ b/tls/base/gtlsoperationsthread-base.c
@@ -105,6 +105,9 @@ typedef struct {
     guint num_vectors;
   };
 
+  /* For handshakes */
+  gchar **advertised_protocols;
+
   gint64 timeout;
   gint64 start_time;
 
@@ -143,12 +146,20 @@ g_tls_operations_thread_base_get_connection (GTlsOperationsThreadBase *self)
   return priv->connection;
 }
 
+void
+g_tls_operations_thread_base_copy_client_session_state (GTlsOperationsThreadBase  *self,
+                                                        GTlsOperationsThreadBase  *source)
+{
+
+}
+
 static GTlsThreadOperation *
 g_tls_thread_operation_new (GTlsThreadOperationType   type,
                             GTlsOperationsThreadBase *thread,
                             GTlsConnectionBase       *connection,
                             void                     *data,
                             gsize                     size,
+                            const gchar             **advertised_protocols,
                             gint64                    timeout,
                             GCancellable             *cancellable)
 {
@@ -160,6 +171,7 @@ g_tls_thread_operation_new (GTlsThreadOperationType   type,
   op->connection = g_object_ref (connection);
   op->data = data;
   op->size = size;
+  op->advertised_protocols = g_strdupv ((gchar **)advertised_protocols);
   op->timeout = timeout;
   op->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
 
@@ -261,6 +273,8 @@ g_tls_thread_operation_free (GTlsThreadOperation *op)
       g_cond_clear (&op->finished_condition);
     }
 
+  g_strfreev (op->advertised_protocols);
+
   g_free (op);
 }
 
@@ -275,9 +289,9 @@ wait_for_op_completion (GTlsThreadOperation *op)
 
 static GTlsConnectionBaseStatus
 execute_op (GTlsOperationsThreadBase *self,
-                 GTlsThreadOperation      *op /* owned */,
-                 gssize                   *count,
-                 GError                  **error)
+            GTlsThreadOperation      *op /* owned */,
+            gssize                   *count,
+            GError                  **error)
 {
   GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
   GTlsConnectionBaseStatus result;
@@ -305,6 +319,7 @@ execute_op (GTlsOperationsThreadBase *self,
 
 GTlsConnectionBaseStatus
 g_tls_operations_thread_base_handshake (GTlsOperationsThreadBase  *self,
+                                        const gchar              **advertised_protocols,
                                         gint64                     timeout,
                                         GCancellable              *cancellable,
                                         GError                   **error)
@@ -316,6 +331,7 @@ g_tls_operations_thread_base_handshake (GTlsOperationsThreadBase  *self,
                                    self,
                                    priv->connection,
                                    NULL, 0,
+                                   advertised_protocols,
                                    timeout,
                                    cancellable);
 
@@ -338,6 +354,7 @@ g_tls_operations_thread_base_read (GTlsOperationsThreadBase  *self,
                                    self,
                                    priv->connection,
                                    buffer, size,
+                                   NULL,
                                    timeout,
                                    cancellable);
 
@@ -381,6 +398,7 @@ g_tls_operations_thread_base_write (GTlsOperationsThreadBase  *self,
                                    self,
                                    priv->connection,
                                    (void *)buffer, size,
+                                   NULL,
                                    timeout,
                                    cancellable);
 
@@ -420,6 +438,7 @@ g_tls_operations_thread_base_close (GTlsOperationsThreadBase  *self,
                                    self,
                                    priv->connection,
                                    NULL, 0,
+                                   NULL,
                                    -1 /* blocking */,
                                    cancellable);
 
@@ -741,6 +760,7 @@ process_op (GAsyncQueue         *queue,
     {
     case G_TLS_THREAD_OP_HANDSHAKE:
       op->result = base_class->handshake_fn (op->thread,
+                                             (const gchar **)op->advertised_protocols,
                                              op->timeout,
                                              op->cancellable,
                                              &op->error);
diff --git a/tls/base/gtlsoperationsthread-base.h b/tls/base/gtlsoperationsthread-base.h
index a26dd7d..8f15d31 100644
--- a/tls/base/gtlsoperationsthread-base.h
+++ b/tls/base/gtlsoperationsthread-base.h
@@ -38,9 +38,12 @@ struct _GTlsOperationsThreadBaseClass
 {
   GObjectClass parent_class;
 
+  void                        (*copy_client_session_state)  (GTlsOperationsThreadBase  *self,
+                                                             GTlsOperationsThreadBase  *source);
+
 /* FIXME: working on these... */
   GTlsConnectionBaseStatus    (*handshake_fn)               (GTlsOperationsThreadBase  *self,
-                                                             gchar                    **advertised_protocols,
+                                                             const gchar              **advertised_protocols,
                                                              gint64                     timeout,
                                                              GCancellable              *cancellable,
                                                              GError                   **error);
@@ -86,8 +89,12 @@ struct _GTlsOperationsThreadBaseClass
 /* FIXME: remove!!! */
 GTlsConnectionBase       *g_tls_operations_thread_base_get_connection (GTlsOperationsThreadBase  *self);
 
+void                      g_tls_operations_thread_base_copy_client_session_state
+                                                                      (GTlsOperationsThreadBase  *self,
+                                                                       GTlsOperationsThreadBase  *source);
+
 GTlsConnectionBaseStatus  g_tls_operations_thread_base_handshake      (GTlsOperationsThreadBase  *self,
-                                                                       gchar                    
**advertised_protocols,
+                                                                       const gchar              
**advertised_protocols,
                                                                        gint64                     timeout,
                                                                        GCancellable              
*cancellable,
                                                                        GError                   **error);
diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c
index e74b43f..8bc8662 100644
--- a/tls/gnutls/gtlsclientconnection-gnutls.c
+++ b/tls/gnutls/gtlsclientconnection-gnutls.c
@@ -23,19 +23,20 @@
  */
 
 #include "config.h"
-#include "glib.h"
+#include "gtlsclientconnection-gnutls.h"
+
+#include "gtlsbackend-gnutls.h"
+#include "gtlsconnection-base.h"
+#include "gtlscertificate-gnutls.h"
+#include "gtlsoperationsthread-base.h"
 
 #include <errno.h>
+#include <glib.h>
+#include <glib/gi18n-lib.h>
 #include <gnutls/gnutls.h>
 #include <gnutls/x509.h>
 #include <string.h>
 
-#include "gtlsconnection-base.h"
-#include "gtlsclientconnection-gnutls.h"
-#include "gtlsbackend-gnutls.h"
-#include "gtlscertificate-gnutls.h"
-#include <glib/gi18n-lib.h>
-
 enum
 {
   PROP_0,
@@ -53,15 +54,6 @@ struct _GTlsClientConnectionGnutls
   GSocketConnectable *server_identity;
   gboolean use_ssl3;
 
-  /* session_data is either the session ticket that was used to resume this
-   * connection, or the most recent session ticket received from the server.
-   * Because session ticket reuse is generally undesirable, it should only be
-   * accessed if session_data_override is set.
-   */
-  GBytes *session_id;
-  GBytes *session_data;
-  gboolean session_data_override;
-
   GPtrArray *accepted_cas;
   gboolean accepted_cas_changed;
 
@@ -155,8 +147,6 @@ g_tls_client_connection_gnutls_finalize (GObject *object)
 
   g_clear_object (&gnutls->server_identity);
   g_clear_pointer (&gnutls->accepted_cas, g_ptr_array_unref);
-  g_clear_pointer (&gnutls->session_id, g_bytes_unref);
-  g_clear_pointer (&gnutls->session_data, g_bytes_unref);
 
   clear_gnutls_certificate_copy (gnutls);
 
@@ -366,39 +356,6 @@ g_tls_client_connection_gnutls_handshake_thread_retrieve_function (gnutls_sessio
 
   return 0;
 }
-
-static void
-g_tls_client_connection_gnutls_prepare_handshake (GTlsConnectionBase  *tls,
-                                                  gchar              **advertised_protocols)
-{
-  GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (tls);
-
-  g_tls_client_connection_gnutls_compute_session_id (gnutls);
-
-  if (gnutls->session_data_override)
-    {
-      g_assert (gnutls->session_data);
-      gnutls_session_set_data (g_tls_connection_gnutls_get_session (G_TLS_CONNECTION_GNUTLS (tls)),
-                               g_bytes_get_data (gnutls->session_data, NULL),
-                               g_bytes_get_size (gnutls->session_data));
-    }
-  else if (gnutls->session_id)
-    {
-      GBytes *session_data;
-
-      session_data = g_tls_backend_gnutls_lookup_session_data (gnutls->session_id);
-      if (session_data)
-        {
-          gnutls_session_set_data (g_tls_connection_gnutls_get_session (G_TLS_CONNECTION_GNUTLS (tls)),
-                                   g_bytes_get_data (session_data, NULL),
-                                   g_bytes_get_size (session_data));
-          g_clear_pointer (&gnutls->session_data, g_bytes_unref);
-          gnutls->session_data = g_steal_pointer (&session_data);
-        }
-    }
-
-}
-
 static void
 g_tls_client_connection_gnutls_complete_handshake (GTlsConnectionBase  *tls,
                                                    gchar              **negotiated_protocol,
@@ -419,27 +376,10 @@ static void
 g_tls_client_connection_gnutls_copy_session_state (GTlsClientConnection *conn,
                                                    GTlsClientConnection *source)
 {
-  GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (conn);
-  GTlsClientConnectionGnutls *gnutls_source = G_TLS_CLIENT_CONNECTION_GNUTLS (source);
-
-  /* Precondition: source has handshaked, conn has not. */
-  g_return_if_fail (!gnutls->session_id);
-  g_return_if_fail (gnutls_source->session_id);
-
-  /* Prefer to use a new session ticket, if possible. */
-  gnutls->session_data = g_tls_backend_gnutls_lookup_session_data (gnutls_source->session_id);
-
-  if (!gnutls->session_data && gnutls_source->session_data)
-    {
-      /* If it's not possible, we'll try to reuse the old ticket, even though
-       * this is a privacy risk since TLS 1.3. Applications should not use this
-       * function unless they need us to try as hard as possible to resume a
-       * session, even at the cost of privacy.
-       */
-      gnutls->session_data = g_bytes_ref (gnutls_source->session_data);
-    }
+  GTlsOperationsThreadBase *thread = g_tls_connection_base_get_op_thread (G_TLS_CONNECTION_BASE (conn));
+  GTlsOperationsThreadBase *source_thread = g_tls_connection_base_get_op_thread (G_TLS_CONNECTION_BASE 
(source));
 
-  gnutls->session_data_override = !!gnutls->session_data;
+  g_tls_operations_thread_base_copy_client_session_state (thread, source_thread);
 }
 
 static void
diff --git a/tls/gnutls/gtlsoperationsthread-gnutls.c b/tls/gnutls/gtlsoperationsthread-gnutls.c
index c6559d6..57ab183 100644
--- a/tls/gnutls/gtlsoperationsthread-gnutls.c
+++ b/tls/gnutls/gtlsoperationsthread-gnutls.c
@@ -28,6 +28,7 @@
 #include "config.h"
 #include "gtlsoperationsthread-gnutls.h"
 
+#include "gtlsbackend-gnutls.h"
 #include "gtlsconnection-gnutls.h"
 
 #include <errno.h>
@@ -39,7 +40,16 @@ struct _GTlsOperationsThreadGnutls {
   GTlsOperationsThreadBase parent_instance;
 
   guint                            init_flags;
-  gnutls_certificate_credentials_t creds; /* owned by GTlsConnectionGnutls */
+  gnutls_certificate_credentials_t creds;
+
+  /* session_data is either the session ticket that was used to resume this
+   * connection, or the most recent session ticket received from the server.
+   * Because session ticket reuse is generally undesirable, it should only be
+   * accessed if session_data_override is set.
+   */
+  GBytes                  *session_id;
+  GBytes                  *session_data;
+  gboolean                 session_data_override; /* FIXME: sort this all out */
 
   gnutls_session_t         session;
 
@@ -345,18 +355,90 @@ compute_session_id (GTlsOperationsThreadGnutls *self)
                                         server_hostname ? server_hostname : "",
                                         port,
                                         cert_hash ? cert_hash : "");
-          gnutls->session_id = g_bytes_new_take (session_id, strlen (session_id));
+          self->session_id = g_bytes_new_take (session_id, strlen (session_id));
           g_free (addrstr);
           g_free (cert_hash);
         }
       g_object_unref (remote_addr);
     }
-  g_clear_object (&base_conn);
+}
+
+static void
+set_advertised_protocols (GTlsOperationsThreadGnutls  *self,
+                          const gchar                **advertised_protocols)
+{
+  gnutls_datum_t *protocols;
+  int n_protos, i;
+
+  n_protos = g_strv_length ((gchar **)advertised_protocols);
+  protocols = g_new (gnutls_datum_t, n_protos);
+  for (i = 0; advertised_protocols[i]; i++)
+    {
+      protocols[i].size = strlen (advertised_protocols[i]);
+      protocols[i].data = (guchar *)advertised_protocols[i];
+    }
+  gnutls_alpn_set_protocols (self->session, protocols, n_protos, 0);
+  g_free (protocols);
+}
+
+static void
+set_session_data (GTlsOperationsThreadGnutls *self)
+{
+  compute_session_id (self);
+
+  if (self->session_data_override)
+    {
+      g_assert (self->session_data);
+      gnutls_session_set_data (self->session,
+                               g_bytes_get_data (self->session_data, NULL),
+                               g_bytes_get_size (self->session_data));
+    }
+  else if (self->session_id)
+    {
+      GBytes *session_data;
+
+      session_data = g_tls_backend_gnutls_lookup_session_data (self->session_id);
+      if (session_data)
+        {
+          gnutls_session_set_data (self->session,
+                                   g_bytes_get_data (session_data, NULL),
+                                   g_bytes_get_size (session_data));
+          g_clear_pointer (&self->session_data, g_bytes_unref);
+          self->session_data = g_steal_pointer (&session_data);
+        }
+    }
+}
+
+static void
+g_tls_operations_thread_gnutls_copy_client_session_state (GTlsOperationsThreadBase *base,
+                                                          GTlsOperationsThreadBase *base_source)
+{
+  GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (base);
+  GTlsOperationsThreadGnutls *source = G_TLS_OPERATIONS_THREAD_GNUTLS (base_source);
+
+  /* Precondition: source has handshaked, conn has not. */
+  g_return_if_fail (!self->session_id);
+  g_return_if_fail (source->session_id);
+
+  /* Prefer to use a new session ticket, if possible. */
+  self->session_data = g_tls_backend_gnutls_lookup_session_data (source->session_id);
+
+  if (!self->session_data && source->session_data)
+    {
+      /* If it's not possible, we'll try to reuse the old ticket, even though
+       * this is a privacy risk since TLS 1.3. Applications should not use this
+       * function unless they need us to try as hard as possible to resume a
+       * session, even at the cost of privacy.
+       */
+      self->session_data = g_bytes_ref (source->session_data);
+    }
+
+  self->session_data_override = !!self->session_data;
 }
 
 static GTlsConnectionBaseStatus
 g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase  *base,
-                                          gchar                    **advertised_protocols,
+                                          const gchar              **advertised_protocols,
                                           gint64                     timeout,
                                           GCancellable              *cancellable,
                                           GError                   **error)
@@ -385,20 +467,9 @@ g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase  *base,
     }
 
   if (advertised_protocols)
-    {
-      gnutls_datum_t *protocols;
-      int n_protos, i;
+    set_advertised_protocols (self, advertised_protocols);
 
-      n_protos = g_strv_length (advertised_protocols);
-      protocols = g_new (gnutls_datum_t, n_protos);
-      for (i = 0; advertised_protocols[i]; i++)
-        {
-          protocols[i].size = strlen (advertised_protocols[i]);
-          protocols[i].data = (guchar *)advertised_protocols[i];
-        }
-      gnutls_alpn_set_protocols (self->session, protocols, n_protos, 0);
-      g_free (protocols);
-    }
+  set_session_data (self);
 
   self->handshaking = TRUE;
 
@@ -938,10 +1009,16 @@ g_tls_operations_thread_gnutls_finalize (GObject *object)
 {
   GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (object);
 
-  if (self->session)
-    gnutls_deinit (self->session);
-  if (self->creds)
-    gnutls_certificate_free_credentials (self->creds);
+  g_clear_pointer (&self->session, gnutls_deinit);
+  g_clear_pointer (&self->creds, gnutls_certificate_free_credentials);
+  g_clear_pointer (&self->session_id, g_bytes_unref);
+  g_clear_pointer (&self->session_data, g_bytes_unref);
+
+  g_clear_object (&self->base_iostream);
+  g_clear_object (&self->base_socket);
+
+  g_assert (!self->op_cancellable);
+  g_assert (!self->op_error);
 
   G_OBJECT_CLASS (g_tls_operations_thread_gnutls_parent_class)->finalize (object);
 }
@@ -1019,12 +1096,13 @@ g_tls_operations_thread_gnutls_class_init (GTlsOperationsThreadGnutlsClass *klas
   gobject_class->get_property  = g_tls_operations_thread_gnutls_get_property;
   gobject_class->set_property  = g_tls_operations_thread_gnutls_set_property;
 
-  base_class->handshake_fn     = g_tls_operations_thread_gnutls_handshake;
-  base_class->read_fn          = g_tls_operations_thread_gnutls_read;
-  base_class->read_message_fn  = g_tls_operations_thread_gnutls_read_message;
-  base_class->write_fn         = g_tls_operations_thread_gnutls_write;
-  base_class->write_message_fn = g_tls_operations_thread_gnutls_write_message;
-  base_class->close_fn         = g_tls_operations_thread_gnutls_close;
+  base_class->copy_client_session_state = g_tls_operations_thread_gnutls_copy_client_session_state;
+  base_class->handshake_fn              = g_tls_operations_thread_gnutls_handshake;
+  base_class->read_fn                   = g_tls_operations_thread_gnutls_read;
+  base_class->read_message_fn           = g_tls_operations_thread_gnutls_read_message;
+  base_class->write_fn                  = g_tls_operations_thread_gnutls_write;
+  base_class->write_message_fn          = g_tls_operations_thread_gnutls_write_message;
+  base_class->close_fn                  = g_tls_operations_thread_gnutls_close;
 
   obj_properties[PROP_BASE_IO_STREAM] =
     g_param_spec_object ("base-io-stream",


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