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