[glib-networking/mcatanzaro/base-rebase: 20/38] gtlsconnection-base: use G_DECLARE_DERIVABLE_TYPE
- From: Michael Catanzaro <mcatanzaro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking/mcatanzaro/base-rebase: 20/38] gtlsconnection-base: use G_DECLARE_DERIVABLE_TYPE
- Date: Fri, 10 May 2019 12:19:39 +0000 (UTC)
commit 35c7745978ea31a7e765bbf8de4b70c9fcfaf076
Author: Michael Catanzaro <mcatanzaro igalia com>
Date: Fri Apr 5 17:24:40 2019 -0500
gtlsconnection-base: use G_DECLARE_DERIVABLE_TYPE
Well this was fun. It requires making the instance struct actually
private, which is probably a good thing, but requires exposing a couple
more functions for use by GTlsConnectionOpenssl and
GTlsClientConnectionOpenssl.
tls/base/gtlsconnection-base.c | 613 +++++++++++++++++++----------
tls/base/gtlsconnection-base.h | 127 ++----
tls/openssl/gtlsclientconnection-openssl.c | 10 +-
tls/openssl/gtlsconnection-openssl.c | 53 +--
tls/openssl/gtlsconnection-openssl.h | 3 -
5 files changed, 450 insertions(+), 356 deletions(-)
---
diff --git a/tls/base/gtlsconnection-base.c b/tls/base/gtlsconnection-base.c
index 12ecadf..f06c7bc 100644
--- a/tls/base/gtlsconnection-base.c
+++ b/tls/base/gtlsconnection-base.c
@@ -53,6 +53,90 @@
* • Implements GInitable for failable initialisation.
*/
+typedef struct
+{
+ /* When operating in stream mode.
+ * Mutually exclusive with base_socket.
+ */
+ GIOStream *base_io_stream;
+ GPollableInputStream *base_istream;
+ GPollableOutputStream *base_ostream;
+
+ /* When operating in stream mode; when operating in datagram mode, the
+ * GTlsConnectionBase itself is the DTLS GDatagramBased (and uses
+ * base_socket for its underlying I/O):
+ */
+ GInputStream *tls_istream;
+ GOutputStream *tls_ostream;
+
+ /* When operating in datagram mode.
+ * Mutually exclusive with base_io_stream.
+ */
+ GDatagramBased *base_socket;
+
+ GTlsDatabase *database;
+ GTlsInteraction *interaction;
+
+ GTlsCertificate *certificate;
+ gboolean certificate_requested;
+ GError *certificate_error;
+ GTlsCertificate *peer_certificate;
+ GTlsCertificateFlags peer_certificate_errors;
+
+ gboolean require_close_notify;
+ GTlsRehandshakeMode rehandshake_mode;
+
+ /* need_handshake means the next claim_op() will get diverted into
+ * an implicit handshake (unless it's an OP_HANDSHAKE or OP_CLOSE*).
+ * need_finish_handshake means the next claim_op() will get diverted
+ * into finish_handshake() (unless it's an OP_CLOSE*).
+ *
+ * handshaking is TRUE as soon as a handshake thread is queued. For
+ * a sync handshake it becomes FALSE after finish_handshake()
+ * completes in the calling thread, but for an async implicit
+ * handshake, it becomes FALSE (and need_finish_handshake becomes
+ * TRUE) at the end of the handshaking thread (and then the next
+ * non-close op will call finish_handshake()). We can't just wait
+ * for handshake_thread_completed() to run, because it's possible
+ * that its main loop is being blocked by a synchronous op which is
+ * waiting for handshaking to become FALSE...
+ *
+ * started_handshake indicates that the current handshake attempt
+ * got at least as far as sending the first handshake packet (and so
+ * any error should be copied to handshake_error and returned on all
+ * future operations). ever_handshaked indicates that TLS has been
+ * successfully negotiated at some point.
+ */
+ gboolean need_handshake;
+ gboolean need_finish_handshake;
+ gboolean started_handshake;
+ gboolean handshaking;
+ gboolean ever_handshaked;
+ GTask *implicit_handshake;
+ GError *handshake_error;
+ GByteArray *app_data_buf;
+
+ /* read_closed means the read direction has closed; write_closed similarly.
+ * If (and only if) both are set, the entire GTlsConnection is closed. */
+ gboolean read_closing, read_closed;
+ gboolean write_closing, write_closed;
+
+ gboolean reading;
+ gint64 read_timeout;
+ GError *read_error;
+ GCancellable *read_cancellable;
+
+ gboolean writing;
+ gint64 write_timeout;
+ GError *write_error;
+ GCancellable *write_cancellable;
+
+ gboolean is_system_certdb;
+ gboolean database_is_unset;
+
+ GMutex op_mutex;
+ GCancellable *waiting_for_op;
+} GTlsConnectionBasePrivate;
static void g_tls_connection_base_dtls_connection_iface_init (GDtlsConnectionInterface *iface);
@@ -67,6 +151,7 @@ static gboolean finish_handshake (GTlsConnectionBase *tls,
GError **error);
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GTlsConnectionBase, g_tls_connection_base, G_TYPE_TLS_CONNECTION,
+ G_ADD_PRIVATE (GTlsConnectionBase);
G_IMPLEMENT_INTERFACE (G_TYPE_DATAGRAM_BASED,
g_tls_connection_base_datagram_based_iface_init);
G_IMPLEMENT_INTERFACE (G_TYPE_DTLS_CONNECTION,
@@ -94,54 +179,59 @@ enum
static gboolean
g_tls_connection_base_is_dtls (GTlsConnectionBase *tls)
{
- return tls->base_socket != NULL;
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
+ return priv->base_socket != NULL;
}
static void
g_tls_connection_base_init (GTlsConnectionBase *tls)
{
- tls->need_handshake = TRUE;
- tls->database_is_unset = TRUE;
- tls->is_system_certdb = TRUE;
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
+ priv->need_handshake = TRUE;
+ priv->database_is_unset = TRUE;
+ priv->is_system_certdb = TRUE;
- g_mutex_init (&tls->op_mutex);
- tls->waiting_for_op = g_cancellable_new ();
- g_cancellable_cancel (tls->waiting_for_op);
+ g_mutex_init (&priv->op_mutex);
+ priv->waiting_for_op = g_cancellable_new ();
+ g_cancellable_cancel (priv->waiting_for_op);
}
static void
g_tls_connection_base_finalize (GObject *object)
{
GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (object);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
- g_clear_object (&tls->base_io_stream);
- g_clear_object (&tls->base_socket);
+ g_clear_object (&priv->base_io_stream);
+ g_clear_object (&priv->base_socket);
- g_clear_object (&tls->tls_istream);
- g_clear_object (&tls->tls_ostream);
+ g_clear_object (&priv->tls_istream);
+ g_clear_object (&priv->tls_ostream);
- g_clear_object (&tls->database);
- g_clear_object (&tls->certificate);
- g_clear_error (&tls->certificate_error);
- g_clear_object (&tls->peer_certificate);
+ g_clear_object (&priv->database);
+ g_clear_object (&priv->certificate);
+ g_clear_error (&priv->certificate_error);
+ g_clear_object (&priv->peer_certificate);
- g_clear_object (&tls->interaction);
+ g_clear_object (&priv->interaction);
/* 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. */
- g_clear_object (&tls->implicit_handshake);
+ g_clear_object (&priv->implicit_handshake);
- g_clear_error (&tls->handshake_error);
- g_clear_error (&tls->read_error);
- g_clear_error (&tls->write_error);
- g_clear_object (&tls->read_cancellable);
- g_clear_object (&tls->write_cancellable);
+ g_clear_error (&priv->handshake_error);
+ g_clear_error (&priv->read_error);
+ g_clear_error (&priv->write_error);
+ g_clear_object (&priv->read_cancellable);
+ g_clear_object (&priv->write_cancellable);
- g_clear_object (&tls->waiting_for_op);
- g_mutex_clear (&tls->op_mutex);
+ g_clear_object (&priv->waiting_for_op);
+ g_mutex_clear (&priv->op_mutex);
- g_clear_pointer (&tls->app_data_buf, g_byte_array_unref);
+ g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
G_OBJECT_CLASS (g_tls_connection_base_parent_class)->finalize (object);
}
@@ -153,54 +243,55 @@ g_tls_connection_base_get_property (GObject *object,
GParamSpec *pspec)
{
GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (object);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
GTlsBackend *backend;
switch (prop_id)
{
case PROP_BASE_IO_STREAM:
- g_value_set_object (value, tls->base_io_stream);
+ g_value_set_object (value, priv->base_io_stream);
break;
case PROP_BASE_SOCKET:
- g_value_set_object (value, tls->base_socket);
+ g_value_set_object (value, priv->base_socket);
break;
case PROP_REQUIRE_CLOSE_NOTIFY:
- g_value_set_boolean (value, tls->require_close_notify);
+ g_value_set_boolean (value, priv->require_close_notify);
break;
case PROP_REHANDSHAKE_MODE:
- g_value_set_enum (value, tls->rehandshake_mode);
+ g_value_set_enum (value, priv->rehandshake_mode);
break;
case PROP_USE_SYSTEM_CERTDB:
- g_value_set_boolean (value, tls->is_system_certdb);
+ g_value_set_boolean (value, priv->is_system_certdb);
break;
case PROP_DATABASE:
- if (tls->database_is_unset)
+ if (priv->database_is_unset)
{
backend = g_tls_backend_get_default ();
- tls->database = g_tls_backend_get_default_database (backend);
- tls->database_is_unset = FALSE;
+ priv->database = g_tls_backend_get_default_database (backend);
+ priv->database_is_unset = FALSE;
}
- g_value_set_object (value, tls->database);
+ g_value_set_object (value, priv->database);
break;
case PROP_CERTIFICATE:
- g_value_set_object (value, tls->certificate);
+ g_value_set_object (value, priv->certificate);
break;
case PROP_INTERACTION:
- g_value_set_object (value, tls->interaction);
+ g_value_set_object (value, priv->interaction);
break;
case PROP_PEER_CERTIFICATE:
- g_value_set_object (value, tls->peer_certificate);
+ g_value_set_object (value, priv->peer_certificate);
break;
case PROP_PEER_CERTIFICATE_ERRORS:
- g_value_set_flags (value, tls->peer_certificate_errors);
+ g_value_set_flags (value, priv->peer_certificate_errors);
break;
default:
@@ -215,6 +306,7 @@ g_tls_connection_base_set_property (GObject *object,
GParamSpec *pspec)
{
GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (object);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
GInputStream *istream;
GOutputStream *ostream;
gboolean system_certdb;
@@ -224,82 +316,82 @@ g_tls_connection_base_set_property (GObject *object,
{
case PROP_BASE_IO_STREAM:
g_assert (g_value_get_object (value) == NULL ||
- tls->base_socket == NULL);
+ priv->base_socket == NULL);
- if (tls->base_io_stream)
+ if (priv->base_io_stream)
{
- g_object_unref (tls->base_io_stream);
- tls->base_istream = NULL;
- tls->base_ostream = NULL;
+ g_object_unref (priv->base_io_stream);
+ priv->base_istream = NULL;
+ priv->base_ostream = NULL;
}
- tls->base_io_stream = g_value_dup_object (value);
- if (!tls->base_io_stream)
+ priv->base_io_stream = g_value_dup_object (value);
+ if (!priv->base_io_stream)
return;
- istream = g_io_stream_get_input_stream (tls->base_io_stream);
- ostream = g_io_stream_get_output_stream (tls->base_io_stream);
+ istream = g_io_stream_get_input_stream (priv->base_io_stream);
+ ostream = g_io_stream_get_output_stream (priv->base_io_stream);
if (G_IS_POLLABLE_INPUT_STREAM (istream) &&
g_pollable_input_stream_can_poll (G_POLLABLE_INPUT_STREAM (istream)))
{
- tls->base_istream = G_POLLABLE_INPUT_STREAM (istream);
- tls->tls_istream = g_tls_input_stream_new (tls);
+ priv->base_istream = G_POLLABLE_INPUT_STREAM (istream);
+ priv->tls_istream = g_tls_input_stream_new (tls);
}
if (G_IS_POLLABLE_OUTPUT_STREAM (ostream) &&
g_pollable_output_stream_can_poll (G_POLLABLE_OUTPUT_STREAM (ostream)))
{
- tls->base_ostream = G_POLLABLE_OUTPUT_STREAM (ostream);
- tls->tls_ostream = g_tls_output_stream_new (tls);
+ priv->base_ostream = G_POLLABLE_OUTPUT_STREAM (ostream);
+ priv->tls_ostream = g_tls_output_stream_new (tls);
}
break;
case PROP_BASE_SOCKET:
g_assert (g_value_get_object (value) == NULL ||
- tls->base_io_stream == NULL);
+ priv->base_io_stream == NULL);
- g_clear_object (&tls->base_socket);
- tls->base_socket = g_value_dup_object (value);
+ g_clear_object (&priv->base_socket);
+ priv->base_socket = g_value_dup_object (value);
break;
case PROP_REQUIRE_CLOSE_NOTIFY:
- tls->require_close_notify = g_value_get_boolean (value);
+ priv->require_close_notify = g_value_get_boolean (value);
break;
case PROP_REHANDSHAKE_MODE:
- tls->rehandshake_mode = g_value_get_enum (value);
+ priv->rehandshake_mode = g_value_get_enum (value);
break;
case PROP_USE_SYSTEM_CERTDB:
system_certdb = g_value_get_boolean (value);
- if (system_certdb != tls->is_system_certdb)
+ if (system_certdb != priv->is_system_certdb)
{
- g_clear_object (&tls->database);
+ g_clear_object (&priv->database);
if (system_certdb)
{
backend = g_tls_backend_get_default ();
- tls->database = g_tls_backend_get_default_database (backend);
+ priv->database = g_tls_backend_get_default_database (backend);
}
- tls->is_system_certdb = system_certdb;
- tls->database_is_unset = FALSE;
+ priv->is_system_certdb = system_certdb;
+ priv->database_is_unset = FALSE;
}
break;
case PROP_DATABASE:
- g_clear_object (&tls->database);
- tls->database = g_value_dup_object (value);
- tls->is_system_certdb = FALSE;
- tls->database_is_unset = FALSE;
+ g_clear_object (&priv->database);
+ priv->database = g_value_dup_object (value);
+ priv->is_system_certdb = FALSE;
+ priv->database_is_unset = FALSE;
break;
case PROP_CERTIFICATE:
- if (tls->certificate)
- g_object_unref (tls->certificate);
- tls->certificate = g_value_dup_object (value);
+ if (priv->certificate)
+ g_object_unref (priv->certificate);
+ priv->certificate = g_value_dup_object (value);
break;
case PROP_INTERACTION:
- g_clear_object (&tls->interaction);
- tls->interaction = g_value_dup_object (value);
+ g_clear_object (&priv->interaction);
+ priv->interaction = g_value_dup_object (value);
break;
default:
@@ -323,33 +415,35 @@ claim_op (GTlsConnectionBase *tls,
GCancellable *cancellable,
GError **error)
{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
try_again:
if (g_cancellable_set_error_if_cancelled (cancellable, error))
return FALSE;
- g_mutex_lock (&tls->op_mutex);
+ g_mutex_lock (&priv->op_mutex);
if (((op == G_TLS_CONNECTION_BASE_OP_HANDSHAKE ||
op == G_TLS_CONNECTION_BASE_OP_READ) &&
- (tls->read_closing || tls->read_closed)) ||
+ (priv->read_closing || priv->read_closed)) ||
((op == G_TLS_CONNECTION_BASE_OP_HANDSHAKE ||
op == G_TLS_CONNECTION_BASE_OP_WRITE) &&
- (tls->write_closing || tls->write_closed)))
+ (priv->write_closing || priv->write_closed)))
{
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_CLOSED,
_("Connection is closed"));
- g_mutex_unlock (&tls->op_mutex);
+ g_mutex_unlock (&priv->op_mutex);
return FALSE;
}
- if (tls->handshake_error &&
+ if (priv->handshake_error &&
op != G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH &&
op != G_TLS_CONNECTION_BASE_OP_CLOSE_READ &&
op != G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE)
{
if (error)
- *error = g_error_copy (tls->handshake_error);
- g_mutex_unlock (&tls->op_mutex);
+ *error = g_error_copy (priv->handshake_error);
+ g_mutex_unlock (&priv->op_mutex);
return FALSE;
}
@@ -358,29 +452,29 @@ claim_op (GTlsConnectionBase *tls,
if (op != G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH &&
op != G_TLS_CONNECTION_BASE_OP_CLOSE_READ &&
op != G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE &&
- tls->need_handshake && !tls->handshaking)
+ priv->need_handshake && !priv->handshaking)
{
- tls->handshaking = TRUE;
+ priv->handshaking = TRUE;
if (!do_implicit_handshake (tls, timeout, cancellable, error))
{
- g_cancellable_reset (tls->waiting_for_op);
- g_mutex_unlock (&tls->op_mutex);
+ g_cancellable_reset (priv->waiting_for_op);
+ g_mutex_unlock (&priv->op_mutex);
return FALSE;
}
}
- if (tls->need_finish_handshake &&
- tls->implicit_handshake)
+ if (priv->need_finish_handshake &&
+ priv->implicit_handshake)
{
GError *my_error = NULL;
gboolean success;
- tls->need_finish_handshake = FALSE;
+ priv->need_finish_handshake = FALSE;
- g_mutex_unlock (&tls->op_mutex);
- success = finish_handshake (tls, tls->implicit_handshake, &my_error);
- g_clear_object (&tls->implicit_handshake);
- g_mutex_lock (&tls->op_mutex);
+ g_mutex_unlock (&priv->op_mutex);
+ success = finish_handshake (tls, priv->implicit_handshake, &my_error);
+ g_clear_object (&priv->implicit_handshake);
+ g_mutex_lock (&priv->op_mutex);
if (op != G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH &&
op != G_TLS_CONNECTION_BASE_OP_CLOSE_READ &&
@@ -388,7 +482,7 @@ claim_op (GTlsConnectionBase *tls,
(!success || g_cancellable_set_error_if_cancelled (cancellable, &my_error)))
{
g_propagate_error (error, my_error);
- g_mutex_unlock (&tls->op_mutex);
+ g_mutex_unlock (&priv->op_mutex);
return FALSE;
}
@@ -396,18 +490,18 @@ claim_op (GTlsConnectionBase *tls,
}
}
- if ((op != G_TLS_CONNECTION_BASE_OP_WRITE && tls->reading) ||
- (op != G_TLS_CONNECTION_BASE_OP_READ && tls->writing) ||
- (op != G_TLS_CONNECTION_BASE_OP_HANDSHAKE && tls->handshaking))
+ if ((op != G_TLS_CONNECTION_BASE_OP_WRITE && priv->reading) ||
+ (op != G_TLS_CONNECTION_BASE_OP_READ && priv->writing) ||
+ (op != G_TLS_CONNECTION_BASE_OP_HANDSHAKE && priv->handshaking))
{
GPollFD fds[2];
int nfds;
gint64 start_time;
gint result = 1; /* if the loop is never entered, it's as if we cancelled early */
- g_cancellable_reset (tls->waiting_for_op);
+ g_cancellable_reset (priv->waiting_for_op);
- g_mutex_unlock (&tls->op_mutex);
+ g_mutex_unlock (&priv->op_mutex);
if (timeout == 0)
{
@@ -416,7 +510,7 @@ claim_op (GTlsConnectionBase *tls,
return FALSE;
}
- g_cancellable_make_pollfd (tls->waiting_for_op, &fds[0]);
+ g_cancellable_make_pollfd (priv->waiting_for_op, &fds[0]);
if (g_cancellable_make_pollfd (cancellable, &fds[1]))
nfds = 2;
else
@@ -429,7 +523,7 @@ claim_op (GTlsConnectionBase *tls,
/* Poll until cancellation or the timeout is reached. */
start_time = g_get_monotonic_time ();
- while (!g_cancellable_is_cancelled (tls->waiting_for_op) &&
+ while (!g_cancellable_is_cancelled (priv->waiting_for_op) &&
!g_cancellable_is_cancelled (cancellable))
{
result = g_poll (fds, nfds, timeout);
@@ -461,20 +555,20 @@ claim_op (GTlsConnectionBase *tls,
}
if (op == G_TLS_CONNECTION_BASE_OP_HANDSHAKE)
- tls->handshaking = TRUE;
+ priv->handshaking = TRUE;
if (op == G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH ||
op == G_TLS_CONNECTION_BASE_OP_CLOSE_READ)
- tls->read_closing = TRUE;
+ priv->read_closing = TRUE;
if (op == G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH ||
op == G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE)
- tls->write_closing = TRUE;
+ priv->write_closing = TRUE;
if (op != G_TLS_CONNECTION_BASE_OP_WRITE)
- tls->reading = TRUE;
+ priv->reading = TRUE;
if (op != G_TLS_CONNECTION_BASE_OP_READ)
- tls->writing = TRUE;
+ priv->writing = TRUE;
- g_mutex_unlock (&tls->op_mutex);
+ g_mutex_unlock (&priv->op_mutex);
return TRUE;
}
@@ -483,27 +577,29 @@ yield_op (GTlsConnectionBase *tls,
GTlsConnectionBaseOp op,
GTlsConnectionBaseStatus status)
{
- g_mutex_lock (&tls->op_mutex);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
+ g_mutex_lock (&priv->op_mutex);
if (op == G_TLS_CONNECTION_BASE_OP_HANDSHAKE)
- tls->handshaking = FALSE;
- else if (status == G_TLS_CONNECTION_BASE_REHANDSHAKE && !tls->handshaking)
- tls->need_handshake = TRUE;
+ priv->handshaking = FALSE;
+ else if (status == G_TLS_CONNECTION_BASE_REHANDSHAKE && !priv->handshaking)
+ priv->need_handshake = TRUE;
if (op == G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH ||
op == G_TLS_CONNECTION_BASE_OP_CLOSE_READ)
- tls->read_closing = FALSE;
+ priv->read_closing = FALSE;
if (op == G_TLS_CONNECTION_BASE_OP_CLOSE_BOTH ||
op == G_TLS_CONNECTION_BASE_OP_CLOSE_WRITE)
- tls->write_closing = FALSE;
+ priv->write_closing = FALSE;
if (op != G_TLS_CONNECTION_BASE_OP_WRITE)
- tls->reading = FALSE;
+ priv->reading = FALSE;
if (op != G_TLS_CONNECTION_BASE_OP_READ)
- tls->writing = FALSE;
+ priv->writing = FALSE;
- g_cancellable_cancel (tls->waiting_for_op);
- g_mutex_unlock (&tls->op_mutex);
+ g_cancellable_cancel (priv->waiting_for_op);
+ g_mutex_unlock (&priv->op_mutex);
}
static void
@@ -512,18 +608,20 @@ g_tls_connection_base_real_push_io (GTlsConnectionBase *tls,
gint64 timeout,
GCancellable *cancellable)
{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
if (direction & G_IO_IN)
{
- tls->read_timeout = timeout;;
- tls->read_cancellable = cancellable;
- g_clear_error (&tls->read_error);
+ priv->read_timeout = timeout;;
+ priv->read_cancellable = cancellable;
+ g_clear_error (&priv->read_error);
}
if (direction & G_IO_OUT)
{
- tls->write_timeout = timeout;
- tls->write_cancellable = cancellable;
- g_clear_error (&tls->write_error);
+ priv->write_timeout = timeout;
+ priv->write_cancellable = cancellable;
+ g_clear_error (&priv->write_error);
}
}
@@ -546,29 +644,30 @@ g_tls_connection_base_real_pop_io (GTlsConnectionBase *tls,
gboolean success,
GError **error)
{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
GError *my_error = NULL;
if (direction & G_IO_IN)
{
- tls->read_cancellable = NULL;
+ priv->read_cancellable = NULL;
if (!success)
{
- my_error = tls->read_error;
- tls->read_error = NULL;
+ my_error = priv->read_error;
+ priv->read_error = NULL;
}
else
- g_clear_error (&tls->read_error);
+ g_clear_error (&priv->read_error);
}
if (direction & G_IO_OUT)
{
- tls->write_cancellable = NULL;
+ priv->write_cancellable = NULL;
if (!success && !my_error)
{
- my_error = tls->write_error;
- tls->write_error = NULL;
+ my_error = priv->write_error;
+ priv->write_error = NULL;
}
else
- g_clear_error (&tls->write_error);
+ g_clear_error (&priv->write_error);
}
if (success)
@@ -610,14 +709,16 @@ static gboolean
g_tls_connection_base_base_check (GTlsConnectionBase *tls,
GIOCondition condition)
{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
if (g_tls_connection_base_is_dtls (tls))
- return g_datagram_based_condition_check (tls->base_socket, condition);
+ return g_datagram_based_condition_check (priv->base_socket, condition);
if (condition & G_IO_IN)
- return g_pollable_input_stream_is_readable (tls->base_istream);
+ return g_pollable_input_stream_is_readable (priv->base_istream);
if (condition & G_IO_OUT)
- return g_pollable_output_stream_is_writable (tls->base_ostream);
+ return g_pollable_output_stream_is_writable (priv->base_ostream);
g_assert_not_reached ();
}
@@ -628,18 +729,20 @@ gboolean
g_tls_connection_base_check (GTlsConnectionBase *tls,
GIOCondition condition)
{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
/* Racy, but worst case is that we just get WOULD_BLOCK back */
- if (tls->need_finish_handshake)
+ if (priv->need_finish_handshake)
return TRUE;
/* If a handshake or close is in progress, then tls_istream and
* tls_ostream are blocked, regardless of the base stream status.
*/
- if (tls->handshaking)
+ if (priv->handshaking)
return FALSE;
- if (((condition & G_IO_IN) && tls->read_closing) ||
- ((condition & G_IO_OUT) && tls->write_closing))
+ if (((condition & G_IO_IN) && priv->read_closing) ||
+ ((condition & G_IO_OUT) && priv->write_closing))
return FALSE;
/* Defer to the base stream or GDatagramBased. */
@@ -690,26 +793,27 @@ static void
tls_source_sync (GTlsConnectionBaseSource *tls_source)
{
GTlsConnectionBase *tls = tls_source->tls;
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
gboolean io_waiting, op_waiting;
/* Was the source destroyed earlier in this main context iteration? */
if (g_source_is_destroyed ((GSource *) tls_source))
return;
- g_mutex_lock (&tls->op_mutex);
- if (((tls_source->condition & G_IO_IN) && tls->reading) ||
- ((tls_source->condition & G_IO_OUT) && tls->writing) ||
- (tls->handshaking && !tls->need_finish_handshake))
+ g_mutex_lock (&priv->op_mutex);
+ if (((tls_source->condition & G_IO_IN) && priv->reading) ||
+ ((tls_source->condition & G_IO_OUT) && priv->writing) ||
+ (priv->handshaking && !priv->need_finish_handshake))
op_waiting = TRUE;
else
op_waiting = FALSE;
- if (!op_waiting && !tls->need_handshake &&
- !tls->need_finish_handshake)
+ if (!op_waiting && !priv->need_handshake &&
+ !priv->need_finish_handshake)
io_waiting = TRUE;
else
io_waiting = FALSE;
- g_mutex_unlock (&tls->op_mutex);
+ g_mutex_unlock (&priv->op_mutex);
if (op_waiting == tls_source->op_waiting &&
io_waiting == tls_source->io_waiting)
@@ -725,13 +829,13 @@ tls_source_sync (GTlsConnectionBaseSource *tls_source)
}
if (op_waiting)
- tls_source->child_source = g_cancellable_source_new (tls->waiting_for_op);
+ tls_source->child_source = g_cancellable_source_new (priv->waiting_for_op);
else if (io_waiting && G_IS_DATAGRAM_BASED (tls_source->base))
- tls_source->child_source = g_datagram_based_create_source (tls->base_socket, tls_source->condition,
NULL);
+ tls_source->child_source = g_datagram_based_create_source (priv->base_socket, tls_source->condition,
NULL);
else if (io_waiting && G_IS_POLLABLE_INPUT_STREAM (tls_source->base))
- tls_source->child_source = g_pollable_input_stream_create_source (tls->base_istream, NULL);
+ tls_source->child_source = g_pollable_input_stream_create_source (priv->base_istream, NULL);
else if (io_waiting && G_IS_POLLABLE_OUTPUT_STREAM (tls_source->base))
- tls_source->child_source = g_pollable_output_stream_create_source (tls->base_ostream, NULL);
+ tls_source->child_source = g_pollable_output_stream_create_source (priv->base_ostream, NULL);
else
tls_source->child_source = g_timeout_source_new (0);
@@ -848,6 +952,7 @@ g_tls_connection_base_create_source (GTlsConnectionBase *tls,
GIOCondition condition,
GCancellable *cancellable)
{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
GSource *source, *cancellable_source;
GTlsConnectionBaseSource *tls_source;
@@ -869,10 +974,10 @@ g_tls_connection_base_create_source (GTlsConnectionBase *tls,
tls_source->condition = condition;
if (g_tls_connection_base_is_dtls (tls))
tls_source->base = G_OBJECT (tls);
- else if (tls->tls_istream != NULL && condition & G_IO_IN)
- tls_source->base = G_OBJECT (tls->tls_istream);
- else if (tls->tls_ostream != NULL && condition & G_IO_OUT)
- tls_source->base = G_OBJECT (tls->tls_ostream);
+ else if (priv->tls_istream != NULL && condition & G_IO_IN)
+ tls_source->base = G_OBJECT (priv->tls_istream);
+ else if (priv->tls_ostream != NULL && condition & G_IO_OUT)
+ tls_source->base = G_OBJECT (priv->tls_ostream);
else
g_assert_not_reached ();
@@ -918,6 +1023,7 @@ g_tls_connection_base_condition_wait (GDatagramBased *datagram_based,
GError **error)
{
GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (datagram_based);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
GPollFD fds[2];
guint n_fds;
gint result = 1; /* if the loop is never entered, it's as if we cancelled early */
@@ -932,7 +1038,7 @@ g_tls_connection_base_condition_wait (GDatagramBased *datagram_based,
start_time = g_get_monotonic_time ();
- g_cancellable_make_pollfd (tls->waiting_for_op, &fds[0]);
+ g_cancellable_make_pollfd (priv->waiting_for_op, &fds[0]);
n_fds = 1;
if (g_cancellable_make_pollfd (cancellable, &fds[1]))
@@ -1005,9 +1111,11 @@ g_tls_connection_base_set_peer_certificate (GTlsConnectionBase *tls,
GTlsCertificate *peer_certificate,
GTlsCertificateFlags peer_certificate_errors)
{
- g_set_object (&tls->peer_certificate, peer_certificate);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
+ g_set_object (&priv->peer_certificate, peer_certificate);
- tls->peer_certificate_errors = peer_certificate_errors;
+ priv->peer_certificate_errors = peer_certificate_errors;
g_object_notify (G_OBJECT (tls), "peer-certificate");
g_object_notify (G_OBJECT (tls), "peer-certificate-errors");
@@ -1020,6 +1128,7 @@ handshake_thread (GTask *task,
GCancellable *cancellable)
{
GTlsConnectionBase *tls = object;
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
GTlsConnectionBaseClass *tls_class = G_TLS_CONNECTION_BASE_GET_CLASS (tls);
GError *error = NULL;
gint64 timeout;
@@ -1028,8 +1137,8 @@ handshake_thread (GTask *task,
g_assert (task_data != NULL);
timeout = *((gint64 *)task_data);
- tls->started_handshake = FALSE;
- tls->certificate_requested = FALSE;
+ priv->started_handshake = FALSE;
+ priv->certificate_requested = FALSE;
if (!claim_op (tls, G_TLS_CONNECTION_BASE_OP_HANDSHAKE,
timeout, cancellable, &error))
@@ -1038,9 +1147,9 @@ handshake_thread (GTask *task,
return;
}
- g_clear_error (&tls->handshake_error);
+ g_clear_error (&priv->handshake_error);
- if (tls->ever_handshaked && !tls->need_handshake)
+ if (priv->ever_handshaked && !priv->need_handshake)
{
GTlsConnectionBaseStatus status;
@@ -1052,25 +1161,25 @@ handshake_thread (GTask *task,
}
}
- g_clear_object (&tls->peer_certificate);
- tls->peer_certificate_errors = 0;
+ g_clear_object (&priv->peer_certificate);
+ priv->peer_certificate_errors = 0;
- tls->started_handshake = TRUE;
+ priv->started_handshake = TRUE;
tls_class->handshake (tls, timeout, cancellable, &error);
- tls->need_handshake = FALSE;
+ priv->need_handshake = FALSE;
if (error)
{
if ((g_error_matches (error, G_IO_ERROR, G_IO_ERROR_FAILED) ||
g_error_matches (error, G_IO_ERROR, G_IO_ERROR_BROKEN_PIPE) ||
g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS)) &&
- tls->certificate_requested)
+ priv->certificate_requested)
{
g_clear_error (&error);
- if (tls->certificate_error)
+ if (priv->certificate_error)
{
- error = tls->certificate_error;
- tls->certificate_error = NULL;
+ error = priv->certificate_error;
+ priv->certificate_error = NULL;
}
else
{
@@ -1082,7 +1191,7 @@ handshake_thread (GTask *task,
}
else
{
- tls->ever_handshaked = TRUE;
+ priv->ever_handshaked = TRUE;
g_task_return_boolean (task, TRUE);
}
}
@@ -1093,13 +1202,14 @@ finish_handshake (GTlsConnectionBase *tls,
GError **error)
{
GTlsConnectionBaseClass *tls_class = G_TLS_CONNECTION_BASE_GET_CLASS (tls);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
GError *my_error = NULL;
if (g_task_propagate_boolean (task, &my_error))
tls_class->complete_handshake (tls, &my_error);
- if (my_error && tls->started_handshake)
- tls->handshake_error = g_error_copy (my_error);
+ if (my_error && priv->started_handshake)
+ priv->handshake_error = g_error_copy (my_error);
if (!my_error)
return TRUE;
@@ -1160,18 +1270,19 @@ handshake_thread_completed (GObject *object,
{
GTask *caller_task = user_data;
GTlsConnectionBase *tls = g_task_get_source_object (caller_task);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
GError *error = NULL;
gboolean need_finish_handshake, success;
- g_mutex_lock (&tls->op_mutex);
- if (tls->need_finish_handshake)
+ g_mutex_lock (&priv->op_mutex);
+ if (priv->need_finish_handshake)
{
need_finish_handshake = TRUE;
- tls->need_finish_handshake = FALSE;
+ priv->need_finish_handshake = FALSE;
}
else
need_finish_handshake = FALSE;
- g_mutex_unlock (&tls->op_mutex);
+ g_mutex_unlock (&priv->op_mutex);
if (need_finish_handshake)
{
@@ -1181,8 +1292,8 @@ handshake_thread_completed (GObject *object,
else
g_task_return_error (caller_task, error);
}
- else if (tls->handshake_error)
- g_task_return_error (caller_task, g_error_copy (tls->handshake_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);
@@ -1196,17 +1307,18 @@ async_handshake_thread (GTask *task,
GCancellable *cancellable)
{
GTlsConnectionBase *tls = object;
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
handshake_thread (task, object, task_data, cancellable);
- g_mutex_lock (&tls->op_mutex);
- tls->need_finish_handshake = TRUE;
+ 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.
*/
- tls->handshaking = FALSE;
- g_mutex_unlock (&tls->op_mutex);
+ priv->handshaking = FALSE;
+ g_mutex_unlock (&priv->op_mutex);
yield_op (tls, G_TLS_CONNECTION_BASE_OP_HANDSHAKE,
G_TLS_CONNECTION_BASE_OK);
@@ -1273,10 +1385,11 @@ implicit_handshake_completed (GObject *object,
gpointer user_data)
{
GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (object);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
- g_mutex_lock (&tls->op_mutex);
- tls->need_finish_handshake = TRUE;
- g_mutex_unlock (&tls->op_mutex);
+ 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);
@@ -1288,18 +1401,19 @@ do_implicit_handshake (GTlsConnectionBase *tls,
GCancellable *cancellable,
GError **error)
{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
gint64 *thread_timeout = NULL;
/* We have op_mutex */
- g_assert (tls->implicit_handshake == NULL);
- tls->implicit_handshake = g_task_new (tls, cancellable,
+ g_assert (priv->implicit_handshake == NULL);
+ priv->implicit_handshake = g_task_new (tls, cancellable,
implicit_handshake_completed,
NULL);
- g_task_set_source_tag (tls->implicit_handshake, do_implicit_handshake);
+ g_task_set_source_tag (priv->implicit_handshake, do_implicit_handshake);
thread_timeout = g_new0 (gint64, 1);
- g_task_set_task_data (tls->implicit_handshake,
+ g_task_set_task_data (priv->implicit_handshake,
thread_timeout, g_free);
if (timeout != 0)
@@ -1314,16 +1428,16 @@ do_implicit_handshake (GTlsConnectionBase *tls,
* operation is complete or errors. */
*thread_timeout = timeout;
- g_mutex_unlock (&tls->op_mutex);
- g_task_run_in_thread_sync (tls->implicit_handshake,
+ g_mutex_unlock (&priv->op_mutex);
+ g_task_run_in_thread_sync (priv->implicit_handshake,
handshake_thread);
success = finish_handshake (tls,
- tls->implicit_handshake,
+ priv->implicit_handshake,
&my_error);
- g_clear_object (&tls->implicit_handshake);
+ g_clear_object (&priv->implicit_handshake);
yield_op (tls, G_TLS_CONNECTION_BASE_OP_HANDSHAKE,
G_TLS_CONNECTION_BASE_OK);
- g_mutex_lock (&tls->op_mutex);
+ g_mutex_lock (&priv->op_mutex);
if (my_error)
g_propagate_error (error, my_error);
@@ -1337,7 +1451,7 @@ do_implicit_handshake (GTlsConnectionBase *tls,
* about. Run the actual operation as blocking in its thread. */
*thread_timeout = -1; /* blocking */
- g_task_run_in_thread (tls->implicit_handshake,
+ g_task_run_in_thread (priv->implicit_handshake,
handshake_thread);
g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK,
@@ -1354,6 +1468,7 @@ g_tls_connection_base_read (GTlsConnectionBase *tls,
GCancellable *cancellable,
GError **error)
{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
GTlsConnectionBaseStatus status;
gssize nread;
@@ -1363,14 +1478,14 @@ g_tls_connection_base_read (GTlsConnectionBase *tls,
timeout, cancellable, error))
return -1;
- if (tls->app_data_buf && !tls->handshaking)
+ if (priv->app_data_buf && !priv->handshaking)
{
- nread = MIN (count, tls->app_data_buf->len);
- memcpy (buffer, tls->app_data_buf->data, nread);
- if (nread == tls->app_data_buf->len)
- g_clear_pointer (&tls->app_data_buf, g_byte_array_unref);
+ nread = MIN (count, priv->app_data_buf->len);
+ memcpy (buffer, priv->app_data_buf->data, nread);
+ if (nread == priv->app_data_buf->len)
+ g_clear_pointer (&priv->app_data_buf, g_byte_array_unref);
else
- g_byte_array_remove_range (tls->app_data_buf, 0, nread);
+ g_byte_array_remove_range (priv->app_data_buf, 0, nread);
status = G_TLS_CONNECTION_BASE_OK;
}
else
@@ -1397,6 +1512,7 @@ g_tls_connection_base_read_message (GTlsConnectionBase *tls,
GCancellable *cancellable,
GError **error)
{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
GTlsConnectionBaseStatus status;
gssize nread;
@@ -1406,7 +1522,7 @@ g_tls_connection_base_read_message (GTlsConnectionBase *tls,
return -1;
/* Copy data out of the app data buffer first. */
- if (tls->app_data_buf && !tls->handshaking)
+ if (priv->app_data_buf && !priv->handshaking)
{
nread = 0;
@@ -1415,14 +1531,14 @@ g_tls_connection_base_read_message (GTlsConnectionBase *tls,
gsize count;
GInputVector *vec = &vectors[i];
- count = MIN (vec->size, tls->app_data_buf->len);
+ count = MIN (vec->size, priv->app_data_buf->len);
nread += count;
- memcpy (vec->buffer, tls->app_data_buf->data, count);
- if (count == tls->app_data_buf->len)
- g_clear_pointer (&tls->app_data_buf, g_byte_array_unref);
+ 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 (tls->app_data_buf, 0, count);
+ g_byte_array_remove_range (priv->app_data_buf, 0, count);
status = G_TLS_CONNECTION_BASE_OK;
}
}
@@ -1643,16 +1759,18 @@ static GInputStream *
g_tls_connection_base_get_input_stream (GIOStream *stream)
{
GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (stream);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
- return tls->tls_istream;
+ return priv->tls_istream;
}
static GOutputStream *
g_tls_connection_base_get_output_stream (GIOStream *stream)
{
GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (stream);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
- return tls->tls_ostream;
+ return priv->tls_ostream;
}
gboolean
@@ -1663,6 +1781,7 @@ g_tls_connection_base_close_internal (GIOStream *stream,
GError **error)
{
GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (stream);
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
GTlsConnectionBaseOp op;
GTlsConnectionBaseStatus status;
gboolean success = TRUE;
@@ -1686,33 +1805,33 @@ g_tls_connection_base_close_internal (GIOStream *stream,
if (!claim_op (tls, op, timeout, cancellable, error))
return FALSE;
- if (tls->ever_handshaked && !tls->write_closed &&
+ if (priv->ever_handshaked && !priv->write_closed &&
direction & G_TLS_DIRECTION_WRITE)
{
status = G_TLS_CONNECTION_BASE_GET_CLASS (tls)->
close_fn (tls, timeout, cancellable, &close_error);
- tls->write_closed = TRUE;
+ priv->write_closed = TRUE;
}
else
status = G_TLS_CONNECTION_BASE_OK;
- if (!tls->read_closed && direction & G_TLS_DIRECTION_READ)
- tls->read_closed = TRUE;
+ if (!priv->read_closed && direction & G_TLS_DIRECTION_READ)
+ priv->read_closed = TRUE;
/* Close the underlying streams. Do this even if the close_fn() call failed,
* as the parent GIOStream will have set its internal closed flag and hence
* this implementation will never be called again. */
- if (tls->base_io_stream != NULL)
+ if (priv->base_io_stream != NULL)
{
if (direction == G_TLS_DIRECTION_BOTH)
- success = g_io_stream_close (tls->base_io_stream,
+ 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 (tls->base_io_stream),
+ 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 (tls->base_io_stream),
+ success = g_output_stream_close (g_io_stream_get_output_stream (priv->base_io_stream),
cancellable, &stream_error);
}
else if (g_tls_connection_base_is_dtls (tls))
@@ -1870,6 +1989,78 @@ g_tls_connection_base_dtls_shutdown_finish (GDtlsConnection *conn,
return g_task_propagate_boolean (G_TASK (result), error);
}
+void
+g_tls_connection_base_set_certificate_requested (GTlsConnectionBase *tls)
+{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
+ /* FIXME: Assert this is only used on the handshake thread. */
+ /* FIXME: Assert it's not already requested? Probably. */
+
+ priv->certificate_requested = TRUE;
+}
+
+GError **
+g_tls_connection_base_get_certificate_error (GTlsConnectionBase *tls)
+{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
+ return &priv->certificate_error;
+}
+
+GError **
+g_tls_connection_base_get_read_error (GTlsConnectionBase *tls)
+{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
+ return &priv->read_error;
+}
+
+GError **
+g_tls_connection_base_get_write_error (GTlsConnectionBase *tls)
+{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
+ return &priv->write_error;
+}
+
+gboolean
+g_tls_connection_base_is_handshaking (GTlsConnectionBase *tls)
+{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
+ return priv->handshaking;
+}
+
+gboolean
+g_tls_connection_base_ever_handshaked (GTlsConnectionBase *tls)
+{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+
+ return priv->ever_handshaked;
+}
+
+gboolean
+g_tls_connection_base_request_certificate (GTlsConnectionBase *tls,
+ GError **error)
+{
+ GTlsConnectionBasePrivate *priv = g_tls_connection_base_get_instance_private (tls);
+ GTlsInteractionResult res = G_TLS_INTERACTION_UNHANDLED;
+ GTlsInteraction *interaction;
+ GTlsConnection *conn;
+
+ g_return_val_if_fail (G_IS_TLS_CONNECTION_BASE (tls), FALSE);
+
+ conn = G_TLS_CONNECTION (tls);
+
+ interaction = g_tls_connection_get_interaction (conn);
+ if (!interaction)
+ return FALSE;
+
+ res = g_tls_interaction_invoke_request_certificate (interaction, conn, 0,
+ priv->read_cancellable, error);
+ return res != G_TLS_INTERACTION_FAILED;
+}
static void
g_tls_connection_base_class_init (GTlsConnectionBaseClass *klass)
diff --git a/tls/base/gtlsconnection-base.h b/tls/base/gtlsconnection-base.h
index 73329f6..b3a700d 100644
--- a/tls/base/gtlsconnection-base.h
+++ b/tls/base/gtlsconnection-base.h
@@ -30,15 +30,8 @@
G_BEGIN_DECLS
#define G_TYPE_TLS_CONNECTION_BASE (g_tls_connection_base_get_type ())
-#define G_TLS_CONNECTION_BASE(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst),
G_TYPE_TLS_CONNECTION_BASE, GTlsConnectionBase))
-#define G_TLS_CONNECTION_BASE_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), G_TYPE_TLS_CONNECTION_BASE,
GTlsConnectionBaseClass))
-#define G_IS_TLS_CONNECTION_BASE(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst),
G_TYPE_TLS_CONNECTION_BASE))
-#define G_IS_TLS_CONNECTION_BASE_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), G_TYPE_TLS_CONNECTION_BASE))
-#define G_TLS_CONNECTION_BASE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst),
G_TYPE_TLS_CONNECTION_BASE, GTlsConnectionBaseClass))
-typedef struct _GTlsConnectionBasePrivate GTlsConnectionBasePrivate;
-typedef struct _GTlsConnectionBaseClass GTlsConnectionBaseClass;
-typedef struct _GTlsConnectionBase GTlsConnectionBase;
+G_DECLARE_DERIVABLE_TYPE (GTlsConnectionBase, g_tls_connection_base, G, TLS_CONNECTION_BASE, GTlsConnection)
typedef enum {
G_TLS_CONNECTION_BASE_OK,
@@ -49,6 +42,14 @@ typedef enum {
G_TLS_CONNECTION_BASE_ERROR,
} GTlsConnectionBaseStatus;
+typedef enum {
+ G_TLS_DIRECTION_NONE = 0,
+ G_TLS_DIRECTION_READ = 1 << 0,
+ G_TLS_DIRECTION_WRITE = 1 << 1,
+} GTlsDirection;
+
+#define G_TLS_DIRECTION_BOTH (G_TLS_DIRECTION_READ | G_TLS_DIRECTION_WRITE)
+
struct _GTlsConnectionBaseClass
{
GTlsConnectionClass parent_class;
@@ -109,95 +110,6 @@ struct _GTlsConnectionBaseClass
GError **error);
};
-struct _GTlsConnectionBase
-{
- GTlsConnection parent_instance;
-
- /* When operating in stream mode.
- * Mutually exclusive with base_socket.
- */
- GIOStream *base_io_stream;
- GPollableInputStream *base_istream;
- GPollableOutputStream *base_ostream;
-
- /* When operating in stream mode; when operating in datagram mode, the
- * GTlsConnectionBase itself is the DTLS GDatagramBased (and uses
- * base_socket for its underlying I/O):
- */
- GInputStream *tls_istream;
- GOutputStream *tls_ostream;
-
- /* When operating in datagram mode.
- * Mutually exclusive with base_io_stream.
- */
- GDatagramBased *base_socket;
-
- GTlsDatabase *database;
- GTlsInteraction *interaction;
-
- GTlsCertificate *certificate;
- gboolean certificate_requested;
- GError *certificate_error;
- GTlsCertificate *peer_certificate;
- GTlsCertificateFlags peer_certificate_errors;
-
- gboolean require_close_notify;
- GTlsRehandshakeMode rehandshake_mode;
-
- /* need_handshake means the next claim_op() will get diverted into
- * an implicit handshake (unless it's an OP_HANDSHAKE or OP_CLOSE*).
- * need_finish_handshake means the next claim_op() will get diverted
- * into finish_handshake() (unless it's an OP_CLOSE*).
- *
- * handshaking is TRUE as soon as a handshake thread is queued. For
- * a sync handshake it becomes FALSE after finish_handshake()
- * completes in the calling thread, but for an async implicit
- * handshake, it becomes FALSE (and need_finish_handshake becomes
- * TRUE) at the end of the handshaking thread (and then the next
- * non-close op will call finish_handshake()). We can't just wait
- * for handshake_thread_completed() to run, because it's possible
- * that its main loop is being blocked by a synchronous op which is
- * waiting for handshaking to become FALSE...
- *
- * started_handshake indicates that the current handshake attempt
- * got at least as far as sending the first handshake packet (and so
- * any error should be copied to handshake_error and returned on all
- * future operations). ever_handshaked indicates that TLS has been
- * successfully negotiated at some point.
- */
- gboolean need_handshake;
- gboolean need_finish_handshake;
- gboolean started_handshake;
- gboolean handshaking;
- gboolean ever_handshaked;
- GTask *implicit_handshake;
- GError *handshake_error;
- GByteArray *app_data_buf;
-
- /* read_closed means the read direction has closed; write_closed similarly.
- * If (and only if) both are set, the entire GTlsConnection is closed. */
- gboolean read_closing, read_closed;
- gboolean write_closing, write_closed;
-
- gboolean reading;
- gint64 read_timeout;
- GError *read_error;
- GCancellable *read_cancellable;
-
- gboolean writing;
- gint64 write_timeout;
- GError *write_error;
- GCancellable *write_cancellable;
-
- gboolean is_system_certdb;
- gboolean database_is_unset;
-
- GMutex op_mutex;
- GCancellable *waiting_for_op;
-};
-
-GType g_tls_connection_base_get_type (void) G_GNUC_CONST;
-
gboolean g_tls_connection_base_accept_peer_certificate (GTlsConnectionBase *tls,
GTlsCertificate *peer_certificate,
GTlsCertificateFlags peer_certificate_errors);
@@ -235,20 +147,25 @@ GSource *g_tls_connection_base_create_source (GTlsConnectionBase *tls,
GIOCondition condition,
GCancellable *cancellable);
-typedef enum {
- G_TLS_DIRECTION_NONE = 0,
- G_TLS_DIRECTION_READ = 1 << 0,
- G_TLS_DIRECTION_WRITE = 1 << 1,
-} GTlsDirection;
-
-#define G_TLS_DIRECTION_BOTH (G_TLS_DIRECTION_READ | G_TLS_DIRECTION_WRITE)
-
gboolean g_tls_connection_base_close_internal (GIOStream *stream,
GTlsDirection direction,
gint64 timeout,
GCancellable *cancellable,
GError **error);
+void g_tls_connection_base_set_certificate_requested (GTlsConnectionBase *tls);
+
+GError **g_tls_connection_base_get_certificate_error (GTlsConnectionBase *tls);
+GError **g_tls_connection_base_get_read_error (GTlsConnectionBase *tls);
+GError **g_tls_connection_base_get_write_error (GTlsConnectionBase *tls);
+
+gboolean g_tls_connection_base_is_handshaking (GTlsConnectionBase *tls);
+
+gboolean g_tls_connection_base_ever_handshaked (GTlsConnectionBase *tls);
+
+gboolean g_tls_connection_base_request_certificate (GTlsConnectionBase *tls,
+ GError **error);
+
G_END_DECLS
#endif /* __G_TLS_CONNECTION_BASE_H___ */
diff --git a/tls/openssl/gtlsclientconnection-openssl.c b/tls/openssl/gtlsclientconnection-openssl.c
index 3e352f8..d47f69e 100644
--- a/tls/openssl/gtlsclientconnection-openssl.c
+++ b/tls/openssl/gtlsclientconnection-openssl.c
@@ -333,17 +333,16 @@ retrieve_certificate (SSL *ssl,
GTlsClientConnectionOpenssl *client;
GTlsClientConnectionOpensslPrivate *priv;
GTlsConnectionBase *tls;
- GTlsConnectionOpenssl *openssl;
GTlsCertificate *cert;
gboolean set_certificate = FALSE;
+ GError **certificate_error;
client = SSL_get_ex_data (ssl, data_index);
tls = G_TLS_CONNECTION_BASE (client);
- openssl = G_TLS_CONNECTION_OPENSSL (client);
priv = g_tls_client_connection_openssl_get_instance_private (client);
- tls->certificate_requested = TRUE;
+ g_tls_connection_base_set_certificate_requested (tls);
priv->ca_list = SSL_get_client_CA_list (priv->ssl);
g_object_notify (G_OBJECT (client), "accepted-cas");
@@ -353,8 +352,9 @@ retrieve_certificate (SSL *ssl,
set_certificate = TRUE;
else
{
- g_clear_error (&tls->certificate_error);
- if (g_tls_connection_openssl_request_certificate (openssl, &tls->certificate_error))
+ certificate_error = g_tls_connection_base_get_certificate_error (tls);
+ g_clear_error (certificate_error);
+ if (g_tls_connection_base_request_certificate (tls, certificate_error))
{
cert = g_tls_connection_get_certificate (G_TLS_CONNECTION (client));
set_certificate = (cert != NULL);
diff --git a/tls/openssl/gtlsconnection-openssl.c b/tls/openssl/gtlsconnection-openssl.c
index 4d632ce..0600dea 100644
--- a/tls/openssl/gtlsconnection-openssl.c
+++ b/tls/openssl/gtlsconnection-openssl.c
@@ -136,7 +136,7 @@ end_openssl_io (GTlsConnectionOpenssl *openssl,
err_lib = ERR_GET_LIB (err);
reason = ERR_GET_REASON (err);
- if (tls->handshaking && !tls->ever_handshaked)
+ if (g_tls_connection_base_is_handshaking (tls) && !g_tls_connection_base_ever_handshaked (tls))
{
if (reason == SSL_R_BAD_PACKET_LENGTH ||
reason == SSL_R_UNKNOWN_ALERT_TYPE ||
@@ -222,6 +222,7 @@ g_tls_connection_openssl_request_rehandshake (GTlsConnectionBase *tls,
{
GTlsConnectionOpenssl *openssl;
GTlsConnectionBaseStatus status;
+ GTlsRehandshakeMode rehandshake_mode;
SSL *ssl;
int ret;
@@ -234,7 +235,12 @@ g_tls_connection_openssl_request_rehandshake (GTlsConnectionBase *tls,
openssl = G_TLS_CONNECTION_OPENSSL (tls);
- if (tls->rehandshake_mode == G_TLS_REHANDSHAKE_NEVER)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+ rehandshake_mode = g_tls_connection_get_rehandshake_mode (G_TLS_CONNECTION (tls));
+#pragma GCC diagnostic pop
+
+ if (rehandshake_mode == G_TLS_REHANDSHAKE_NEVER)
{
g_set_error_literal (error, G_TLS_ERROR, G_TLS_ERROR_MISC,
_("Peer requested illegal TLS rehandshake"));
@@ -441,6 +447,7 @@ g_tls_connection_openssl_push_io (GTlsConnectionBase *tls,
{
GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (tls);
GTlsConnectionOpensslPrivate *priv;
+ GError **error;
priv = g_tls_connection_openssl_get_instance_private (openssl);
@@ -452,18 +459,20 @@ g_tls_connection_openssl_push_io (GTlsConnectionBase *tls,
if (direction & G_IO_IN)
{
+ error = g_tls_connection_base_get_read_error (tls);
g_tls_bio_set_read_cancellable (priv->bio, cancellable);
g_tls_bio_set_read_blocking (priv->bio, timeout == -1);
- g_clear_error (&tls->read_error);
- g_tls_bio_set_read_error (priv->bio, &tls->read_error);
+ g_clear_error (error);
+ g_tls_bio_set_read_error (priv->bio, error);
}
if (direction & G_IO_OUT)
{
+ error = g_tls_connection_base_get_write_error (tls);
g_tls_bio_set_write_cancellable (priv->bio, cancellable);
g_tls_bio_set_write_blocking (priv->bio, timeout == -1);
- g_clear_error (&tls->write_error);
- g_tls_bio_set_write_error (priv->bio, &tls->write_error);
+ g_clear_error (error);
+ g_tls_bio_set_write_error (priv->bio, error);
}
}
@@ -591,17 +600,20 @@ g_tls_connection_openssl_initable_init (GInitable *initable,
GTlsConnectionOpenssl *openssl = G_TLS_CONNECTION_OPENSSL (initable);
GTlsConnectionOpensslPrivate *priv;
GTlsConnectionBase *tls = G_TLS_CONNECTION_BASE (initable);
+ GIOStream *base_io_stream;
SSL *ssl;
- g_return_val_if_fail (tls->base_istream != NULL &&
- tls->base_ostream != NULL, FALSE);
+ g_object_get (tls,
+ "base-io-stream", &base_io_stream,
+ NULL);
+ g_return_val_if_fail (base_io_stream != NULL, FALSE);
priv = g_tls_connection_openssl_get_instance_private (openssl);
ssl = g_tls_connection_openssl_get_ssl (openssl);
g_assert (ssl != NULL);
- priv->bio = g_tls_bio_new (tls->base_io_stream);
+ priv->bio = g_tls_bio_new (base_io_stream);
SSL_set_bio (ssl, priv->bio, priv->bio);
@@ -626,26 +638,3 @@ g_tls_connection_openssl_get_ssl (GTlsConnectionOpenssl *openssl)
return G_TLS_CONNECTION_OPENSSL_GET_CLASS (openssl)->get_ssl (openssl);
}
-
-gboolean
-g_tls_connection_openssl_request_certificate (GTlsConnectionOpenssl *openssl,
- GError **error)
-{
- GTlsInteractionResult res = G_TLS_INTERACTION_UNHANDLED;
- GTlsInteraction *interaction;
- GTlsConnection *conn;
- GTlsConnectionBase *tls;
-
- g_return_val_if_fail (G_IS_TLS_CONNECTION_OPENSSL (openssl), FALSE);
-
- conn = G_TLS_CONNECTION (openssl);
- tls = G_TLS_CONNECTION_BASE (openssl);
-
- interaction = g_tls_connection_get_interaction (conn);
- if (!interaction)
- return FALSE;
-
- res = g_tls_interaction_invoke_request_certificate (interaction, conn, 0,
- tls->read_cancellable, error);
- return res != G_TLS_INTERACTION_FAILED;
-}
diff --git a/tls/openssl/gtlsconnection-openssl.h b/tls/openssl/gtlsconnection-openssl.h
index ef8e41d..08ee313 100644
--- a/tls/openssl/gtlsconnection-openssl.h
+++ b/tls/openssl/gtlsconnection-openssl.h
@@ -59,9 +59,6 @@ GType g_tls_connection_openssl_get_type (void) G_GNUC_CONST;
SSL *g_tls_connection_openssl_get_ssl (GTlsConnectionOpenssl *connection);
-gboolean g_tls_connection_openssl_request_certificate (GTlsConnectionOpenssl *openssl,
- GError **error);
-
G_END_DECLS
#endif /* __G_TLS_CONNECTION_OPENSSL_H___ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]