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



commit 3779db47f21f9930a9aebef852af70de27f78626
Author: Michael Catanzaro <mcatanzaro gnome org>
Date:   Sat Dec 21 19:10:02 2019 -0600

    progress

 tls/base/gtlsoperationsthread-base.c     | 46 ++++++++++++++-
 tls/base/gtlsoperationsthread-base.h     | 98 +++++++++++++++++---------------
 tls/gnutls/gtlsclientconnection-gnutls.c | 66 +++------------------
 tls/gnutls/gtlsoperationsthread-gnutls.c | 81 +++++++++++++++++++++++++-
 4 files changed, 181 insertions(+), 110 deletions(-)
---
diff --git a/tls/base/gtlsoperationsthread-base.c b/tls/base/gtlsoperationsthread-base.c
index 1c52d20..339aa65 100644
--- a/tls/base/gtlsoperationsthread-base.c
+++ b/tls/base/gtlsoperationsthread-base.c
@@ -79,6 +79,7 @@ typedef struct {
 
 typedef enum {
   G_TLS_THREAD_OP_COPY_CLIENT_SESSION_STATE,
+  G_TLS_THREAD_OP_SET_SERVER_IDENTITY,
   G_TLS_THREAD_OP_HANDSHAKE,
   G_TLS_THREAD_OP_READ,
   G_TLS_THREAD_OP_READ_MESSAGE,
@@ -97,6 +98,7 @@ typedef struct {
 
   union {
     GTlsOperationsThreadBase *source; /* for copy client session state */
+    gchar *server_identity;           /* for set server identity */
     gchar **advertised_protocols;     /* for handshake */
   };
 
@@ -168,6 +170,25 @@ g_tls_thread_copy_client_session_state_operation_new (GTlsOperationsThreadBase *
   return op;
 }
 
+static GTlsThreadOperation *
+g_tls_thread_set_server_identity_operation_new (GTlsOperationsThreadBase *thread,
+                                                GTlsConnectionBase       *connection,
+                                                const gchar              *server_identity)
+{
+  GTlsThreadOperation *op;
+
+  op = g_new0 (GTlsThreadOperation, 1);
+  op->type = G_TLS_THREAD_OP_SET_SERVER_IDENTITY;
+  op->thread = thread;
+  op->connection = connection;
+  op->server_identity = g_strdup (server_identity);
+
+  g_mutex_init (&op->finished_mutex);
+  g_cond_init (&op->finished_condition);
+
+  return op;
+}
+
 static GTlsThreadOperation *
 g_tls_thread_handshake_operation_new (GTlsOperationsThreadBase  *thread,
                                       GTlsConnectionBase        *connection,
@@ -331,6 +352,9 @@ g_tls_thread_shutdown_operation_new (void)
 static void
 g_tls_thread_operation_free (GTlsThreadOperation *op)
 {
+  if (op->type == G_TLS_THREAD_OP_SET_SERVER_IDENTITY)
+    g_free (op->server_identity);
+
   if (op->type == G_TLS_THREAD_OP_HANDSHAKE)
     g_strfreev (op->advertised_protocols);
 
@@ -383,8 +407,8 @@ execute_op (GTlsOperationsThreadBase *self,
 }
 
 void
-g_tls_operations_thread_base_copy_client_session_state (GTlsOperationsThreadBase  *self,
-                                                        GTlsOperationsThreadBase  *source)
+g_tls_operations_thread_base_copy_client_session_state (GTlsOperationsThreadBase *self,
+                                                        GTlsOperationsThreadBase *source)
 {
   GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
   GTlsThreadOperation *op;
@@ -395,6 +419,19 @@ g_tls_operations_thread_base_copy_client_session_state (GTlsOperationsThreadBase
   execute_op (self, g_steal_pointer (&op), NULL, NULL);
 }
 
+void
+g_tls_operations_thread_base_set_server_identity (GTlsOperationsThreadBase *self,
+                                                  const gchar              *server_identity)
+{
+  GTlsOperationsThreadBasePrivate *priv = g_tls_operations_thread_base_get_instance_private (self);
+  GTlsThreadOperation *op;
+
+  op = g_tls_thread_set_server_identity_operation_new (self,
+                                                       priv->connection,
+                                                       server_identity);
+  execute_op (self, g_steal_pointer (&op), NULL, NULL);
+}
+
 GTlsConnectionBaseStatus
 g_tls_operations_thread_base_handshake (GTlsOperationsThreadBase  *self,
                                         const gchar              **advertised_protocols,
@@ -825,6 +862,11 @@ process_op (GAsyncQueue         *queue,
       if (base_class->copy_client_session_state)
         base_class->copy_client_session_state (op->thread, op->source);
       break;
+    case G_TLS_THREAD_OP_SET_SERVER_IDENTITY:
+      g_assert (base_class->set_server_identity);
+      base_class->set_server_identity (op->thread,
+                                       op->server_identity);
+      break;
     case G_TLS_THREAD_OP_HANDSHAKE:
       op->result = base_class->handshake_fn (op->thread,
                                              (const gchar **)op->advertised_protocols,
diff --git a/tls/base/gtlsoperationsthread-base.h b/tls/base/gtlsoperationsthread-base.h
index 3774b43..b69d207 100644
--- a/tls/base/gtlsoperationsthread-base.h
+++ b/tls/base/gtlsoperationsthread-base.h
@@ -40,6 +40,8 @@ struct _GTlsOperationsThreadBaseClass
 
   void                        (*copy_client_session_state)  (GTlsOperationsThreadBase  *self,
                                                              GTlsOperationsThreadBase  *source);
+  void                        (*set_server_identity)        (GTlsOperationsThreadBase  *self,
+                                                             const gchar               *server_identity);
 
   GTlsConnectionBaseStatus    (*handshake_fn)               (GTlsOperationsThreadBase  *self,
                                                              const gchar              **advertised_protocols,
@@ -90,52 +92,54 @@ 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,
-                                                                       const gchar              
**advertised_protocols,
-                                                                       gint64                     timeout,
-                                                                       GCancellable              
*cancellable,
-                                                                       GError                   **error);
-
-GTlsConnectionBaseStatus  g_tls_operations_thread_base_read           (GTlsOperationsThreadBase  *self,
-                                                                       void                      *buffer,
-                                                                       gsize                      size,
-                                                                       gint64                     timeout,
-                                                                       gssize                    *nread,
-                                                                       GCancellable              
*cancellable,
-                                                                       GError                   **error);
-
-GTlsConnectionBaseStatus  g_tls_operations_thread_base_read_message   (GTlsOperationsThreadBase  *self,
-                                                                       GInputVector              *vectors,
-                                                                       guint                      
num_vectors,
-                                                                       gint64                     timeout,
-                                                                       gssize                    *nread,
-                                                                       GCancellable              
*cancellable,
-                                                                       GError                   **error);
-
-GTlsConnectionBaseStatus  g_tls_operations_thread_base_write          (GTlsOperationsThreadBase  *self,
-                                                                       const void                *buffer,
-                                                                       gsize                      size,
-                                                                       gint64                     timeout,
-                                                                       gssize                    *nwrote,
-                                                                       GCancellable              
*cancellable,
-                                                                       GError                   **error);
-
-GTlsConnectionBaseStatus  g_tls_operations_thread_base_write_message  (GTlsOperationsThreadBase  *self,
-                                                                       GOutputVector             *vectors,
-                                                                       guint                      
num_vectors,
-                                                                       gint64                     timeout,
-                                                                       gssize                    *nwrote,
-                                                                       GCancellable              
*cancellable,
-                                                                       GError                   **error);
-
-GTlsConnectionBaseStatus  g_tls_operations_thread_base_close          (GTlsOperationsThreadBase  *self,
-                                                                       GCancellable              
*cancellable,
-                                                                       GError                   **error);
+GTlsConnectionBase       *g_tls_operations_thread_base_get_connection            (GTlsOperationsThreadBase  
*self);
+
+void                      g_tls_operations_thread_base_copy_client_session_state (GTlsOperationsThreadBase  
*self,
+                                                                                  GTlsOperationsThreadBase  
*source);
+
+void                      g_tls_operations_thread_base_set_server_identity       (GTlsOperationsThreadBase  
*self,
+                                                                                  const gchar               
*server_identity);
+
+GTlsConnectionBaseStatus  g_tls_operations_thread_base_handshake                 (GTlsOperationsThreadBase  
*self,
+                                                                                  const gchar              
**advertised_protocols,
+                                                                                  gint64                     
timeout,
+                                                                                  GCancellable              
*cancellable,
+                                                                                  GError                   
**error);
+
+GTlsConnectionBaseStatus  g_tls_operations_thread_base_read                      (GTlsOperationsThreadBase  
*self,
+                                                                                  void                      
*buffer,
+                                                                                  gsize                      
size,
+                                                                                  gint64                     
timeout,
+                                                                                  gssize                    
*nread,
+                                                                                  GCancellable              
*cancellable,
+                                                                                  GError                   
**error);
+
+GTlsConnectionBaseStatus  g_tls_operations_thread_base_read_message              (GTlsOperationsThreadBase  
*self,
+                                                                                  GInputVector              
*vectors,
+                                                                                  guint                      
num_vectors,
+                                                                                  gint64                     
timeout,
+                                                                                  gssize                    
*nread,
+                                                                                  GCancellable              
*cancellable,
+                                                                                  GError                   
**error);
+
+GTlsConnectionBaseStatus  g_tls_operations_thread_base_write                     (GTlsOperationsThreadBase  
*self,
+                                                                                  const void                
*buffer,
+                                                                                  gsize                      
size,
+                                                                                  gint64                     
timeout,
+                                                                                  gssize                    
*nwrote,
+                                                                                  GCancellable              
*cancellable,
+                                                                                  GError                   
**error);
+
+GTlsConnectionBaseStatus  g_tls_operations_thread_base_write_message             (GTlsOperationsThreadBase  
*self,
+                                                                                  GOutputVector             
*vectors,
+                                                                                  guint                      
num_vectors,
+                                                                                  gint64                     
timeout,
+                                                                                  gssize                    
*nwrote,
+                                                                                  GCancellable              
*cancellable,
+                                                                                  GError                   
**error);
+
+GTlsConnectionBaseStatus  g_tls_operations_thread_base_close                     (GTlsOperationsThreadBase  
*self,
+                                                                                  GCancellable              
*cancellable,
+                                                                                  GError                   
**error);
 
 G_END_DECLS
diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c
index 3699c30..6e55ea4 100644
--- a/tls/gnutls/gtlsclientconnection-gnutls.c
+++ b/tls/gnutls/gtlsclientconnection-gnutls.c
@@ -112,34 +112,6 @@ get_server_identity (GTlsClientConnectionGnutls *gnutls)
     return NULL;
 }
 
-static int
-handshake_thread_session_ticket_received_cb (gnutls_session_t      session,
-                                             guint                 htype,
-                                             guint                 when,
-                                             guint                 incoming,
-                                             const gnutls_datum_t *msg)
-{
-  GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (gnutls_session_get_ptr (session));
-  gnutls_datum_t session_datum;
-
-  if (gnutls_session_get_data2 (session, &session_datum) == GNUTLS_E_SUCCESS)
-    {
-      g_clear_pointer (&gnutls->session_data, g_bytes_unref);
-      gnutls->session_data = g_bytes_new_with_free_func (session_datum.data,
-                                                         session_datum.size,
-                                                         (GDestroyNotify)gnutls_free,
-                                                         session_datum.data);
-
-      if (gnutls->session_id)
-        {
-          g_tls_backend_gnutls_store_session_data (gnutls->session_id,
-                                                   gnutls->session_data);
-        }
-    }
-
-  return 0;
-}
-
 static void
 g_tls_client_connection_gnutls_finalize (GObject *object)
 {
@@ -159,7 +131,7 @@ g_tls_client_connection_gnutls_initable_init (GInitable       *initable,
                                               GError         **error)
 {
   GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (initable);
-  gnutls_session_t session;
+  GTlsOperationsThreadBase *thread = g_tls_connection_base_get_op_thread (G_TLS_CONNECTION_BASE (gnutls));
   const gchar *hostname;
   gnutls_certificate_credentials_t creds;
 
@@ -169,23 +141,10 @@ 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);
 
-  session = g_tls_connection_gnutls_get_session (gnutls);
+
   hostname = get_server_identity (G_TLS_CLIENT_CONNECTION_GNUTLS (gnutls));
   if (hostname)
-    {
-      gchar *normalized_hostname = g_strdup (hostname);
-
-      if (hostname[strlen (hostname) - 1] == '.')
-        normalized_hostname[strlen (hostname) - 1] = '\0';
-
-      gnutls_server_name_set (session, GNUTLS_NAME_DNS,
-                              normalized_hostname, strlen (normalized_hostname));
-
-      g_free (normalized_hostname);
-    }
-
-  gnutls_handshake_set_hook_function (session, GNUTLS_HANDSHAKE_NEW_SESSION_TICKET,
-                                      GNUTLS_HOOK_POST, handshake_thread_session_ticket_received_cb);
+    g_tls_operations_thread_base_set_server_identity (thread, hostname);
 
   return TRUE;
 }
@@ -256,22 +215,10 @@ g_tls_client_connection_gnutls_set_property (GObject      *object,
       hostname = get_server_identity (gnutls);
       if (hostname)
         {
-          gnutls_session_t session = g_tls_connection_gnutls_get_session (G_TLS_CONNECTION_GNUTLS (gnutls));
+          GTlsOperationsThreadBase *thread;
 
-          /* This will only be triggered if the identity is set after
-           * initialization */
-          if (session)
-            {
-              gchar *normalized_hostname = g_strdup (hostname);
-
-              if (hostname[strlen (hostname) - 1] == '.')
-                normalized_hostname[strlen (hostname) - 1] = '\0';
-
-              gnutls_server_name_set (session, GNUTLS_NAME_DNS,
-                                      normalized_hostname, strlen (normalized_hostname));
-
-              g_free (normalized_hostname);
-            }
+          thread = g_tls_connection_base_get_op_thread (G_TLS_CONNECTION_BASE (gnutls));
+          g_tls_operations_thread_base_set_server_identity (thread, hostname);
         }
       break;
 
@@ -363,6 +310,7 @@ g_tls_client_connection_gnutls_handshake_thread_retrieve_function (gnutls_sessio
 
   return 0;
 }
+
 static void
 g_tls_client_connection_gnutls_complete_handshake (GTlsConnectionBase  *tls,
                                                    gchar              **negotiated_protocol,
diff --git a/tls/gnutls/gtlsoperationsthread-gnutls.c b/tls/gnutls/gtlsoperationsthread-gnutls.c
index b07a1a1..2b9e959 100644
--- a/tls/gnutls/gtlsoperationsthread-gnutls.c
+++ b/tls/gnutls/gtlsoperationsthread-gnutls.c
@@ -51,6 +51,8 @@ struct _GTlsOperationsThreadGnutls {
   GBytes                  *session_data;
   gboolean                 session_data_override; /* FIXME: sort this all out */
 
+  gchar                   *server_identity;
+
   gnutls_session_t         session;
 
   GIOStream               *base_iostream;
@@ -86,6 +88,12 @@ is_dtls (GTlsOperationsThreadGnutls *self)
   return self->init_flags & GNUTLS_DATAGRAM;
 }
 
+static inline gboolean
+is_client (GTlsOperationsThreadGnutls *self)
+{
+  return self->init_flags & GNUTLS_CLIENT;
+}
+
 static GTlsConnectionBaseStatus
 end_gnutls_io (GTlsOperationsThreadGnutls  *self,
                GIOCondition                 direction,
@@ -333,7 +341,7 @@ compute_session_id (GTlsOperationsThreadGnutls *self)
           port = g_inet_socket_address_get_port (isaddr);
 
           addrstr = g_inet_address_to_string (iaddr);
-          server_hostname = get_server_identity (self);
+          server_hostname = self->server_identity;
 
           /* If we have a certificate, make its hash part of the session ID, so
            * that different connections to the same server can use different
@@ -436,6 +444,35 @@ g_tls_operations_thread_gnutls_copy_client_session_state (GTlsOperationsThreadBa
   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--;
+    }
+
+  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 GTlsConnectionBaseStatus
 g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase  *base,
                                           const gchar              **advertised_protocols,
@@ -469,7 +506,8 @@ g_tls_operations_thread_gnutls_handshake (GTlsOperationsThreadBase  *base,
   if (advertised_protocols)
     set_advertised_protocols (self, advertised_protocols);
 
-  set_session_data (self);
+  if (is_client (self))
+    set_session_data (self);
 
   self->handshaking = TRUE;
 
@@ -950,6 +988,34 @@ g_tls_operations_thread_gnutls_pull_timeout_func (gnutls_transport_ptr_t transpo
   return 0;
 }
 
+static int
+session_ticket_received_cb (gnutls_session_t      session,
+                            guint                 htype,
+                            guint                 when,
+                            guint                 incoming,
+                            const gnutls_datum_t *msg)
+{
+  GTlsOperationsThreadGnutls *self = G_TLS_OPERATIONS_THREAD_GNUTLS (gnutls_session_get_ptr (session));
+  gnutls_datum_t session_datum;
+
+  if (gnutls_session_get_data2 (session, &session_datum) == GNUTLS_E_SUCCESS)
+    {
+      g_clear_pointer (&self->session_data, g_bytes_unref);
+      self->session_data = g_bytes_new_with_free_func (session_datum.data,
+                                                       session_datum.size,
+                                                       (GDestroyNotify)gnutls_free,
+                                                       session_datum.data);
+
+      if (self->session_id)
+        {
+          g_tls_backend_gnutls_store_session_data (self->session_id,
+                                                   self->session_data);
+        }
+    }
+
+  return 0;
+}
+
 static void
 g_tls_operations_thread_gnutls_get_property (GObject    *object,
                                              guint       prop_id,
@@ -1014,6 +1080,8 @@ g_tls_operations_thread_gnutls_finalize (GObject *object)
   g_clear_pointer (&self->session_id, g_bytes_unref);
   g_clear_pointer (&self->session_data, g_bytes_unref);
 
+  g_clear_pointer (&self->server_identity, g_free);
+
   g_clear_object (&self->base_iostream);
   g_clear_object (&self->base_socket);
 
@@ -1078,6 +1146,14 @@ g_tls_operations_thread_gnutls_constructed (GObject *object)
       /* Set reasonable MTU */
       gnutls_dtls_set_mtu (self->session, 1400);
     }
+
+  if (is_client (self))
+    {
+      gnutls_handshake_set_hook_function (self->session,
+                                          GNUTLS_HANDSHAKE_NEW_SESSION_TICKET,
+                                          GNUTLS_HOOK_POST,
+                                          session_ticket_received_cb);
+    }
 }
 
 static void
@@ -1097,6 +1173,7 @@ g_tls_operations_thread_gnutls_class_init (GTlsOperationsThreadGnutlsClass *klas
   gobject_class->set_property  = g_tls_operations_thread_gnutls_set_property;
 
   base_class->copy_client_session_state = g_tls_operations_thread_gnutls_copy_client_session_state;
+  base_class->set_server_identity       = g_tls_operations_thread_gnutls_set_server_identity;
   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;


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