[glib-networking/mcatanzaro/tls-thread: 10/24] progress



commit 03ef9e07e2af450bfefb7a0542f4810153ac6e66
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Sat Dec 21 19:40:57 2019 -0600

    progress

 tls/base/gtlsconnection-base.c           |  10 +-
 tls/base/gtlsoperationsthread-base.c     |  13 ++-
 tls/base/gtlsoperationsthread-base.h     |   2 +
 tls/gnutls/gtlsclientconnection-gnutls.c |   1 -
 tls/gnutls/gtlsconnection-gnutls.c       |   8 --
 tls/gnutls/gtlsoperationsthread-gnutls.c | 186 ++++++++++++++++++-------------
 tls/gnutls/gtlsserverconnection-gnutls.c |  88 ++++-----------
 7 files changed, 154 insertions(+), 154 deletions(-)
---
diff --git a/tls/base/gtlsconnection-base.c b/tls/base/gtlsconnection-base.c
index a3d8262..9b493dc 100644
--- a/tls/base/gtlsconnection-base.c
+++ b/tls/base/gtlsconnection-base.c
@@ -1418,6 +1418,7 @@ handshake (GTlsConnectionBase  *tls,
            GError             **error)
 {
   GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+  GTlsAuthenticationMode auth_mode = G_TLS_AUTHENTICATION_NONE;
 
   g_tls_log_debug (tls, "TLS handshake starts");
 
@@ -1447,8 +1448,15 @@ handshake (GTlsConnectionBase  *tls,
       return TRUE;
     }
 
+  if (G_IS_TLS_SERVER_CONNECTION (tls))
+    {
+      g_object_get (tls,
+                    "authentication-mode", &auth_mode,
+                    NULL);
+    }
+
   priv->started_handshake = TRUE;
-  g_tls_operations_thread_base_handshake (priv->thread, priv->advertised_protocols, timeout, cancellable, 
error);
+  g_tls_operations_thread_base_handshake (priv->thread, (const gchar **)priv->advertised_protocols, 
auth_mode, timeout, cancellable, error);
   priv->need_handshake = FALSE;
 
   if (error && *error)
diff --git a/tls/base/gtlsoperationsthread-base.c b/tls/base/gtlsoperationsthread-base.c
index 339aa65..32959e7 100644
--- a/tls/base/gtlsoperationsthread-base.c
+++ b/tls/base/gtlsoperationsthread-base.c
@@ -96,11 +96,10 @@ typedef struct {
   GTlsOperationsThreadBase *thread;
   GTlsConnectionBase *connection; /* FIXME: threadsafety nightmare, not OK */
 
-  union {
-    GTlsOperationsThreadBase *source; /* for copy client session state */
-    gchar *server_identity;           /* for set server identity */
-    gchar **advertised_protocols;     /* for handshake */
-  };
+  GTlsOperationsThreadBase *source; /* for copy client session state */
+  gchar *server_identity;           /* for set server identity */
+  gchar **advertised_protocols;     /* for handshake */
+  GTlsAuthenticationMode auth_mode; /* for handshake */
 
   union {
     void *data;                    /* for read/write */
@@ -170,6 +169,7 @@ g_tls_thread_copy_client_session_state_operation_new (GTlsOperationsThreadBase *
   return op;
 }
 
+/* FIXME: dumb, move this into handshake operation as is done for authentication mode */
 static GTlsThreadOperation *
 g_tls_thread_set_server_identity_operation_new (GTlsOperationsThreadBase *thread,
                                                 GTlsConnectionBase       *connection,
@@ -193,6 +193,7 @@ static GTlsThreadOperation *
 g_tls_thread_handshake_operation_new (GTlsOperationsThreadBase  *thread,
                                       GTlsConnectionBase        *connection,
                                       const gchar              **advertised_protocols,
+                                      GTlsAuthenticationMode     auth_mode,
                                       gint64                     timeout,
                                       GCancellable              *cancellable)
 {
@@ -204,6 +205,7 @@ g_tls_thread_handshake_operation_new (GTlsOperationsThreadBase  *thread,
   op->thread = thread;
   op->connection = connection;
   op->advertised_protocols = g_strdupv ((gchar **)advertised_protocols);
+  op->auth_mode = auth_mode;
   op->timeout = timeout;
   op->cancellable = cancellable;
 
@@ -870,6 +872,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->auth_mode,
                                              op->timeout,
                                              op->cancellable,
                                              &op->error);
diff --git a/tls/base/gtlsoperationsthread-base.h b/tls/base/gtlsoperationsthread-base.h
index b69d207..039f3b5 100644
--- a/tls/base/gtlsoperationsthread-base.h
+++ b/tls/base/gtlsoperationsthread-base.h
@@ -45,6 +45,7 @@ struct _GTlsOperationsThreadBaseClass
 
   GTlsConnectionBaseStatus    (*handshake_fn)               (GTlsOperationsThreadBase  *self,
                                                              const gchar              **advertised_protocols,
+                                                             GTlsAuthenticationMode     auth_mode,
                                                              gint64                     timeout,
                                                              GCancellable              *cancellable,
                                                              GError                   **error);
@@ -102,6 +103,7 @@ void                      g_tls_operations_thread_base_set_server_identity
 
 GTlsConnectionBaseStatus  g_tls_operations_thread_base_handshake                 (GTlsOperationsThreadBase  
*self,
                                                                                   const gchar              
**advertised_protocols,
+                                                                                  GTlsAuthenticationMode     
auth_mode,
                                                                                   gint64                     
timeout,
                                                                                   GCancellable              
*cancellable,
                                                                                   GError                   
**error);
diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c
index 6e55ea4..4a8c549 100644
--- a/tls/gnutls/gtlsclientconnection-gnutls.c
+++ b/tls/gnutls/gtlsclientconnection-gnutls.c
@@ -141,7 +141,6 @@ g_tls_client_connection_gnutls_initable_init (GInitable       *initable,
   creds = g_tls_connection_gnutls_get_credentials (G_TLS_CONNECTION_GNUTLS (gnutls));
   gnutls_certificate_set_retrieve_function2 (creds, 
g_tls_client_connection_gnutls_handshake_thread_retrieve_function);
 
-
   hostname = get_server_identity (G_TLS_CLIENT_CONNECTION_GNUTLS (gnutls));
   if (hostname)
     g_tls_operations_thread_base_set_server_identity (thread, hostname);
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index d1a6b68..1c49fd1 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -136,14 +136,6 @@ g_tls_connection_gnutls_finalize (GObject *object)
   G_OBJECT_CLASS (g_tls_connection_gnutls_parent_class)->finalize (object);
 }
 
-gnutls_certificate_credentials_t
-g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *gnutls)
-{
-  GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
-
-  return priv->creds; /* FIXME: get via op thread? */
-}
-
 static int
 on_pin_request (void         *userdata,
                 int           attempt,
diff --git a/tls/gnutls/gtlsoperationsthread-gnutls.c b/tls/gnutls/gtlsoperationsthread-gnutls.c
index 2b9e959..9d25cd9 100644
--- a/tls/gnutls/gtlsoperationsthread-gnutls.c
+++ b/tls/gnutls/gtlsoperationsthread-gnutls.c
@@ -94,6 +94,12 @@ is_client (GTlsOperationsThreadGnutls *self)
   return self->init_flags & GNUTLS_CLIENT;
 }
 
+static inline gboolean
+is_server (GTlsOperationsThreadGnutls *self)
+{
+  return self->init_flags & GNUTLS_SERVER;
+}
+
 static GTlsConnectionBaseStatus
 end_gnutls_io (GTlsOperationsThreadGnutls  *self,
                GIOCondition                 direction,
@@ -281,18 +287,6 @@ initialize_gnutls_priority (void)
     g_warning ("Failed to set GnuTLS session priority with error beginning at %s: %s", error_pos, 
gnutls_strerror (ret));
 }
 
-static void
-set_handshake_priority (GTlsOperationsThreadGnutls *self)
-{
-  int ret;
-
-  g_assert (priority);
-
-  ret = gnutls_priority_set (self->session, priority);
-  if (ret != GNUTLS_E_SUCCESS)
-    g_warning ("Failed to set GnuTLS session priority: %s", gnutls_strerror (ret));
-}
-
 static void
 compute_session_id (GTlsOperationsThreadGnutls *self)
 {
@@ -371,6 +365,88 @@ compute_session_id (GTlsOperationsThreadGnutls *self)
     }
 }
 
+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 void
+g_tls_operations_thread_gnutls_set_server_identity (GTlsOperationsThreadBase *base,
+                                                    const gchar              *server_identity)
+{
+  GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (base);
+  gchar *normalized_hostname;
+  size_t len;
+
+  g_assert (is_client (self));
+
+  normalized_hostname = g_strdup (server_identity);
+  len = strlen (server_identity);
+
+  if (server_identity[len - 1] == '.')
+    {
+      normalized_hostname[len - 1] = '\0';
+      len--;
+    }
+
+  gnutls_server_name_set (self->session, GNUTLS_NAME_DNS,
+                          normalized_hostname, len);
+
+  g_clear_pointer (&self->server_identity, g_free);
+  self->server_identity = g_steal_pointer (&normalized_hostname);
+}
+
+static void
+set_handshake_priority (GTlsOperationsThreadGnutls *self)
+{
+  int ret;
+
+  g_assert (priority);
+
+  ret = gnutls_priority_set (self->session, priority);
+  if (ret != GNUTLS_E_SUCCESS)
+    g_warning ("Failed to set GnuTLS session priority: %s", gnutls_strerror (ret));
+}
+
+static void
+set_handshake_timeout (GTlsOperationsThreadGnutls *self,
+                       gint64                      timeout)
+{
+  unsigned int timeout_ms;
+
+  /* Convert from microseconds to milliseconds, but ensure the timeout
+   * remains positive.
+   */
+  timeout_ms = (timeout + 999) / 1000;
+
+  if (is_dtls (self))
+    gnutls_dtls_set_timeouts (self->session, 1000 /* default */, timeout_ms);
+  else
+    gnutls_handshake_set_timeout (self->session, timeout_ms);
+}
+
 static void
 set_advertised_protocols (GTlsOperationsThreadGnutls  *self,
                           const gchar                **advertised_protocols)
@@ -418,64 +494,32 @@ set_session_data (GTlsOperationsThreadGnutls *self)
 }
 
 static void
-g_tls_operations_thread_gnutls_copy_client_session_state (GTlsOperationsThreadBase *base,
-                                                          GTlsOperationsThreadBase *base_source)
+set_authentication_mode (GTlsOperationsThreadGnutls *self,
+                         GTlsAuthenticationMode      auth_mode)
 {
-  GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (base);
-  GTlsOperationsThreadGnutls *source = G_TLS_OPERATIONS_THREAD_GNUTLS (base_source);
+  gnutls_certificate_request_t req = GNUTLS_CERT_IGNORE;
 
-  /* Precondition: source has handshaked, conn has not. */
-  g_return_if_fail (!self->session_id);
-  g_return_if_fail (source->session_id);
+  g_assert (is_server (self));
 
-  /* 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)
+  switch (auth_mode)
     {
-      /* 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 void
-g_tls_operations_thread_gnutls_set_server_identity (GTlsOperationsThreadBase *base,
-                                                    const gchar              *server_identity)
-{
-  GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (base);
-  gchar *normalized_hostname;
-  size_t len;
-
-  /* This function sets the SNI hostname, which the client uses to tell the
-   * server which vhost it's connecting to. Clients only!
-   */
-  g_assert (is_client (self));
-
-  normalized_hostname = g_strdup (server_identity);
-  len = strlen (server_identity);
-
-  if (server_identity[len - 1] == '.')
-    {
-      normalized_hostname[len - 1] = '\0';
-      len--;
+    case G_TLS_AUTHENTICATION_REQUESTED:
+      req = GNUTLS_CERT_REQUEST;
+      break;
+    case G_TLS_AUTHENTICATION_REQUIRED:
+      req = GNUTLS_CERT_REQUIRE;
+      break;
+    default:
+      break;
     }
 
-  gnutls_server_name_set (self->session, GNUTLS_NAME_DNS,
-                          normalized_hostname, len);
-
-  g_clear_pointer (&self->server_identity, g_free);
-  self->server_identity = g_steal_pointer (&normalized_hostname);
+  gnutls_certificate_server_set_request (self->session, req);
 }
 
 static GTlsConnectionBaseStatus
 g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase  *base,
                                           const gchar              **advertised_protocols,
+                                          GTlsAuthenticationMode     auth_mode,
                                           gint64                     timeout,
                                           GCancellable              *cancellable,
                                           GError                   **error)
@@ -491,17 +535,7 @@ g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase  *base,
     set_handshake_priority (self);
 
   if (timeout > 0)
-    {
-      unsigned int timeout_ms;
-
-      /* Convert from microseconds to milliseconds, but ensure the timeout
-       * remains positive.
-       */
-      timeout_ms = (timeout + 999) / 1000;
-
-      gnutls_handshake_set_timeout (self->session, timeout_ms);
-      gnutls_dtls_set_timeouts (self->session, 1000 /* default */, timeout_ms);
-    }
+    set_handshake_timeout (self, timeout);
 
   if (advertised_protocols)
     set_advertised_protocols (self, advertised_protocols);
@@ -509,6 +543,9 @@ g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase  *base,
   if (is_client (self))
     set_session_data (self);
 
+  if (is_server (self))
+    set_authentication_mode (self, auth_mode);
+
   self->handshaking = TRUE;
 
   BEGIN_GNUTLS_IO (self, G_IO_IN | G_IO_OUT, cancellable);
@@ -685,7 +722,8 @@ g_tls_operations_thread_gnutls_write_message (GTlsOperationsThreadBase  *base,
       if (ret < 0 || ret < vectors[i].size)
         {
           /* Uncork to restore state, then bail. The peer will receive a
-           * truncated datagram. */
+           * truncated datagram.
+           */
           break;
         }
     }
@@ -848,11 +886,9 @@ g_tls_operations_thread_gnutls_vec_push_func (gnutls_transport_ptr_t  transport_
   /* this entire expression will be evaluated at compile time */
   if (sizeof *iov == sizeof *vectors &&
       sizeof iov->iov_base == sizeof vectors->buffer &&
-      G_STRUCT_OFFSET (giovec_t, iov_base) ==
-      G_STRUCT_OFFSET (GOutputVector, buffer) &&
+      G_STRUCT_OFFSET (giovec_t, iov_base) == G_STRUCT_OFFSET (GOutputVector, buffer) &&
       sizeof iov->iov_len == sizeof vectors->size &&
-      G_STRUCT_OFFSET (giovec_t, iov_len) ==
-      G_STRUCT_OFFSET (GOutputVector, size))
+      G_STRUCT_OFFSET (giovec_t, iov_len) == G_STRUCT_OFFSET (GOutputVector, size))
     /* ABI is compatible */
     {
       message.vectors = (GOutputVector *)iov;
diff --git a/tls/gnutls/gtlsserverconnection-gnutls.c b/tls/gnutls/gtlsserverconnection-gnutls.c
index 090b57d..8a44285 100644
--- a/tls/gnutls/gtlsserverconnection-gnutls.c
+++ b/tls/gnutls/gtlsserverconnection-gnutls.c
@@ -55,15 +55,6 @@ static void     g_tls_server_connection_gnutls_initable_interface_init (GInitabl
 
 static void g_tls_server_connection_gnutls_server_connection_interface_init (GTlsServerConnectionInterface 
*iface);
 
-static int g_tls_server_connection_gnutls_handshake_thread_retrieve_function (gnutls_session_t              
session,
-                                                                              const gnutls_datum_t         
*req_ca_rdn,
-                                                                              int                           
nreqs,
-                                                                              const gnutls_pk_algorithm_t  
*pk_algos,
-                                                                              int                           
pk_algos_length,
-                                                                              gnutls_pcert_st             
**pcert,
-                                                                              unsigned int                 
*pcert_length,
-                                                                              gnutls_privkey_t             
*pkey);
-
 static GInitableIface *g_tls_server_connection_gnutls_parent_initable_iface;
 
 G_DEFINE_TYPE_WITH_CODE (GTlsServerConnectionGnutls, g_tls_server_connection_gnutls, 
G_TYPE_TLS_CONNECTION_GNUTLS,
@@ -100,6 +91,30 @@ g_tls_server_connection_gnutls_finalize (GObject *object)
   G_OBJECT_CLASS (g_tls_server_connection_gnutls_parent_class)->finalize (object);
 }
 
+static int
+g_tls_server_connection_gnutls_handshake_thread_retrieve_function (gnutls_session_t              session,
+                                                                   const gnutls_datum_t         *req_ca_rdn,
+                                                                   int                           nreqs,
+                                                                   const gnutls_pk_algorithm_t  *pk_algos,
+                                                                   int                           
pk_algos_length,
+                                                                   gnutls_pcert_st             **pcert,
+                                                                   unsigned int                 
*pcert_length,
+                                                                   gnutls_privkey_t             *pkey)
+{
+  GTlsServerConnectionGnutls *gnutls = G_TLS_SERVER_CONNECTION_GNUTLS (gnutls_transport_get_ptr (session));
+
+  clear_gnutls_certificate_copy (gnutls);
+
+  g_tls_connection_gnutls_handshake_thread_get_certificate (G_TLS_CONNECTION_GNUTLS (gnutls),
+                                                            pcert, pcert_length, pkey);
+
+  gnutls->pcert = *pcert;
+  gnutls->pcert_length = *pcert_length;
+  gnutls->pkey = *pkey;
+
+  return 0;
+}
+
 static gboolean
 g_tls_server_connection_gnutls_initable_init (GInitable       *initable,
                                               GCancellable    *cancellable,
@@ -166,70 +181,15 @@ g_tls_server_connection_gnutls_set_property (GObject      *object,
     }
 }
 
-static int
-g_tls_server_connection_gnutls_handshake_thread_retrieve_function (gnutls_session_t              session,
-                                                                   const gnutls_datum_t         *req_ca_rdn,
-                                                                   int                           nreqs,
-                                                                   const gnutls_pk_algorithm_t  *pk_algos,
-                                                                   int                           
pk_algos_length,
-                                                                   gnutls_pcert_st             **pcert,
-                                                                   unsigned int                 
*pcert_length,
-                                                                   gnutls_privkey_t             *pkey)
-{
-  GTlsServerConnectionGnutls *gnutls = G_TLS_SERVER_CONNECTION_GNUTLS (gnutls_transport_get_ptr (session));
-
-  clear_gnutls_certificate_copy (gnutls);
-
-  g_tls_connection_gnutls_handshake_thread_get_certificate (G_TLS_CONNECTION_GNUTLS (gnutls),
-                                                            pcert, pcert_length, pkey);
-
-  gnutls->pcert = *pcert;
-  gnutls->pcert_length = *pcert_length;
-  gnutls->pkey = *pkey;
-
-  return 0;
-}
-
-static void
-g_tls_server_connection_gnutls_prepare_handshake (GTlsConnectionBase  *tls,
-                                                  gchar              **advertised_protocols)
-{
-  GTlsServerConnectionGnutls *gnutls = G_TLS_SERVER_CONNECTION_GNUTLS (tls);
-  gnutls_session_t session;
-  gnutls_certificate_request_t req_mode;
-
-  switch (gnutls->authentication_mode)
-    {
-    case G_TLS_AUTHENTICATION_REQUESTED:
-      req_mode = GNUTLS_CERT_REQUEST;
-      break;
-    case G_TLS_AUTHENTICATION_REQUIRED:
-      req_mode = GNUTLS_CERT_REQUIRE;
-      break;
-    case G_TLS_AUTHENTICATION_NONE:
-    default:
-      req_mode = GNUTLS_CERT_IGNORE;
-      break;
-    }
-
-  session = g_tls_connection_gnutls_get_session (G_TLS_CONNECTION_GNUTLS (tls));
-  gnutls_certificate_server_set_request (session, req_mode);
-
-  G_TLS_CONNECTION_BASE_CLASS (g_tls_server_connection_gnutls_parent_class)->prepare_handshake (tls, 
advertised_protocols);
-}
-
 static void
 g_tls_server_connection_gnutls_class_init (GTlsServerConnectionGnutlsClass *klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-  GTlsConnectionBaseClass *base_class = G_TLS_CONNECTION_BASE_CLASS (klass);
 
   gobject_class->finalize     = g_tls_server_connection_gnutls_finalize;
   gobject_class->get_property = g_tls_server_connection_gnutls_get_property;
   gobject_class->set_property = g_tls_server_connection_gnutls_set_property;
 
-  base_class->prepare_handshake  = g_tls_server_connection_gnutls_prepare_handshake;
-
   g_object_class_override_property (gobject_class, PROP_AUTHENTICATION_MODE, "authentication-mode");
 }
 


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