[glib-networking/mcatanzaro/base-rebase: 33/33] more progress
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/base-rebase: 33/33] more progress
- Date: Fri, 19 Apr 2019 22:33:53 +0000 (UTC)
commit 7e735a8856fdcc68f802da63950b42fb7fc0135b
Author: Michael Catanzaro <mcatanzaro igalia com>
Date: Fri Apr 19 17:30:37 2019 -0500
more progress
tls/base/gtlsconnection-base.c | 80 +--
tls/gnutls/gtlsclientconnection-gnutls.c | 11 +-
tls/gnutls/gtlsconnection-gnutls.c | 861 +++--------------------------
tls/gnutls/gtlsconnection-gnutls.h | 7 +-
tls/gnutls/gtlsserverconnection-gnutls.c | 11 +-
tls/openssl/gtlsclientconnection-openssl.c | 25 -
tls/openssl/gtlsconnection-openssl.c | 9 +-
tls/openssl/gtlsserverconnection-openssl.c | 15 +-
8 files changed, 150 insertions(+), 869 deletions(-)
---
diff --git a/tls/base/gtlsconnection-base.c b/tls/base/gtlsconnection-base.c
index 73f2a8b..8602265 100644
--- a/tls/base/gtlsconnection-base.c
+++ b/tls/base/gtlsconnection-base.c
@@ -92,6 +92,11 @@ typedef struct
GTlsCertificate *peer_certificate;
GTlsCertificateFlags peer_certificate_errors;
+ GMutex verify_certificate_mutex;
+ GCond verify_certificate_condition;
+ gboolean peer_certificate_accepted;
+ gboolean peer_certificate_examined;
+
gboolean require_close_notify;
GTlsRehandshakeMode rehandshake_mode;
@@ -121,6 +126,7 @@ typedef struct
gboolean started_handshake;
gboolean handshaking;
gboolean ever_handshaked;
+ GMainContext *handshake_context;
GTask *implicit_handshake;
GError *handshake_error;
GByteArray *app_data_buf;
@@ -209,7 +215,11 @@ g_tls_connection_base_init (GTlsConnectionBase *tls)
priv->database_is_unset = TRUE;
priv->is_system_certdb = TRUE;
+ g_mutex_init (&priv->verify_certificate_mutex);
+ g_cond_init (&priv->verify_certificate_condition);
+
g_mutex_init (&priv->op_mutex);
+
priv->waiting_for_op = g_cancellable_new ();
g_cancellable_cancel (priv->waiting_for_op);
}
@@ -231,8 +241,13 @@ g_tls_connection_base_finalize (GObject *object)
g_clear_error (&priv->certificate_error);
g_clear_object (&priv->peer_certificate);
+ g_mutex_clear (&priv->verify_certificate_mutex);
+ g_cond_clear (&priv->verify_certificate_condition);
+
g_clear_object (&priv->interaction);
+ g_clear_pointer (&priv->handshake_context, g_main_context_unref);
+
/* This must always be NULL at this point, as it holds a reference to @tls as
* its source object. However, we clear it anyway just in case this changes
* in future. */
@@ -249,11 +264,9 @@ g_tls_connection_base_finalize (GObject *object)
g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
-#if GLIB_CHECK_VERSION(2, 60, 0)
g_clear_pointer (&priv->advertised_protocols, g_strfreev);
g_clear_pointer (&priv->negotiated_protocol, g_free);
-#endif
-
+c
G_OBJECT_CLASS (g_tls_connection_base_parent_class)->finalize (object);
}
@@ -508,6 +521,7 @@ claim_op (GTlsConnectionBase *tls,
g_mutex_unlock (&priv->op_mutex);
success = finish_handshake (tls, priv->implicit_handshake, &my_error);
g_clear_object (&priv->implicit_handshake);
+ g_clear_pointer (&priv->handshake_context, g_main_context_unref);
g_mutex_lock (&priv->op_mutex);
if (op != G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH &&
@@ -1247,11 +1261,21 @@ finish_handshake (GTlsConnectionBase *tls,
orig_negotiated_protocol = g_steal_pointer (&priv->negotiated_protocol);
if (g_task_propagate_boolean (task, &my_error))
- tls_class->complete_handshake (tls, &priv->negotiated_protocol, &my_error);
+ {
+ if (tls_class->complete_handshake)
+ tls_class->complete_handshake (tls, &priv->negotiated_protocol, &my_error);
+
+ if (g_strcmp0 (original_negotiated_protocol, priv->negotiated_protocol) != 0)
+ g_object_notify (G_OBJECT (tls), "negotiated-protocol");
+ g_free (original_negotiated_protocol);
- if (g_strcmp0 (original_negotiated_protocol, priv->negotiated_protocol) != 0)
- g_object_notify (G_OBJECT (tls), "negotiated-protocol");
- g_free (original_negotiated_protocol);
+ /* FIXME: Return an error from the handshake thread instead. */
+ if (priv->peer_certificate && !priv->peer_certificate_accepted)
+ {
+ g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
+ _("Unacceptable TLS certificate"));
+ }
+ }
if (my_error && priv->started_handshake)
priv->handshake_error = g_error_copy (my_error);
@@ -1333,8 +1357,6 @@ handshake_thread_completed (GObject *object,
GError *error = NULL;
gboolean need_finish_handshake, success;
- g_clear_pointer (&priv->handshake_context, g_main_context_unref);
-
g_mutex_lock (&priv->op_mutex);
if (priv->need_finish_handshake)
{
@@ -1358,6 +1380,7 @@ handshake_thread_completed (GObject *object,
else
g_task_return_boolean (caller_task, TRUE);
+ g_clear_pointer (&priv->handshake_context, g_main_context_unref);
g_object_unref (caller_task);
}
@@ -1400,9 +1423,13 @@ g_tls_connection_base_handshake_async (GTlsConnection *conn,
g_assert (!priv->handshake_context);
priv->handshake_context = g_main_context_ref_thread_default ();
+ if (tls_class->prepare_handshake)
+ tls_class->prepare_handshake (tls, priv->advertised_protocols);
+
caller_task = g_task_new (conn, cancellable, callback, user_data);
g_task_set_source_tag (caller_task, g_tls_connection_base_handshake_async);
g_task_set_priority (caller_task, io_priority);
+
thread_task = g_task_new (conn, cancellable, handshake_thread_completed, caller_task);
g_task_set_source_tag (thread_task, g_tls_connection_base_handshake_async);
g_task_set_priority (thread_task, io_priority);
@@ -1445,22 +1472,6 @@ g_tls_connection_base_dtls_handshake_finish (GDtlsConnection *conn,
result, error);
}
-static void
-implicit_handshake_completed (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (object);
- GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
-
- g_mutex_lock (&priv->op_mutex);
- priv->need_finish_handshake = TRUE;
- g_mutex_unlock (&priv->op_mutex);
-
- yield_op (tls, G_TLS_CONNECTION_BASE_OP_HANDSHAKE,
- G_TLS_CONNECTION_BASE_OK);
-}
-
static gboolean
do_implicit_handshake (GTlsConnectionBase *tls,
gint64 timeout,
@@ -1493,6 +1504,9 @@ do_implicit_handshake (GTlsConnectionBase *tls,
g_task_set_task_data (priv->implicit_handshake,
thread_timeout, g_free);
+ if (tls_class->prepare_handshake)
+ tls_class->prepare_handshake (tls, priv->advertised_protocols);
+
if (timeout != 0)
{
GError *my_error = NULL;
@@ -1509,18 +1523,20 @@ do_implicit_handshake (GTlsConnectionBase *tls,
g_task_set_return_on_cancel (priv->implicit_handshake, TRUE);
g_task_run_in_thread (priv->implicit_handshake, handshake_thread);
- crank_sync_handshake_context (tls, cancellable);
-
- g_main_context_pop_thread_default (priv->handshake_context);
- g_clear_pointer (&priv->handshake_context, g_main_context_unref);
+ crank_sync_handshake_context (tls, cancellable);
success = finish_handshake (tls,
priv->implicit_handshake,
&my_error);
+
+ g_main_context_pop_thread_default (priv->handshake_context);
+ g_clear_pointer (&priv->handshake_context, g_main_context_unref);
g_clear_object (&priv->implicit_handshake);
+
yield_op (tls, G_TLS_CONNECTION_BASE_OP_HANDSHAKE,
G_TLS_CONNECTION_BASE_OK);
+
g_mutex_lock (&priv->op_mutex);
if (my_error)
@@ -2076,7 +2092,6 @@ g_tls_connection_base_dtls_shutdown_finish (GDtlsConnection *conn,
return g_task_propagate_boolean (G_TASK (result), error);
}
-#if GLIB_CHECK_VERSION(2, 60, 0)
static void
g_tls_connection_base_dtls_set_advertised_protocols (GDtlsConnection *conn,
const gchar * const *protocols)
@@ -2092,7 +2107,6 @@ g_tls_connection_base_dtls_get_negotiated_protocol (GDtlsConnection *conn)
return priv->negotiated_protocol;
}
-#endif
gboolean
g_tls_connection_base_is_dtls (GTlsConnectionBase *tls)
@@ -2285,10 +2299,8 @@ g_tls_connection_base_class_init (GTlsConnectionBaseClass *klass)
g_object_class_override_property (gobject_class, PROP_INTERACTION, "interaction");
g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE, "peer-certificate");
g_object_class_override_property (gobject_class, PROP_PEER_CERTIFICATE_ERRORS, "peer-certificate-errors");
-#if GLIB_CHECK_VERSION(2, 60, 0)
g_object_class_override_property (gobject_class, PROP_ADVERTISED_PROTOCOLS, "advertised-protocols");
g_object_class_override_property (gobject_class, PROP_NEGOTIATED_PROTOCOL, "negotiated-protocol");
-#endif
}
static void
@@ -2300,10 +2312,8 @@ g_tls_connection_base_dtls_connection_iface_init (GDtlsConnectionInterface *ifac
iface->shutdown = g_tls_connection_base_dtls_shutdown;
iface->shutdown_async = g_tls_connection_base_dtls_shutdown_async;
iface->shutdown_finish = g_tls_connection_base_dtls_shutdown_finish;
-#if GLIB_CHECK_VERSION(2, 60, 0)
iface->set_advertised_protocols = g_tls_connection_base_dtls_set_advertised_protocols;
iface->get_negotiated_protocol = g_tls_connection_gnutls_dtls_get_negotiated_protocol;
-#endif
}
static void
diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c
index fc5227b..d94188b 100644
--- a/tls/gnutls/gtlsclientconnection-gnutls.c
+++ b/tls/gnutls/gtlsclientconnection-gnutls.c
@@ -398,10 +398,9 @@ g_tls_client_connection_gnutls_failed (GTlsConnectionGnutls *conn)
g_tls_backend_gnutls_remove_session (GNUTLS_CLIENT, gnutls->session_id);
}
-static GTlsConnectionBaseStatus
+static void
g_tls_client_connection_gnutls_handshake (GTlsConnectionBase *tls,
- GCancellable *cancellable,
- GError **error)
+ gchar **advertised_protocols)
{
GTlsClientConnectionGnutls *gnutls = G_TLS_CLIENT_CONNECTION_GNUTLS (tls);
@@ -429,8 +428,8 @@ g_tls_client_connection_gnutls_handshake (GTlsConnectionBase *tls,
}
}
- return G_TLS_CONNECTION_BASE_CLASS (g_tls_client_connection_gnutls_parent_class)->
- handshake (tls, cancellable, error);
+ G_TLS_CONNECTION_BASE_CLASS (g_tls_client_connection_gnutls_parent_class)->
+ prepare_handshake (tls, advertised_protocols);
}
static GTlsConnectionBaseStatus
@@ -505,7 +504,7 @@ g_tls_client_connection_gnutls_class_init (GTlsClientConnectionGnutlsClass *klas
gobject_class->set_property = g_tls_client_connection_gnutls_set_property;
gobject_class->finalize = g_tls_client_connection_gnutls_finalize;
- base_class->begin_handshake = g_tls_client_connection_gnutls_handshake;
+ base_class->prepare_handshake = g_tls_client_connection_gnutls_prepare_handshake;
base_class->complete_handshake = g_tls_client_connection_gnutls_complete_handshake;
gnutls_class->failed = g_tls_client_connection_gnutls_failed;
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index 0d1bd37..537d465 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -346,7 +346,9 @@ end_gnutls_io (GTlsConnectionGnutls *gnutls,
g_assert (status == G_TLS_CONNECTION_BASE_ERROR);
// FIXME: Right place?
+#if 0
G_TLS_CONNECTION_GNUTLS_GET_CLASS (gnutls)->failed (gnutls);
+#endif
handshaking = g_tls_connection_base_is_handshaking (tls);
ever_handshaked = g_tls_connection_base_ever_handshaked (tls);
@@ -431,11 +433,7 @@ end_gnutls_io (GTlsConnectionGnutls *gnutls,
{
g_clear_error (&my_error);
g_set_error_literal (error, G_TLS_ERROR,
-#if GLIB_CHECK_VERSION(2, 60, 0)
G_TLS_ERROR_INAPPROPRIATE_FALLBACK,
-#else
- G_TLS_ERROR_MISC,
-#endif
_("Protocol version downgrade attack detected"));
return G_TLS_CONNECTION_BASE_ERROR;
}
@@ -1053,9 +1051,10 @@ g_tls_connection_gnutls_complete_handshake (GTlsConnectionBase *tls,
{
GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
+ gnutls_datum_t protocol;
- g_clear_pointer (&priv->handshake_context, g_main_context_unref);
-
+// FIXME: move
+#if 0
if (gnutls_session_is_resumed (priv->session))
{
/* Because this session was resumed, we skipped certificate
@@ -1072,338 +1071,44 @@ g_tls_connection_gnutls_complete_handshake (GTlsConnectionBase *tls,
priv->peer_certificate_accepted = TRUE;
g_mutex_unlock (&priv->verify_certificate_mutex);
}
+#endif
- if (g_task_propagate_boolean (task, error) &&
- priv->peer_certificate && !priv->peer_certificate_accepted)
- {
- g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_BAD_CERTIFICATE,
- _("Unacceptable TLS certificate"));
- }
-
-// FIXME: this needs to remain in GnuTLS class
- if (!*error && priv->advertised_protocols)
- update_negotiated_protocol (gnutls);
-
- if (*error && priv->started_handshake)
- priv->handshake_error = g_error_copy (*error);
-
- return (*error == NULL);
-}
-
-static gboolean
-g_tls_connection_gnutls_handshake (GTlsConnection *conn,
- GCancellable *cancellable,
- GError **error)
-{
- GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (conn);
- GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
- GTask *task;
- gboolean success;
- gint64 *timeout = NULL;
- GError *my_error = NULL;
-
- g_assert (priv->handshake_context == NULL);
- priv->handshake_context = g_main_context_new ();
-
- g_main_context_push_thread_default (priv->handshake_context);
-
- begin_handshake (gnutls);
-
- task = g_task_new (conn, cancellable, sync_handshake_thread_completed, NULL);
- g_task_set_source_tag (task, g_tls_connection_gnutls_handshake);
- g_task_set_return_on_cancel (task, TRUE);
-
- timeout = g_new0 (gint64, 1);
- *timeout = -1; /* blocking */
- g_task_set_task_data (task, timeout, g_free);
-
- g_task_run_in_thread (task, handshake_thread);
- crank_sync_handshake_context (gnutls, cancellable);
-
- success = finish_handshake (gnutls, task, &my_error);
-
- g_main_context_pop_thread_default (priv->handshake_context);
- g_clear_pointer (&priv->handshake_context, g_main_context_unref);
- g_object_unref (task);
-
- yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
-
- if (my_error)
- g_propagate_error (error, my_error);
- return success;
-}
-
-static gboolean
-g_tls_connection_gnutls_dtls_handshake (GDtlsConnection *conn,
- GCancellable *cancellable,
- GError **error)
-{
- return g_tls_connection_gnutls_handshake (G_TLS_CONNECTION (conn),
- cancellable, error);
-}
-
-/* In the async version we use two GTasks; one to run handshake_thread() and
- * then call handshake_thread_completed(), and a second to call the caller's
- * original callback after we call finish_handshake().
- */
-
-static void
-handshake_thread_completed (GObject *object,
- GAsyncResult *result,
- gpointer user_data)
-{
- GTask *caller_task = user_data;
- GTlsConnectionGnutls *gnutls = g_task_get_source_object (caller_task);
- GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
- GError *error = NULL;
- gboolean need_finish_handshake, success;
-
- g_mutex_lock (&priv->op_mutex);
- if (priv->need_finish_handshake)
- {
- need_finish_handshake = TRUE;
- priv->need_finish_handshake = FALSE;
- }
- else
- need_finish_handshake = FALSE;
- g_mutex_unlock (&priv->op_mutex);
-
- if (need_finish_handshake)
- {
- success = finish_handshake (gnutls, G_TASK (result), &error);
- if (success)
- g_task_return_boolean (caller_task, TRUE);
- else
- g_task_return_error (caller_task, error);
- }
- else if (priv->handshake_error)
- g_task_return_error (caller_task, g_error_copy (priv->handshake_error));
- else
- g_task_return_boolean (caller_task, TRUE);
-
- g_clear_pointer (&priv->handshake_context, g_main_context_unref);
- g_object_unref (caller_task);
-}
-
-static void
-async_handshake_thread (GTask *task,
- gpointer object,
- gpointer task_data,
- GCancellable *cancellable)
-{
- GTlsConnectionGnutls *gnutls = object;
- GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
-
- handshake_thread (task, object, task_data, cancellable);
-
- g_mutex_lock (&priv->op_mutex);
- priv->need_finish_handshake = TRUE;
- /* yield_op will clear handshaking too, but we don't want the
- * connection to be briefly "handshaking && need_finish_handshake"
- * after we unlock the mutex.
- */
- priv->handshaking = FALSE;
- g_mutex_unlock (&priv->op_mutex);
-
- yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
-}
-
-static void
-g_tls_connection_gnutls_handshake_async (GTlsConnection *conn,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (G_TLS_CONNECTION_GNUTLS
(conn));
- GTask *thread_task, *caller_task;
- gint64 *timeout = NULL;
-
- g_assert (!priv->handshake_context);
- priv->handshake_context = g_main_context_ref_thread_default ();
-
- caller_task = g_task_new (conn, cancellable, callback, user_data);
- g_task_set_source_tag (caller_task, g_tls_connection_gnutls_handshake_async);
- g_task_set_priority (caller_task, io_priority);
-
- begin_handshake (G_TLS_CONNECTION_GNUTLS (conn));
-
- thread_task = g_task_new (conn, cancellable,
- handshake_thread_completed, caller_task);
- g_task_set_source_tag (thread_task, g_tls_connection_gnutls_handshake_async);
- g_task_set_priority (thread_task, io_priority);
-
- timeout = g_new0 (gint64, 1);
- *timeout = -1; /* blocking */
- g_task_set_task_data (thread_task, timeout, g_free);
-
- g_task_run_in_thread (thread_task, async_handshake_thread);
- g_object_unref (thread_task);
-}
-
-static gboolean
-g_tls_connection_gnutls_handshake_finish (GTlsConnection *conn,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
-
- return g_task_propagate_boolean (G_TASK (result), error);
-}
-
-static void
-g_tls_connection_gnutls_dtls_handshake_async (GDtlsConnection *conn,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_tls_connection_gnutls_handshake_async (G_TLS_CONNECTION (conn), io_priority,
- cancellable, callback, user_data);
-}
-
-static gboolean
-g_tls_connection_gnutls_dtls_handshake_finish (GDtlsConnection *conn,
- GAsyncResult *result,
- GError **error)
-{
- return g_tls_connection_gnutls_handshake_finish (G_TLS_CONNECTION (conn),
- result, error);
-}
-
-static gboolean
-do_implicit_handshake (GTlsConnectionGnutls *gnutls,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
-{
- GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
- gint64 *thread_timeout = NULL;
-
- /* We have op_mutex */
-
- g_assert (priv->handshake_context == NULL);
- if (timeout != 0)
- {
- priv->handshake_context = g_main_context_new ();
- g_main_context_push_thread_default (priv->handshake_context);
- }
- else
- {
- priv->handshake_context = g_main_context_ref_thread_default ();
- }
-
- g_assert (priv->implicit_handshake == NULL);
- priv->implicit_handshake = g_task_new (gnutls, cancellable,
- timeout ? sync_handshake_thread_completed : NULL,
- NULL);
- g_task_set_source_tag (priv->implicit_handshake,
- do_implicit_handshake);
-
- thread_timeout = g_new0 (gint64, 1);
- g_task_set_task_data (priv->implicit_handshake,
- thread_timeout, g_free);
-
- begin_handshake (gnutls);
-
- if (timeout != 0)
- {
- GError *my_error = NULL;
- gboolean success;
-
- /* In the blocking case, run the handshake operation synchronously in
- * another thread, and delegate handling the timeout to that thread; it
- * should return G_IO_ERROR_TIMED_OUT iff (timeout > 0) and the operation
- * times out. If (timeout < 0) it should block indefinitely until the
- * operation is complete or errors. */
- *thread_timeout = timeout;
-
- g_mutex_unlock (&priv->op_mutex);
-
- g_task_set_return_on_cancel (priv->implicit_handshake, TRUE);
- g_task_run_in_thread (priv->implicit_handshake, handshake_thread);
-
- crank_sync_handshake_context (gnutls, cancellable);
-
- success = finish_handshake (gnutls,
- priv->implicit_handshake,
- &my_error);
-
- g_main_context_pop_thread_default (priv->handshake_context);
- g_clear_pointer (&priv->handshake_context, g_main_context_unref);
- g_clear_object (&priv->implicit_handshake);
-
- yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE);
-
- g_mutex_lock (&priv->op_mutex);
-
- if (my_error)
- g_propagate_error (error, my_error);
- return success;
- }
- else
+ if (gnutls_alpn_get_selected_protocol (priv->session, &protocol) == 0 && protocol.size > 0)
{
- /* In the non-blocking case, start the asynchronous handshake operation
- * and return EWOULDBLOCK to the caller, who will handle polling for
- * completion of the handshake and whatever operation they actually cared
- * about. Run the actual operation as blocking in its thread. */
- *thread_timeout = -1; /* blocking */
-
- g_task_run_in_thread (priv->implicit_handshake,
- async_handshake_thread);
-
- /* Intentionally not translated because this is not a fatal error to be
- * presented to the user, and to avoid this showing up in profiling. */
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, "Operation would block");
- return FALSE;
+ g_assert (!*negotiated_protocol);
+ *negotiated_protocol = g_strndup ((gchar *)protocol.data, protocol.size);
}
}
-gssize
-g_tls_connection_gnutls_read (GTlsConnectionGnutls *gnutls,
- void *buffer,
- gsize count,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
+static GTlsConnectionBaseStatus
+g_tls_connection_gnutls_read (GTlsConnectionBase *gtls,
+ void *buffer,
+ gsize count,
+ gint64 timeout,
+ gssize *nread,
+ GCancellable *cancellable,
+ GError **error)
{
+ GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
+ GTlsConnectionBaseStatus status;
gssize ret;
- if (priv->app_data_buf && !priv->handshaking)
- {
- ret = MIN (count, priv->app_data_buf->len);
- memcpy (buffer, priv->app_data_buf->data, ret);
- if (ret == priv->app_data_buf->len)
- g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
- else
- g_byte_array_remove_range (priv->app_data_buf, 0, ret);
- return ret;
- }
-
- again:
- if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
- timeout, cancellable, error))
- return -1;
-
BEGIN_GNUTLS_IO (gnutls, G_IO_IN, timeout, cancellable);
ret = gnutls_record_recv (priv->session, buffer, count);
- END_GNUTLS_IO (gnutls, G_IO_IN, ret, _("Error reading data from TLS socket"), error);
+ END_GNUTLS_IO (gnutls, G_IO_IN, ret, status, _("Error reading data from TLS socket"), error);
yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
if (ret >= 0)
- return ret;
- else if (ret == GNUTLS_E_REHANDSHAKE)
- goto again;
- else
- return -1;
+ *nread = ret;
+ return status;
}
static gsize
-input_vectors_from_gnutls_datum_t (GInputVector *vectors,
- guint num_vectors,
- const gnutls_datum_t *datum)
+input_vectors_from_gnutls_datum_t (GInputVector *vectors,
+ guint num_vectors,
+ const gnutls_datum_t *datum)
{
guint i;
gsize total = 0;
@@ -1425,47 +1130,21 @@ input_vectors_from_gnutls_datum_t (GInputVector *vectors,
return total;
}
-static gssize
-g_tls_connection_gnutls_read_message (GTlsConnectionGnutls *gnutls,
- GInputVector *vectors,
- guint num_vectors,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
+static GTlsConnectionBaseStatus
+g_tls_connection_gnutls_read_message (GTlsConnectionBase *tls,
+ GInputVector *vectors,
+ guint num_vectors,
+ gint64 timeout,
+ gssize *nread,
+ GCancellable *cancellable,
+ GError **error)
{
- GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
- guint i;
+ GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
+ GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (tls);
+ GTlsConnectionBaseStatus status;
gssize ret;
gnutls_packet_t packet = { 0, };
- /* Copy data out of the app data buffer first. */
- if (priv->app_data_buf && !priv->handshaking)
- {
- ret = 0;
-
- for (i = 0; i < num_vectors; i++)
- {
- gsize count;
- GInputVector *vec = &vectors[i];
-
- count = MIN (vec->size, priv->app_data_buf->len);
- ret += count;
-
- memcpy (vec->buffer, priv->app_data_buf->data, count);
- if (count == priv->app_data_buf->len)
- g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
- else
- g_byte_array_remove_range (priv->app_data_buf, 0, count);
- }
-
- return ret;
- }
-
- again:
- if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ,
- timeout, cancellable, error))
- return -1;
-
BEGIN_GNUTLS_IO (gnutls, G_IO_IN, timeout, cancellable);
/* Receive the entire datagram (zero-copy). */
@@ -1480,148 +1159,57 @@ g_tls_connection_gnutls_read_message (GTlsConnectionGnutls *gnutls,
gnutls_packet_deinit (packet);
}
- END_GNUTLS_IO (gnutls, G_IO_IN, ret, _("Error reading data from TLS socket"), error);
-
- yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_READ);
+ END_GNUTLS_IO (gnutls, G_IO_IN, ret, status, _("Error reading data from TLS socket"), error);
if (ret >= 0)
- return ret;
- else if (ret == GNUTLS_E_REHANDSHAKE)
- goto again;
- else
- return -1;
-}
-
-static gint
-g_tls_connection_gnutls_receive_messages (GDatagramBased *datagram_based,
- GInputMessage *messages,
- guint num_messages,
- gint flags,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
-{
- GTlsConnectionGnutls *gnutls;
- guint i;
- GError *child_error = NULL;
-
- gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
-
- if (flags != G_SOCKET_MSG_NONE)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- _("Receive flags are not supported"));
- return -1;
- }
-
- for (i = 0; i < num_messages && child_error == NULL; i++)
- {
- GInputMessage *message = &messages[i];
- gssize n_bytes_read;
-
- n_bytes_read = g_tls_connection_gnutls_read_message (gnutls,
- message->vectors,
- message->num_vectors,
- timeout,
- cancellable,
- &child_error);
-
- if (message->address != NULL)
- *message->address = NULL;
- message->flags = G_SOCKET_MSG_NONE;
- if (message->control_messages != NULL)
- *message->control_messages = NULL;
- message->num_control_messages = 0;
-
- if (n_bytes_read > 0)
- {
- message->bytes_received = n_bytes_read;
- }
- else if (n_bytes_read == 0)
- {
- /* EOS. */
- break;
- }
- else if (i > 0 &&
- (g_error_matches (child_error,
- G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) ||
- g_error_matches (child_error,
- G_IO_ERROR, G_IO_ERROR_TIMED_OUT)))
- {
- /* Blocked or timed out after receiving some messages successfully. */
- g_clear_error (&child_error);
- break;
- }
- else
- {
- /* Error, including G_IO_ERROR_WOULD_BLOCK or G_IO_ERROR_TIMED_OUT on
- * the first message; or G_IO_ERROR_CANCELLED at any time. */
- break;
- }
- }
-
- if (child_error != NULL)
- {
- g_propagate_error (error, child_error);
- return -1;
- }
-
- return i;
+ *nread = ret;
+ return status;
}
-gssize
-g_tls_connection_gnutls_write (GTlsConnectionGnutls *gnutls,
- const void *buffer,
- gsize count,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
+static GTlsConnectionBaseStatus
+g_tls_connection_gnutls_write (GTlsConnectionBase *tls,
+ const void *buffer,
+ gsize count,
+ gint64 timeout,
+ gssize *nwrote,
+ GCancellable *cancellable,
+ GError **error)
{
+ GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
+ GTlsConnectionBaseStatus status;
gssize ret;
- again:
- if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
- timeout, cancellable, error))
- return -1;
-
BEGIN_GNUTLS_IO (gnutls, G_IO_OUT, timeout, cancellable);
ret = gnutls_record_send (priv->session, buffer, count);
- END_GNUTLS_IO (gnutls, G_IO_OUT, ret, _("Error writing data to TLS socket"), error);
-
- yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
+ END_GNUTLS_IO (gnutls, G_IO_OUT, ret, status, _("Error writing data to TLS socket"), error);
if (ret >= 0)
- return ret;
- else if (ret == GNUTLS_E_REHANDSHAKE)
- goto again;
- else
- return -1;
+ *nread = ret;
+ return status;
}
-static gssize
-g_tls_connection_gnutls_write_message (GTlsConnectionGnutls *gnutls,
- GOutputVector *vectors,
- guint num_vectors,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
+static GTlsConnectionBaseStatus
+g_tls_connection_gnutls_write_message (GTlsConnectionBase *tls,
+ GOutputVector *vectors,
+ guint num_vectors,
+ gint64 timeout,
+ gssize *nwrote,
+ GCancellable *cancellable,
+ GError **error)
{
+ GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (tls);
GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
+ GTlsConnectionBaseStatus status;
gssize ret;
guint i;
gsize total_message_size;
- again:
- if (!claim_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE,
- timeout, cancellable, error))
- return -1;
-
/* Calculate the total message size and check it’s not too big. */
for (i = 0, total_message_size = 0; i < num_vectors; i++)
total_message_size += vectors[i].size;
- if (priv->base_socket != NULL &&
+ if (g_tls_connection_base_is_dtls (tls) &&
gnutls_dtls_get_data_mtu (priv->session) < total_message_size)
{
char *message;
@@ -1638,7 +1226,7 @@ g_tls_connection_gnutls_write_message (GTlsConnectionGnutls *gnutls,
mtu);
g_free (message);
- goto done;
+ return G_TLS_CONNECTION_BASE_ERROR;
}
/* Queue up the data from all the vectors. */
@@ -1661,314 +1249,27 @@ g_tls_connection_gnutls_write_message (GTlsConnectionGnutls *gnutls,
ret = gnutls_record_uncork (priv->session, 0 /* flags */);
END_GNUTLS_IO (gnutls, G_IO_OUT, ret, _("Error writing data to TLS socket"), error);
- done:
- yield_op (gnutls, G_TLS_CONNECTION_GNUTLS_OP_WRITE);
-
- if (ret >= 0)
- return ret;
- else if (ret == GNUTLS_E_REHANDSHAKE)
- goto again;
- else
- return -1;
-}
-
-static gint
-g_tls_connection_gnutls_send_messages (GDatagramBased *datagram_based,
- GOutputMessage *messages,
- guint num_messages,
- gint flags,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
-{
- GTlsConnectionGnutls *gnutls;
- guint i;
- GError *child_error = NULL;
-
- gnutls = G_TLS_CONNECTION_GNUTLS (datagram_based);
-
- if (flags != G_SOCKET_MSG_NONE)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
- _("Send flags are not supported"));
- return -1;
- }
-
- for (i = 0; i < num_messages && child_error == NULL; i++)
- {
- GOutputMessage *message = &messages[i];
- gssize n_bytes_sent;
-
- n_bytes_sent = g_tls_connection_gnutls_write_message (gnutls,
- message->vectors,
- message->num_vectors,
- timeout,
- cancellable,
- &child_error);
-
- if (n_bytes_sent >= 0)
- {
- message->bytes_sent = n_bytes_sent;
- }
- else if (i > 0 &&
- (g_error_matches (child_error,
- G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) ||
- g_error_matches (child_error,
- G_IO_ERROR, G_IO_ERROR_TIMED_OUT)))
- {
- /* Blocked or timed out after sending some messages successfully. */
- g_clear_error (&child_error);
- break;
- }
- else
- {
- /* Error, including G_IO_ERROR_WOULD_BLOCK or G_IO_ERROR_TIMED_OUT
- * on the first message; or G_IO_ERROR_CANCELLED at any time. */
- break;
- }
- }
-
- if (child_error != NULL)
- {
- g_propagate_error (error, child_error);
- return -1;
- }
-
- return i;
-}
-
-static GInputStream *
-g_tls_connection_gnutls_get_input_stream (GIOStream *stream)
-{
- GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
- GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
-
- return priv->tls_istream;
-}
-
-static GOutputStream *
-g_tls_connection_gnutls_get_output_stream (GIOStream *stream)
-{
- GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
- GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
-
- return priv->tls_ostream;
-}
-
-gboolean
-g_tls_connection_gnutls_close_internal (GIOStream *stream,
- GTlsDirection direction,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
-{
- GTlsConnectionGnutls *gnutls = G_TLS_CONNECTION_GNUTLS (stream);
- GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (gnutls);
- GTlsConnectionGnutlsOp op;
- gboolean success = TRUE;
- int ret = 0;
- GError *gnutls_error = NULL, *stream_error = NULL;
-
- /* This can be called from g_io_stream_close(), g_input_stream_close(),
- * g_output_stream_close() or g_tls_connection_close(). In all cases, we only
- * do the gnutls_bye() for writing. The difference is how we set the flags on
- * this class and how the underlying stream is closed.
- */
-
- g_return_val_if_fail (direction != G_TLS_DIRECTION_NONE, FALSE);
-
- if (direction == G_TLS_DIRECTION_BOTH)
- op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_BOTH;
- else if (direction == G_TLS_DIRECTION_READ)
- op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_READ;
- else
- op = G_TLS_CONNECTION_GNUTLS_OP_CLOSE_WRITE;
-
- if (!claim_op (gnutls, op, timeout, cancellable, error))
- return FALSE;
-
- if (priv->ever_handshaked && !priv->write_closed &&
- direction & G_TLS_DIRECTION_WRITE)
- {
- BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
- ret = gnutls_bye (priv->session, GNUTLS_SHUT_WR);
- END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret,
- _("Error performing TLS close"), &gnutls_error);
-
- priv->write_closed = TRUE;
- }
-
- if (!priv->read_closed && direction & G_TLS_DIRECTION_READ)
- priv->read_closed = TRUE;
-
- /* Close the underlying streams. Do this even if the gnutls_bye() call failed,
- * as the parent GIOStream will have set its internal closed flag and hence
- * this implementation will never be called again. */
- if (priv->base_io_stream != NULL)
- {
- if (direction == G_TLS_DIRECTION_BOTH)
- success = g_io_stream_close (priv->base_io_stream,
- cancellable, &stream_error);
- else if (direction & G_TLS_DIRECTION_READ)
- success = g_input_stream_close (g_io_stream_get_input_stream (priv->base_io_stream),
- cancellable, &stream_error);
- else if (direction & G_TLS_DIRECTION_WRITE)
- success = g_output_stream_close (g_io_stream_get_output_stream (priv->base_io_stream),
- cancellable, &stream_error);
- }
- else if (g_tls_connection_gnutls_is_dtls (gnutls))
- {
- /* We do not close underlying #GDatagramBaseds. There is no
- * g_datagram_based_close() method since different datagram-based
- * protocols vary wildly in how they close. */
- success = TRUE;
- }
- else
- {
- g_assert_not_reached ();
- }
-
- yield_op (gnutls, op);
-
- /* Propagate errors. */
- if (ret != 0)
- {
- g_propagate_error (error, gnutls_error);
- g_clear_error (&stream_error);
- }
- else if (!success)
- {
- g_propagate_error (error, stream_error);
- g_clear_error (&gnutls_error);
- }
-
- return success && (ret == 0);
-}
-
-static gboolean
-g_tls_connection_gnutls_close (GIOStream *stream,
- GCancellable *cancellable,
- GError **error)
-{
- return g_tls_connection_gnutls_close_internal (stream,
- G_TLS_DIRECTION_BOTH,
- -1, /* blocking */
- cancellable, error);
-}
-
-static gboolean
-g_tls_connection_gnutls_dtls_shutdown (GDtlsConnection *conn,
- gboolean shutdown_read,
- gboolean shutdown_write,
- GCancellable *cancellable,
- GError **error)
-{
- GTlsDirection direction = G_TLS_DIRECTION_NONE;
-
- if (shutdown_read)
- direction |= G_TLS_DIRECTION_READ;
- if (shutdown_write)
- direction |= G_TLS_DIRECTION_WRITE;
-
- return g_tls_connection_gnutls_close_internal (G_IO_STREAM (conn),
- direction,
- -1, /* blocking */
- cancellable, error);
-}
-
-/* We do async close as synchronous-in-a-thread so we don't need to
- * implement G_IO_IN/G_IO_OUT flip-flopping just for this one case
- * (since handshakes are also done synchronously now).
- */
-static void
-close_thread (GTask *task,
- gpointer object,
- gpointer task_data,
- GCancellable *cancellable)
-{
- GIOStream *stream = object;
- GTlsDirection direction;
- GError *error = NULL;
-
- direction = GPOINTER_TO_INT (g_task_get_task_data (task));
-
- if (!g_tls_connection_gnutls_close_internal (stream, direction,
- -1, /* blocking */
- cancellable, &error))
- g_task_return_error (task, error);
- else
- g_task_return_boolean (task, TRUE);
-}
-
-static void
-g_tls_connection_gnutls_close_internal_async (GIOStream *stream,
- GTlsDirection direction,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- GTask *task;
-
- task = g_task_new (stream, cancellable, callback, user_data);
- g_task_set_source_tag (task, g_tls_connection_gnutls_close_internal_async);
- g_task_set_priority (task, io_priority);
- g_task_set_task_data (task, GINT_TO_POINTER (direction), NULL);
- g_task_run_in_thread (task, close_thread);
- g_object_unref (task);
-}
-
-static void
-g_tls_connection_gnutls_close_async (GIOStream *stream,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
-{
- g_tls_connection_gnutls_close_internal_async (stream, G_TLS_DIRECTION_BOTH,
- io_priority, cancellable,
- callback, user_data);
-}
-
-static gboolean
-g_tls_connection_gnutls_close_finish (GIOStream *stream,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (g_task_is_valid (result, stream), FALSE);
-
- return g_task_propagate_boolean (G_TASK (result), error);
+ if (ret > 0)
+ *nwrote = ret;
+ return status;
}
-static void
-g_tls_connection_gnutls_dtls_shutdown_async (GDtlsConnection *conn,
- gboolean shutdown_read,
- gboolean shutdown_write,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+static GTlsConnectionBaseStatus
+g_tls_connection_gnutls_close (GTlsConnectionBase *tls,
+ gint64 timeout,
+ GCancellable *cancellable,
+ GError **error)
{
- GTlsDirection direction = G_TLS_DIRECTION_NONE;
-
- if (shutdown_read)
- direction |= G_TLS_DIRECTION_READ;
- if (shutdown_write)
- direction |= G_TLS_DIRECTION_WRITE;
-
- g_tls_connection_gnutls_close_internal_async (G_IO_STREAM (conn), direction,
- io_priority, cancellable,
- callback, user_data);
-}
+ GTlsConnectionGnutls *tls = G_TLS_CONNECTION_GNUTLS (tls);
+ GTlsConnectionGnutlsPrivate *priv = g_tls_connection_gnutls_get_instance_private (priv);
+ GTlsConnectionBaseStatus status;
+ int ret;
-static gboolean
-g_tls_connection_gnutls_dtls_shutdown_finish (GDtlsConnection *conn,
- GAsyncResult *result,
- GError **error)
-{
- g_return_val_if_fail (g_task_is_valid (result, conn), FALSE);
+ BEGIN_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, timeout, cancellable);
+ ret = gnutls_bye (gnutls->priv->session, GNUTLS_SHUT_WR);
+ END_GNUTLS_IO (gnutls, G_IO_IN | G_IO_OUT, ret, status, _("Error performing TLS close: %s"), error);
- return g_task_propagate_boolean (G_TASK (result), error);
+ return status;
}
static void
@@ -1977,7 +1278,7 @@ g_tls_connection_gnutls_class_init (GTlsConnectionGnutlsClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GTlsConnectionBaseClass *base_class = G_TLS_CONNECTION_BASE_CLASS (klass);
- gobject_class->finalize = g_tls_connection_gnutls_finalize;
+ gobject_class->finalize = g_tls_connection_gnutls_finalize;
base_class->request_rehandshake = g_tls_connection_gnutls_request_rehandshake;
base_class->prepare_handshake = g_tls_connection_gnutls_prepare_handshake;
diff --git a/tls/gnutls/gtlsconnection-gnutls.h b/tls/gnutls/gtlsconnection-gnutls.h
index f513a74..1248a0e 100644
--- a/tls/gnutls/gtlsconnection-gnutls.h
+++ b/tls/gnutls/gtlsconnection-gnutls.h
@@ -41,11 +41,10 @@ struct _GTlsConnectionGnutlsClass
{
GTlsConnectionBaseClass parent_class;
+// FIXME: investigate this
+#if 0
void (*failed) (GTlsConnectionGnutls *gnutls);
-
- void (*begin_handshake) (GTlsConnectionGnutls *gnutls);
- void (*finish_handshake) (GTlsConnectionGnutls *gnutls,
- GError **inout_error);
+#endif
};
gnutls_certificate_credentials_t g_tls_connection_gnutls_get_credentials (GTlsConnectionGnutls *connection);
diff --git a/tls/gnutls/gtlsserverconnection-gnutls.c b/tls/gnutls/gtlsserverconnection-gnutls.c
index 2ed3476..defc7b7 100644
--- a/tls/gnutls/gtlsserverconnection-gnutls.c
+++ b/tls/gnutls/gtlsserverconnection-gnutls.c
@@ -209,10 +209,9 @@ g_tls_server_connection_gnutls_failed (GTlsConnectionGnutls *conn)
gnutls_db_remove_session (g_tls_connection_gnutls_get_session (conn));
}
-static GTlsConnectionBaseStatus
-g_tls_server_connection_gnutls_handshake (GTlsConnectionBase *tls,
- GCancellable *cancellable,
- GError **error)
+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;
@@ -235,7 +234,7 @@ g_tls_server_connection_gnutls_handshake (GTlsConnectionBase *tls,
session = g_tls_connection_gnutls_get_session (G_TLS_CONNECTION_GNUTLS (tls));
gnutls_certificate_server_set_request (session, req_mode);
- return G_TLS_CONNECTION_BASE_CLASS (g_tls_server_connection_gnutls_parent_class)->handshake (tls,
cancellable, error);
+ G_TLS_CONNECTION_BASE_CLASS (g_tls_server_connection_gnutls_parent_class)->prepare_handshake (tls,
advertised_protocols);
}
/* Session cache management */
@@ -307,7 +306,7 @@ g_tls_server_connection_gnutls_class_init (GTlsServerConnectionGnutlsClass *klas
gobject_class->get_property = g_tls_server_connection_gnutls_get_property;
gobject_class->set_property = g_tls_server_connection_gnutls_set_property;
- base_class->handshake = g_tls_server_connection_gnutls_handshake;
+ base_class->prepare_handshake = g_tls_server_connection_gnutls_prepare_handshake;
gnutls_class->failed = g_tls_server_connection_gnutls_failed;
diff --git a/tls/openssl/gtlsclientconnection-openssl.c b/tls/openssl/gtlsclientconnection-openssl.c
index 39ebcf1..7d7be05 100644
--- a/tls/openssl/gtlsclientconnection-openssl.c
+++ b/tls/openssl/gtlsclientconnection-openssl.c
@@ -234,28 +234,6 @@ g_tls_client_connection_openssl_constructed (GObject *object)
G_OBJECT_CLASS (g_tls_client_connection_openssl_parent_class)->constructed (object);
}
-static GTlsConnectionBaseStatus
-g_tls_client_connection_openssl_handshake (GTlsConnectionBase *tls,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
-{
- return G_TLS_CONNECTION_BASE_CLASS (g_tls_client_connection_openssl_parent_class)->
- handshake (tls, timeout, cancellable, error);
-}
-
-static GTlsConnectionBaseStatus
-g_tls_client_connection_openssl_complete_handshake (GTlsConnectionBase *tls,
- GError **error)
-{
- GTlsConnectionBaseStatus status;
-
- status = G_TLS_CONNECTION_BASE_CLASS (g_tls_client_connection_openssl_parent_class)->
- complete_handshake (tls, error);
-
- return status;
-}
-
static SSL *
g_tls_client_connection_openssl_get_ssl (GTlsConnectionOpenssl *connection)
{
@@ -274,9 +252,6 @@ g_tls_client_connection_openssl_class_init (GTlsClientConnectionOpensslClass *kl
gobject_class->set_property = g_tls_client_connection_openssl_set_property;
gobject_class->constructed = g_tls_client_connection_openssl_constructed;
- base_class->handshake = g_tls_client_connection_openssl_handshake;
- base_class->complete_handshake = g_tls_client_connection_openssl_complete_handshake;
-
connection_class->get_ssl = g_tls_client_connection_openssl_get_ssl;
g_object_class_override_property (gobject_class, PROP_VALIDATION_FLAGS, "validation-flags");
diff --git a/tls/openssl/gtlsconnection-openssl.c b/tls/openssl/gtlsconnection-openssl.c
index 76f8740..cbd193b 100644
--- a/tls/openssl/gtlsconnection-openssl.c
+++ b/tls/openssl/gtlsconnection-openssl.c
@@ -442,6 +442,8 @@ g_tls_connection_openssl_handshake_thread_handshake (GTlsConnectionBase *tls,
return status;
}
+// FIXME all this needs to move up to base class
+#if 0
static void
g_tls_connection_openssl_complete_handshake (GTlsConnectionBase *tls,
gchar **negotiated_protocol,
@@ -454,8 +456,6 @@ g_tls_connection_openssl_complete_handshake (GTlsConnectionBase *tls,
priv = g_tls_connection_openssl_get_instance_private (openssl);
-// FIXME
-#if 0
peer_certificate = priv->peer_certificate_tmp;
priv->peer_certificate_tmp = NULL;
peer_certificate_errors = priv->peer_certificate_errors_tmp;
@@ -476,8 +476,8 @@ g_tls_connection_openssl_complete_handshake (GTlsConnectionBase *tls,
peer_certificate_errors);
g_clear_object (&peer_certificate);
}
-#endif
}
+#endif
static void
g_tls_connection_openssl_push_io (GTlsConnectionBase *tls,
@@ -620,11 +620,10 @@ g_tls_connection_openssl_class_init (GTlsConnectionOpensslClass *klass)
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GTlsConnectionBaseClass *base_class = G_TLS_CONNECTION_BASE_CLASS (klass);
- gobject_class->finalize = g_tls_connection_openssl_finalize;
+ gobject_class->finalize = g_tls_connection_openssl_finalize;
base_class->request_rehandshake = g_tls_connection_openssl_request_rehandshake;
base_class->handshake_thread_handshake = g_tls_connection_openssl_handshake_thread_handshake;
- base_class->complete_handshake = g_tls_connection_openssl_complete_handshake;
base_class->push_io = g_tls_connection_openssl_push_io;
base_class->pop_io = g_tls_connection_openssl_pop_io;
base_class->read_fn = g_tls_connection_openssl_read;
diff --git a/tls/openssl/gtlsserverconnection-openssl.c b/tls/openssl/gtlsserverconnection-openssl.c
index c29486e..73e86f9 100644
--- a/tls/openssl/gtlsserverconnection-openssl.c
+++ b/tls/openssl/gtlsserverconnection-openssl.c
@@ -179,13 +179,12 @@ verify_callback (int preverify_ok,
return 1;
}
-static GTlsConnectionBaseStatus
-g_tls_server_connection_openssl_handshake (GTlsConnectionBase *tls,
- gint64 timeout,
- GCancellable *cancellable,
- GError **error)
+static void
+g_tls_server_connection_openssl_prepare_handshake (GTlsConnectionBase *tls,
+ gchar **advertised_protocols)
{
GTlsServerConnectionOpenssl *openssl = G_TLS_SERVER_CONNECTION_OPENSSL (tls);
+ GTlsConnectionBaseClass *base_class = G_TLS_CONNECTION_BASE_CLASS
(g_tls_server_connection_openssl_parent_class);
int req_mode = 0;
switch (openssl->authentication_mode)
@@ -205,8 +204,8 @@ g_tls_server_connection_openssl_handshake (GTlsConnectionBase *tls,
/* FIXME: is this ok? */
SSL_set_verify_depth (openssl->ssl, 0);
- return G_TLS_CONNECTION_BASE_CLASS (g_tls_server_connection_openssl_parent_class)->
- handshake (tls, timeout, cancellable, error);
+ if (base_class->prepare_handshake)
+ base_class->prepare_handshake (tls, advertised_protocols);
}
static SSL *
@@ -241,7 +240,7 @@ g_tls_server_connection_openssl_class_init (GTlsServerConnectionOpensslClass *kl
gobject_class->get_property = g_tls_server_connection_openssl_get_property;
gobject_class->set_property = g_tls_server_connection_openssl_set_property;
- base_class->handshake = g_tls_server_connection_openssl_handshake;
+ base_class->prepare_handshake = g_tls_server_connection_openssl_prepare_handshake;
connection_class->get_ssl = g_tls_server_connection_openssl_get_ssl;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]