[glib-networking/mcatanzaro/tls-thread: 9/24] progress
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/tls-thread: 9/24] progress
- Date: Sat, 28 Dec 2019 21:04:13 +0000 (UTC)
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]