From 1166467ce26d249e72d6961e239e96594fe2a020 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Sun, 24 Oct 2010 12:06:03 -0400 Subject: [PATCH] wocky-tls: Merge WockyTLSSession and WockyTLSConnection together to match gio TLS, and because there's not much use in the separation anyway https://bugs.freedesktop.org/show_bug.cgi?id=31447 --- examples/connect.c | 7 +- tests/wocky-test-connector-server.c | 9 +- tests/wocky-tls-test.c | 24 ++-- wocky/wocky-tls-connector.c | 9 +- wocky/wocky-tls.c | 245 ++++++++++++----------------------- wocky/wocky-tls.h | 11 +-- 6 files changed, 107 insertions(+), 198 deletions(-) diff --git a/examples/connect.c b/examples/connect.c index 2f2b9e8..ed8cf74 100644 --- a/examples/connect.c +++ b/examples/connect.c @@ -21,7 +21,6 @@ WockySaslAuth *sasl = NULL; GSocketConnection *tcp; GSocketClient *client; -WockyTLSConnection *ssl; WockyTLSSession *ssl_session; static void @@ -167,13 +166,11 @@ tcp_start_tls_recv_cb (GObject *source, g_object_unref (conn); ssl_session = wocky_tls_session_new (G_IO_STREAM (tcp), server); - ssl = wocky_tls_session_handshake (ssl_session, NULL, &error); - - if (ssl == NULL) + if (!wocky_tls_session_handshake (ssl_session, NULL, &error)) g_error ("connect: %s: %d, %s", g_quark_to_string (error->domain), error->code, error->message); - conn = wocky_xmpp_connection_new (G_IO_STREAM (ssl)); + conn = wocky_xmpp_connection_new (G_IO_STREAM (ssl_session)); wocky_xmpp_connection_send_open_async (conn, server, NULL, "1.0", NULL, NULL, NULL, ssl_open_sent_cb, NULL); diff --git a/tests/wocky-test-connector-server.c b/tests/wocky-test-connector-server.c index b22e046..3143edc 100644 --- a/tests/wocky-test-connector-server.c +++ b/tests/wocky-test-connector-server.c @@ -1056,12 +1056,12 @@ handshake_cb (GObject *source, { TestConnectorServer *self = TEST_CONNECTOR_SERVER (user_data); TestConnectorServerPrivate *priv = self->priv; - WockyTLSConnection *tls_conn; + gboolean success; GError *error = NULL; DEBUG ("TLS/SSL handshake finished"); - tls_conn = wocky_tls_session_handshake_finish ( + success = wocky_tls_session_handshake_finish ( WOCKY_TLS_SESSION (source), result, &error); @@ -1069,7 +1069,7 @@ handshake_cb (GObject *source, if (server_dec_outstanding (self)) goto out; - if (tls_conn == NULL) + if (!success) { DEBUG ("SSL or TLS Server Setup failed: %s", error->message); g_io_stream_close (priv->stream, NULL, NULL); @@ -1080,8 +1080,7 @@ handshake_cb (GObject *source, g_object_unref (priv->conn); priv->state = SERVER_STATE_START; - priv->conn = wocky_xmpp_connection_new (G_IO_STREAM (tls_conn)); - g_object_unref (tls_conn); + priv->conn = wocky_xmpp_connection_new (G_IO_STREAM (source)); priv->tls_started = TRUE; xmpp_init (NULL,NULL,self); diff --git a/tests/wocky-tls-test.c b/tests/wocky-tls-test.c index 44667a5..988f9ae 100644 --- a/tests/wocky-tls-test.c +++ b/tests/wocky-tls-test.c @@ -23,8 +23,8 @@ typedef struct { test_data_t *test; char cli_buf[BUF_SIZE]; char srv_buf[BUF_SIZE]; - WockyTLSConnection *client; - WockyTLSConnection *server; + WockyTLSSession *client; + WockyTLSSession *server; GString *cli_data; GString *srv_data; guint read_op_count; @@ -118,8 +118,10 @@ client_handshake_cb (GObject *source, GInputStream *input; WockyTLSSession *session = WOCKY_TLS_SESSION (source); ssl_test_t *ssl_test = data; + GError *error = NULL; - ssl_test->client = wocky_tls_session_handshake_finish (session, result, NULL); + wocky_tls_session_handshake_finish (session, result, &error); + g_assert_no_error (error); input = g_io_stream_get_input_stream (G_IO_STREAM (ssl_test->client)); ssl_test->in_read = TRUE; @@ -186,11 +188,9 @@ server_handshake_cb (GObject *source, ssl_test_t *ssl_test = data; GError *error = NULL; - ssl_test->server = wocky_tls_session_handshake_finish (session, - result, &error); + wocky_tls_session_handshake_finish (session, result, &error); g_assert_no_error (error); - g_assert (ssl_test->server != NULL); output = g_io_stream_get_output_stream (G_IO_STREAM (ssl_test->server)); @@ -235,21 +235,21 @@ test_openssl_handshake_rw (void) { ssl_test_t ssl_test = { NULL, } ; test_data_t *test = setup_test (); - WockyTLSSession *client = wocky_tls_session_new (test->stream->stream0, NULL); - WockyTLSSession *server = wocky_tls_session_server_new ( - test->stream->stream1, 1024, TLS_SERVER_KEY_FILE, TLS_SERVER_CRT_FILE); gsize expected = TEST_SSL_DATA_LEN * 5; gchar *target = TEST_SSL_DATA_A "\0" TEST_SSL_DATA_B "\0" TEST_SSL_DATA_A "\0" TEST_SSL_DATA_B "\0" TEST_SSL_DATA_A; setup_ssl_test (&ssl_test, test); + ssl_test.client = wocky_tls_session_new (test->stream->stream0, NULL); + ssl_test.server = wocky_tls_session_server_new ( + test->stream->stream1, 1024, TLS_SERVER_KEY_FILE, TLS_SERVER_CRT_FILE); - wocky_tls_session_handshake_async (client, G_PRIORITY_DEFAULT, + wocky_tls_session_handshake_async (ssl_test.client, G_PRIORITY_DEFAULT, test->cancellable, client_handshake_cb, &ssl_test); test->outstanding += 1; - wocky_tls_session_handshake_async (server, G_PRIORITY_DEFAULT, + wocky_tls_session_handshake_async (ssl_test.server, G_PRIORITY_DEFAULT, test->cancellable, server_handshake_cb, &ssl_test); test->outstanding += 1; @@ -264,8 +264,6 @@ test_openssl_handshake_rw (void) teardown_test (test); teardown_ssl_test (&ssl_test); - g_object_unref (client); - g_object_unref (server); } diff --git a/wocky/wocky-tls-connector.c b/wocky/wocky-tls-connector.c index c383dda..ef2062e 100644 --- a/wocky/wocky-tls-connector.c +++ b/wocky/wocky-tls-connector.c @@ -304,15 +304,15 @@ session_handshake_cb (GObject *source, gpointer user_data) { GError *error = NULL; - WockyTLSConnection *tls_conn; + gboolean success; WockyTLSConnector *self = user_data; const gchar *tls_type; tls_type = self->priv->legacy_ssl ? "SSL" : "TLS"; - tls_conn = wocky_tls_session_handshake_finish (self->priv->session, + success = wocky_tls_session_handshake_finish (self->priv->session, res, &error); - if (tls_conn == NULL) + if (!success) { report_error_in_idle (self, WOCKY_CONNECTOR_ERROR_TLS_SESSION_FAILED, "%s handshake error: %s", tls_type, error->message); @@ -324,8 +324,7 @@ session_handshake_cb (GObject *source, DEBUG ("Completed %s handshake", tls_type); self->priv->tls_connection = wocky_xmpp_connection_new ( - G_IO_STREAM (tls_conn)); - g_object_unref (tls_conn); + G_IO_STREAM (source)); wocky_tls_handler_verify_async (self->priv->handler, self->priv->session, diff --git a/wocky/wocky-tls.c b/wocky/wocky-tls.c index b43dc0e..40a019c 100644 --- a/wocky/wocky-tls.c +++ b/wocky/wocky-tls.c @@ -91,12 +91,6 @@ enum enum { - PROP_C_NONE, - PROP_C_SESSION, -}; - -enum -{ PROP_O_NONE, PROP_O_SESSION }; @@ -164,8 +158,7 @@ typedef struct GError *error; } WockyTLSOp; -typedef GIOStreamClass WockyTLSConnectionClass; -typedef GObjectClass WockyTLSSessionClass; +typedef GIOStreamClass WockyTLSSessionClass; typedef GInputStreamClass WockyTLSInputStreamClass; typedef GOutputStreamClass WockyTLSOutputStreamClass; @@ -175,9 +168,12 @@ static gnutls_dh_params_t dh_2048 = NULL; static gnutls_dh_params_t dh_3072 = NULL; static gnutls_dh_params_t dh_4096 = NULL; +typedef struct _WockyTLSInputStream WockyTLSInputStream; +typedef struct _WockyTLSInputStream WockyTLSOutputStream; + struct OPAQUE_TYPE__WockyTLSSession { - GObject parent; + GIOStream parent; GIOStream *stream; GCancellable *cancellable; @@ -206,35 +202,28 @@ struct OPAQUE_TYPE__WockyTLSSession gnutls_session_t session; gnutls_certificate_credentials gnutls_cert_cred; + + WockyTLSInputStream *input; + WockyTLSOutputStream *output; }; -typedef struct +struct _WockyTLSInputStream { GInputStream parent; WockyTLSSession *session; -} WockyTLSInputStream; +}; -typedef struct +struct _WockyTLSOutputStream { GOutputStream parent; WockyTLSSession *session; -} WockyTLSOutputStream; - -struct OPAQUE_TYPE__WockyTLSConnection -{ - GIOStream parent; - - WockyTLSSession *session; - WockyTLSInputStream *input; - WockyTLSOutputStream *output; }; static guint tls_debug_level = 0; static GType wocky_tls_input_stream_get_type (void); static GType wocky_tls_output_stream_get_type (void); -G_DEFINE_TYPE (WockyTLSConnection, wocky_tls_connection, G_TYPE_IO_STREAM); -G_DEFINE_TYPE (WockyTLSSession, wocky_tls_session, G_TYPE_OBJECT); +G_DEFINE_TYPE (WockyTLSSession, wocky_tls_session, G_TYPE_IO_STREAM); G_DEFINE_TYPE (WockyTLSInputStream, wocky_tls_input_stream, G_TYPE_INPUT_STREAM); G_DEFINE_TYPE (WockyTLSOutputStream, wocky_tls_output_stream, G_TYPE_OUTPUT_STREAM); #define WOCKY_TYPE_TLS_INPUT_STREAM (wocky_tls_input_stream_get_type ()) @@ -480,7 +469,7 @@ wocky_tls_job_start (WockyTLSJob *job, job->active = TRUE; } -WockyTLSConnection * +gboolean wocky_tls_session_handshake (WockyTLSSession *session, GCancellable *cancellable, GError **error) @@ -504,12 +493,12 @@ wocky_tls_session_handshake (WockyTLSSession *session, result == GNUTLS_E_PUSH_ERROR); g_propagate_error (error, session->error); - return NULL; + return FALSE; } else if (wocky_tls_set_error (error, result)) - return NULL; + return FALSE; - return g_object_new (WOCKY_TYPE_TLS_CONNECTION, "session", session, NULL); + return TRUE; } /* ************************************************************************* */ @@ -595,7 +584,7 @@ wocky_tls_session_handshake_async (WockyTLSSession *session, wocky_tls_session_try_operation (session, 0); } -WockyTLSConnection * +gboolean wocky_tls_session_handshake_finish (WockyTLSSession *session, GAsyncResult *result, GError **error) @@ -607,17 +596,17 @@ wocky_tls_session_handshake_finish (WockyTLSSession *session, source_object = g_async_result_get_source_object (result); g_object_unref (source_object); - g_return_val_if_fail (G_OBJECT (session) == source_object, NULL); + g_return_val_if_fail (G_OBJECT (session) == source_object, FALSE); } g_return_val_if_fail (wocky_tls_session_handshake_async == - g_simple_async_result_get_source_tag (simple), NULL); + g_simple_async_result_get_source_tag (simple), FALSE); if (g_simple_async_result_propagate_error (simple, error)) - return NULL; + return FALSE; DEBUG ("connection OK"); - return g_object_new (WOCKY_TYPE_TLS_CONNECTION, "session", session, NULL); + return TRUE; } GPtrArray * @@ -985,7 +974,7 @@ wocky_tls_output_stream_set_property (GObject *object, guint prop_id, switch (prop_id) { - case PROP_C_SESSION: + case PROP_O_SESSION: stream->session = g_value_dup_object (value); break; @@ -1041,7 +1030,7 @@ wocky_tls_input_stream_set_property (GObject *object, guint prop_id, switch (prop_id) { - case PROP_C_SESSION: + case PROP_I_SESSION: stream->session = g_value_dup_object (value); break; @@ -1090,11 +1079,6 @@ wocky_tls_input_stream_class_init (GInputStreamClass *class) } static void -wocky_tls_connection_init (WockyTLSConnection *connection) -{ -} - -static void wocky_tls_session_read_ready (GObject *object, GAsyncResult *result, gpointer user_data) @@ -1501,6 +1485,12 @@ wocky_tls_session_finalize (GObject *object) { WockyTLSSession *session = WOCKY_TLS_SESSION (object); + if (session->input != NULL) + g_object_unref (session->input); + + if (session->output != NULL) + g_object_unref (session->output); + gnutls_deinit (session->session); gnutls_certificate_free_credentials (session->gnutls_cert_cred); g_object_unref (session->stream); @@ -1529,51 +1519,94 @@ wocky_tls_session_dispose (GObject *object) G_OBJECT_CLASS (wocky_tls_session_parent_class)->dispose (object); } +static gboolean +wocky_tls_session_close (GIOStream *stream, + GCancellable *cancellable, + GError **error) +{ + WockyTLSSession *session = WOCKY_TLS_SESSION (stream); + + return g_io_stream_close (session->stream, cancellable, error); +} + +static GInputStream * +wocky_tls_session_get_input_stream (GIOStream *io_stream) +{ + WockyTLSSession *session = WOCKY_TLS_SESSION (io_stream); + + if (session->input == NULL) + session->input = g_object_new (WOCKY_TYPE_TLS_INPUT_STREAM, + "session", session, + NULL); + + return (GInputStream *)session->input; +} + +static GOutputStream * +wocky_tls_session_get_output_stream (GIOStream *io_stream) +{ + WockyTLSSession *session = WOCKY_TLS_SESSION (io_stream); + + if (session->output == NULL) + session->output = g_object_new (WOCKY_TYPE_TLS_OUTPUT_STREAM, + "session", session, + NULL); + + return (GOutputStream *)session->output; +} + static void -wocky_tls_session_class_init (GObjectClass *class) +wocky_tls_session_class_init (WockyTLSSessionClass *class) { - class->get_property = wocky_tls_session_get_property; - class->set_property = wocky_tls_session_set_property; - class->constructed = wocky_tls_session_constructed; - class->finalize = wocky_tls_session_finalize; - class->dispose = wocky_tls_session_dispose; + GObjectClass *object_class = G_OBJECT_CLASS (class); + GIOStreamClass *stream_class = G_IO_STREAM_CLASS (class); + + object_class->get_property = wocky_tls_session_get_property; + object_class->set_property = wocky_tls_session_set_property; + object_class->constructed = wocky_tls_session_constructed; + object_class->finalize = wocky_tls_session_finalize; + object_class->dispose = wocky_tls_session_dispose; + + stream_class->get_input_stream = wocky_tls_session_get_input_stream; + stream_class->get_output_stream = wocky_tls_session_get_output_stream; + stream_class->close_fn = wocky_tls_session_close; - g_object_class_install_property (class, PROP_S_STREAM, + g_object_class_install_property (object_class, PROP_S_STREAM, g_param_spec_object ("base-stream", "base stream", "the stream that TLS communicates over", G_TYPE_IO_STREAM, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (class, PROP_S_PEERNAME, + g_object_class_install_property (object_class, PROP_S_PEERNAME, g_param_spec_string ("peername", "peer name", "Peer host/domain name", NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (class, PROP_S_SERVER, + g_object_class_install_property (object_class, PROP_S_SERVER, g_param_spec_boolean ("server", "server", "whether this is a server", FALSE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (class, PROP_S_DHBITS, + g_object_class_install_property (object_class, PROP_S_DHBITS, g_param_spec_uint ("dh-bits", "Diffie-Hellman bits", "Diffie-Hellmann bits: 768, 1024, 2048, 3072 0r 4096", 768, 4096, 1024, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (class, PROP_S_KEYFILE, + g_object_class_install_property (object_class, PROP_S_KEYFILE, g_param_spec_string ("x509-key", "x509 key", "x509 PEM key file", NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); - g_object_class_install_property (class, PROP_S_CERTFILE, + g_object_class_install_property (object_class, PROP_S_CERTFILE, g_param_spec_string ("x509-cert", "x509 certificate", "x509 PEM certificate file", NULL, G_PARAM_WRITABLE | @@ -1581,116 +1614,6 @@ wocky_tls_session_class_init (GObjectClass *class) G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB)); } -static void -wocky_tls_connection_set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec) -{ - WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (object); - - switch (prop_id) - { - case PROP_C_SESSION: - connection->session = g_value_dup_object (value); - break; - - default: - g_assert_not_reached (); - } -} - -static gboolean -wocky_tls_connection_close (GIOStream *stream, - GCancellable *cancellable, - GError **error) -{ - WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (stream); - - return g_io_stream_close (connection->session->stream, cancellable, error); -} - -static GInputStream * -wocky_tls_connection_get_input_stream (GIOStream *io_stream) -{ - WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (io_stream); - - if (connection->input == NULL) - connection->input = g_object_new (WOCKY_TYPE_TLS_INPUT_STREAM, - "session", connection->session, - NULL); - - return (GInputStream *)connection->input; -} - -static GOutputStream * -wocky_tls_connection_get_output_stream (GIOStream *io_stream) -{ - WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (io_stream); - - if (connection->output == NULL) - connection->output = g_object_new (WOCKY_TYPE_TLS_OUTPUT_STREAM, - "session", connection->session, - NULL); - - return (GOutputStream *)connection->output; -} - -static void -wocky_tls_connection_get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec) -{ - switch (prop_id) - { - default: - g_assert_not_reached (); - } -} - -static void -wocky_tls_connection_constructed (GObject *object) -{ - WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (object); - - g_assert (connection->session); -} - -static void -wocky_tls_connection_finalize (GObject *object) -{ - WockyTLSConnection *connection = WOCKY_TLS_CONNECTION (object); - - g_object_unref (connection->session); - - if (connection->input != NULL) - g_object_unref (connection->input); - - if (connection->output != NULL) - g_object_unref (connection->output); - - G_OBJECT_CLASS (wocky_tls_connection_parent_class) - ->finalize (object); -} - -static void -wocky_tls_connection_class_init (WockyTLSConnectionClass *class) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (class); - GIOStreamClass *stream_class = G_IO_STREAM_CLASS (class); - - gobject_class->get_property = wocky_tls_connection_get_property; - gobject_class->set_property = wocky_tls_connection_set_property; - gobject_class->constructed = wocky_tls_connection_constructed; - gobject_class->finalize = wocky_tls_connection_finalize; - - g_object_class_install_property (gobject_class, PROP_C_SESSION, - g_param_spec_object ("session", "TLS session", - "the TLS session object for this connection", - WOCKY_TYPE_TLS_SESSION, G_PARAM_WRITABLE | - G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); - stream_class->get_input_stream = wocky_tls_connection_get_input_stream; - stream_class->get_output_stream = wocky_tls_connection_get_output_stream; - stream_class->close_fn = wocky_tls_connection_close; -} - WockyTLSSession * wocky_tls_session_new (GIOStream *stream, const gchar *peername) diff --git a/wocky/wocky-tls.h b/wocky/wocky-tls.h index 95eea55..85d09b3 100644 --- a/wocky/wocky-tls.h +++ b/wocky/wocky-tls.h @@ -28,16 +28,10 @@ #include -#define WOCKY_TYPE_TLS_CONNECTION (wocky_tls_connection_get_type ()) #define WOCKY_TYPE_TLS_SESSION (wocky_tls_session_get_type ()) #define WOCKY_TLS_SESSION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \ WOCKY_TYPE_TLS_SESSION, WockyTLSSession)) -#define WOCKY_TLS_CONNECTION(inst)(G_TYPE_CHECK_INSTANCE_CAST ((inst), \ - WOCKY_TYPE_TLS_CONNECTION, \ - WockyTLSConnection)) - -typedef struct OPAQUE_TYPE__WockyTLSConnection WockyTLSConnection; typedef struct OPAQUE_TYPE__WockyTLSSession WockyTLSSession; typedef enum @@ -77,7 +71,6 @@ typedef enum WOCKY_TLS_CERT_TYPE_OPENPGP, } WockyTLSCertType; -GType wocky_tls_connection_get_type (void); GType wocky_tls_session_get_type (void); int wocky_tls_session_verify_peer (WockyTLSSession *session, @@ -86,7 +79,7 @@ int wocky_tls_session_verify_peer (WockyTLSSession *session, GPtrArray *wocky_tls_session_get_peers_certificate (WockyTLSSession *session, WockyTLSCertType *type); -WockyTLSConnection *wocky_tls_session_handshake (WockyTLSSession *session, +gboolean wocky_tls_session_handshake (WockyTLSSession *session, GCancellable *cancellable, GError **error); void @@ -95,7 +88,7 @@ wocky_tls_session_handshake_async (WockyTLSSession *session, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data); -WockyTLSConnection * +gboolean wocky_tls_session_handshake_finish (WockyTLSSession *session, GAsyncResult *result, GError **error); -- 1.7.3.1