From: Stephan Bosch Date: Fri, 9 Feb 2018 21:27:00 +0000 (+0100) Subject: lib-http: server: Allow creating server with custom SSL settings. X-Git-Tag: 2.3.9~1801 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7bb571d450137e41c548985b70495bcb2d1a0fef;p=thirdparty%2Fdovecot%2Fcore.git lib-http: server: Allow creating server with custom SSL settings. Normally, the settings are obtained through lib-master, but that is not really suitable for the test suite. --- diff --git a/src/lib-http/http-server-connection.c b/src/lib-http/http-server-connection.c index 4cbffc9dfe..08eec4bddc 100644 --- a/src/lib-http/http-server-connection.c +++ b/src/lib-http/http-server-connection.c @@ -396,17 +396,33 @@ http_server_connection_handle_request(struct http_server_connection *conn, static int http_server_connection_ssl_init(struct http_server_connection *conn) { + struct http_server *server = conn->server; const char *error; + int ret; - if (conn->server->set.debug) + if (http_server_init_ssl_ctx(server, &error) < 0) { + http_server_connection_error(conn, + "Couldn't initialize SSL: %s", error); + return -1; + } + + if (server->set.debug) http_server_connection_debug(conn, "Starting SSL handshake"); http_server_connection_input_halt(conn); - if (master_service_ssl_init(master_service, - &conn->conn.input, &conn->conn.output, - &conn->ssl_iostream, &error) < 0) { + if (server->ssl_ctx == NULL) { + ret = master_service_ssl_init(master_service, + &conn->conn.input, &conn->conn.output, + &conn->ssl_iostream, &error); + } else { + ret = io_stream_create_ssl_server(server->ssl_ctx, + server->set.ssl, &conn->conn.input, &conn->conn.output, + &conn->ssl_iostream, &error); + } + if (ret < 0) { http_server_connection_error(conn, - "Couldn't initialize SSL server for %s: %s", conn->conn.name, error); + "Couldn't initialize SSL server for %s: %s", + conn->conn.name, error); return -1; } http_server_connection_input_resume(conn); diff --git a/src/lib-http/http-server-private.h b/src/lib-http/http-server-private.h index 2949661466..de95bf0cb0 100644 --- a/src/lib-http/http-server-private.h +++ b/src/lib-http/http-server-private.h @@ -276,4 +276,10 @@ int http_server_connection_discard_payload( bool http_server_connection_pending_payload( struct http_server_connection *conn); +/* + * Server + */ + +int http_server_init_ssl_ctx(struct http_server *server, const char **error_r); + #endif diff --git a/src/lib-http/http-server.c b/src/lib-http/http-server.c index fc5d95e650..747d424902 100644 --- a/src/lib-http/http-server.c +++ b/src/lib-http/http-server.c @@ -30,6 +30,10 @@ struct http_server *http_server_init(const struct http_server_settings *set) server->pool = pool; if (set->rawlog_dir != NULL && *set->rawlog_dir != '\0') server->set.rawlog_dir = p_strdup(pool, set->rawlog_dir); + if (set->ssl != NULL) { + server->set.ssl = + ssl_iostream_settings_dup(server->pool, set->ssl); + } server->set.max_client_idle_time_msecs = set->max_client_idle_time_msecs; server->set.max_pipelined_requests = (set->max_pipelined_requests > 0 ? set->max_pipelined_requests : 1); @@ -87,3 +91,19 @@ void http_server_shut_down(struct http_server *server) (void)http_server_connection_shut_down(conn); } } + +int http_server_init_ssl_ctx(struct http_server *server, const char **error_r) +{ + const char *error; + + if (server->set.ssl == NULL || server->ssl_ctx != NULL) + return 0; + + if (ssl_iostream_server_context_cache_get(server->set.ssl, + &server->ssl_ctx, &error) < 0) { + *error_r = t_strdup_printf("Couldn't initialize SSL context: %s", + error); + return -1; + } + return 0; +} diff --git a/src/lib-http/http-server.h b/src/lib-http/http-server.h index 6a94b38f8e..8e8009cf8d 100644 --- a/src/lib-http/http-server.h +++ b/src/lib-http/http-server.h @@ -21,6 +21,9 @@ struct http_server_response; struct http_server_settings { const char *rawlog_dir; + /* SSL settings; if NULL, master_service_ssl_init() is used instead */ + const struct ssl_iostream_settings *ssl; + /* The maximum time in milliseconds a client is allowed to be idle before it is disconnected. */ unsigned int max_client_idle_time_msecs;