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);
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);
(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;
+}
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;