[gtk+] broadway: Initial SSL support
- From: Martyn James Russell <mr src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] broadway: Initial SSL support
- Date: Mon, 15 Dec 2014 11:28:27 +0000 (UTC)
commit c00cc269c5be8537a0ae5a37991e2c8ffc918d81
Author: Michael Natterer <mitch lanedo com>
Date: Mon Dec 15 11:25:43 2014 +0000
broadway: Initial SSL support
Use the new --cert and --key parameters to broadwayd to pass paths to
cert and key files.
https://bugzilla.gnome.org/show_bug.cgi?id=730364
gdk/broadway/broadway-server.c | 90 ++++++++++++++++++++++++++++++++--------
gdk/broadway/broadway-server.h | 2 +
gdk/broadway/broadwayd.c | 10 ++++-
3 files changed, 83 insertions(+), 19 deletions(-)
---
diff --git a/gdk/broadway/broadway-server.c b/gdk/broadway/broadway-server.c
index 8ee4b59..547729f 100644
--- a/gdk/broadway/broadway-server.c
+++ b/gdk/broadway/broadway-server.c
@@ -42,6 +42,8 @@ struct _BroadwayServer {
char *address;
int port;
+ char *ssl_cert;
+ char *ssl_key;
GSocketService *service;
BroadwayOutput *output;
guint32 id_counter;
@@ -85,7 +87,8 @@ struct _BroadwayServerClass
typedef struct HttpRequest {
BroadwayServer *server;
- GSocketConnection *connection;
+ GSocketConnection *socket_connection;
+ GIOStream *connection;
GDataInputStream *data;
GString *request;
} HttpRequest;
@@ -93,7 +96,7 @@ typedef struct HttpRequest {
struct BroadwayInput {
BroadwayServer *server;
BroadwayOutput *output;
- GSocketConnection *connection;
+ GIOStream *connection;
GByteArray *buffer;
GSource *source;
gboolean seen_time;
@@ -155,6 +158,8 @@ broadway_server_finalize (GObject *object)
BroadwayServer *server = BROADWAY_SERVER (object);
g_free (server->address);
+ g_free (server->ssl_cert);
+ g_free (server->ssl_key);
G_OBJECT_CLASS (broadway_server_parent_class)->finalize (object);
}
@@ -172,6 +177,7 @@ static void start (BroadwayInput *input);
static void
http_request_free (HttpRequest *request)
{
+ g_object_unref (request->socket_connection);
g_object_unref (request->connection);
g_object_unref (request->data);
g_string_free (request->request, TRUE);
@@ -661,14 +667,13 @@ broadway_server_read_all_input_nonblocking (BroadwayInput *input)
GInputStream *in;
gssize res;
guint8 buffer[1024];
- GError *error;
+ GError *error = NULL;
if (input == NULL)
return;
- in = g_io_stream_get_input_stream (G_IO_STREAM (input->connection));
+ in = g_io_stream_get_input_stream (input->connection);
- error = NULL;
res = g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (in),
buffer, sizeof (buffer), NULL, &error);
@@ -796,7 +801,8 @@ broadway_server_block_for_input (BroadwayServer *server, char op,
/* Not found, read more, blocking */
- in = g_io_stream_get_input_stream (G_IO_STREAM (input->connection));
+ in = g_io_stream_get_input_stream (input->connection);
+
res = g_input_stream_read (in, buffer, sizeof (buffer), NULL, NULL);
if (res <= 0)
return NULL;
@@ -909,9 +915,11 @@ send_error (HttpRequest *request,
error_code, reason,
error_code, reason,
reason);
+
/* TODO: This should really be async */
- g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
- res, strlen (res), NULL, NULL, NULL);
+ g_output_stream_write_all (g_io_stream_get_output_stream (request->connection),
+ res, strlen (res), NULL, NULL, NULL);
+
g_free (res);
http_request_free (request);
}
@@ -1004,8 +1012,8 @@ start_input (HttpRequest *request)
g_print ("v7 proto response:\n%s", res);
#endif
- g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
- res, strlen (res), NULL, NULL, NULL);
+ g_output_stream_write_all (g_io_stream_get_output_stream (request->connection),
+ res, strlen (res), NULL, NULL, NULL);
g_free (res);
}
else
@@ -1015,7 +1023,7 @@ start_input (HttpRequest *request)
return;
}
- socket = g_socket_connection_get_socket (request->connection);
+ socket = g_socket_connection_get_socket (request->socket_connection);
setsockopt (g_socket_get_fd (socket), IPPROTO_TCP,
TCP_NODELAY, (char *) &flag, sizeof(int));
@@ -1028,12 +1036,13 @@ start_input (HttpRequest *request)
g_byte_array_append (input->buffer, data_buffer, data_buffer_size);
input->output =
- broadway_output_new (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)), 0);
+ broadway_output_new (g_io_stream_get_output_stream (request->connection), 0);
/* This will free and close the data input stream, but we got all the buffered content already */
http_request_free (request);
- in = g_io_stream_get_input_stream (G_IO_STREAM (input->connection));
+ in = g_io_stream_get_input_stream (input->connection);
+
input->source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (in), NULL);
g_source_set_callback (input->source, (GSourceFunc)input_data_cb, input, NULL);
g_source_attach (input->source, NULL);
@@ -1101,11 +1110,12 @@ send_data (HttpRequest *request,
"Content-Length: %"G_GSIZE_FORMAT"\r\n"
"\r\n",
mimetype, len);
+
/* TODO: This should really be async */
- g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
+ g_output_stream_write_all (g_io_stream_get_output_stream (request->connection),
res, strlen (res), NULL, NULL, NULL);
g_free (res);
- g_output_stream_write_all (g_io_stream_get_output_stream (G_IO_STREAM (request->connection)),
+ g_output_stream_write_all (g_io_stream_get_output_stream (request->connection),
data, len, NULL, NULL, NULL);
http_request_free (request);
}
@@ -1202,11 +1212,49 @@ handle_incoming_connection (GSocketService *service,
GInputStream *in;
request = g_new0 (HttpRequest, 1);
- request->connection = g_object_ref (connection);
+ request->socket_connection = g_object_ref (connection);
request->server = BROADWAY_SERVER (source_object);
request->request = g_string_new ("");
- in = g_io_stream_get_input_stream (G_IO_STREAM (connection));
+ if (request->server->ssl_cert && request->server->ssl_key)
+ {
+ GError *error = NULL;
+ GTlsCertificate *certificate;
+
+ certificate = g_tls_certificate_new_from_files (request->server->ssl_cert,
+ request->server->ssl_key,
+ &error);
+ if (!certificate)
+ {
+ g_warning ("Cannot create TLS certificate: %s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ request->connection = g_tls_server_connection_new (G_IO_STREAM (connection),
+ certificate,
+ &error);
+ if (!request->connection)
+ {
+ g_warning ("Cannot create TLS connection: %s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+
+ if (!g_tls_connection_handshake (G_TLS_CONNECTION (request->connection),
+ NULL, &error))
+ {
+ g_warning ("Cannot create TLS connection: %s", error->message);
+ g_error_free (error);
+ return FALSE;
+ }
+ }
+ else
+ {
+ request->connection = g_object_ref (connection);
+ }
+
+ in = g_io_stream_get_input_stream (request->connection);
request->data = g_data_input_stream_new (in);
g_filter_input_stream_set_close_base_stream (G_FILTER_INPUT_STREAM (request->data), FALSE);
@@ -1219,7 +1267,11 @@ handle_incoming_connection (GSocketService *service,
}
BroadwayServer *
-broadway_server_new (char *address, int port, GError **error)
+broadway_server_new (char *address,
+ int port,
+ const char *ssl_cert,
+ const char *ssl_key,
+ GError **error)
{
BroadwayServer *server;
GInetAddress *inet_address;
@@ -1228,6 +1280,8 @@ broadway_server_new (char *address, int port, GError **error)
server = g_object_new (BROADWAY_TYPE_SERVER, NULL);
server->port = port;
server->address = g_strdup (address);
+ server->ssl_cert = g_strdup (ssl_cert);
+ server->ssl_key = g_strdup (ssl_key);
if (address == NULL)
{
diff --git a/gdk/broadway/broadway-server.h b/gdk/broadway/broadway-server.h
index cbe656e..b5d3191 100644
--- a/gdk/broadway/broadway-server.h
+++ b/gdk/broadway/broadway-server.h
@@ -21,6 +21,8 @@ typedef struct _BroadwayServerClass BroadwayServerClass;
BroadwayServer *broadway_server_new (char *address,
int port,
+ const char *ssl_cert,
+ const char *ssl_key,
GError **error);
BroadwayServer *broadway_server_on_unix_socket_new (char *address,
GError **error);
diff --git a/gdk/broadway/broadwayd.c b/gdk/broadway/broadwayd.c
index 031e866..e1a0fc8 100644
--- a/gdk/broadway/broadwayd.c
+++ b/gdk/broadway/broadwayd.c
@@ -419,6 +419,8 @@ main (int argc, char *argv[])
char *http_address = NULL;
char *unixsocket_address = NULL;
int http_port = 0;
+ char *ssl_cert = NULL;
+ char *ssl_key = NULL;
char *display;
int port = 0;
const GOptionEntry entries[] = {
@@ -427,6 +429,8 @@ main (int argc, char *argv[])
#ifdef G_OS_UNIX
{ "unixsocket", 'u', 0, G_OPTION_ARG_STRING, &unixsocket_address, "Unix domain socket address",
"ADDRESS" },
#endif
+ { "cert", 'c', 0, G_OPTION_ARG_STRING, &ssl_cert, "SSL certificate path", "PATH" },
+ { "key", 'k', 0, G_OPTION_ARG_STRING, &ssl_key, "SSL key path", "PATH" },
{ NULL }
};
@@ -493,7 +497,11 @@ main (int argc, char *argv[])
if (unixsocket_address != NULL)
server = broadway_server_on_unix_socket_new (unixsocket_address, &error);
else
- server = broadway_server_new (http_address, http_port, &error);
+ server = broadway_server_new (http_address,
+ http_port,
+ ssl_cert,
+ ssl_key,
+ &error);
if (server == NULL)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]