From: Timo Sirainen Date: Thu, 4 Apr 2013 09:48:52 +0000 (+0300) Subject: lib-http: Each peer doesn't need a separate ssl context, enough to have one for http_... X-Git-Tag: 2.2.rc4~38 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=415e16c3dc185578695b7d88e561a52de6c8b1b1;p=thirdparty%2Fdovecot%2Fcore.git lib-http: Each peer doesn't need a separate ssl context, enough to have one for http_client. Also removed #ifdefs for building with SSL support. lib-ssl-iostream nowadays dynamically loads the SSL library when needed, and also handles failures if Dovecot was built without SSL support. --- diff --git a/src/lib-http/http-client-connection.c b/src/lib-http/http-client-connection.c index 61d0713728..31ddbaef96 100644 --- a/src/lib-http/http-client-connection.c +++ b/src/lib-http/http-client-connection.c @@ -651,7 +651,6 @@ http_client_connection_ready(struct http_client_connection *conn) (void)http_client_connection_next_request(conn); } -#ifdef HTTP_BUILD_SSL static int http_client_connection_ssl_handshaked(void *context) { struct http_client_connection *conn = context; @@ -689,7 +688,7 @@ http_client_connection_ssl_init(struct http_client_connection *conn) struct ssl_iostream_settings ssl_set; const char *source; - if (conn->peer->ssl_ctx == NULL) { + if (conn->client->ssl_ctx == NULL) { http_client_connection_error(conn, "No SSL context"); return -1; } @@ -706,7 +705,7 @@ http_client_connection_ssl_init(struct http_client_connection *conn) source = t_strdup_printf ("connection %s: ", http_client_connection_label(conn)); - if (io_stream_create_ssl(conn->peer->ssl_ctx, source, &ssl_set, + if (io_stream_create_ssl(conn->client->ssl_ctx, source, &ssl_set, &conn->conn.input, &conn->conn.output, &conn->ssl_iostream) < 0) { http_client_connection_error(conn, "Couldn't initialize SSL client"); return -1; @@ -722,7 +721,6 @@ http_client_connection_ssl_init(struct http_client_connection *conn) http_client_connection_ready(conn); return 0; } -#endif static void http_client_connection_connected(struct connection *_conn, bool success) @@ -736,13 +734,11 @@ http_client_connection_connected(struct connection *_conn, bool success) } else { http_client_connection_debug(conn, "Connected"); -#ifdef HTTP_BUILD_SSL if (conn->peer->addr.ssl) { if (http_client_connection_ssl_init(conn) < 0) http_client_peer_connection_failure(conn->peer); return; } -#endif http_client_connection_ready(conn); } } @@ -829,10 +825,8 @@ void http_client_connection_unref(struct http_client_connection **_conn) conn->closing = TRUE; conn->connected = FALSE; -#ifdef HTTP_BUILD_SSL if (conn->ssl_iostream != NULL) ssl_iostream_unref(&conn->ssl_iostream); -#endif connection_deinit(&conn->conn); diff --git a/src/lib-http/http-client-host.c b/src/lib-http/http-client-host.c index c4bd885e93..b0fc8533d8 100644 --- a/src/lib-http/http-client-host.c +++ b/src/lib-http/http-client-host.c @@ -118,6 +118,17 @@ http_client_host_connection_setup(struct http_client_host *host, { struct http_client_peer *peer = NULL; struct http_client_peer_addr addr; + const char *error; + + if (hport->ssl && host->client->ssl_ctx == NULL) { + if (http_client_init_ssl_ctx(host->client, &error) < 0) { + http_client_host_port_error(hport, + HTTP_CLIENT_REQUEST_ERROR_CONNECT_FAILED, error); + if (host->client->ioloop != NULL) + io_loop_stop(host->client->ioloop); + return; + } + } while (hport->ips_connect_idx < host->ips_count) { addr.ip = host->ips[hport->ips_connect_idx]; diff --git a/src/lib-http/http-client-peer.c b/src/lib-http/http-client-peer.c index d805a84634..ab806af5ec 100644 --- a/src/lib-http/http-client-peer.c +++ b/src/lib-http/http-client-peer.c @@ -207,9 +207,8 @@ http_client_peer_create(struct http_client *client, const struct http_client_peer_addr *addr) { struct http_client_peer *peer; -#ifdef HTTP_BUILD_SSL - struct ssl_iostream_settings ssl_set; -#endif + + i_assert(!addr->ssl || client->ssl_ctx != NULL); peer = i_new(struct http_client_peer, 1); peer->client = client; @@ -223,32 +222,6 @@ http_client_peer_create(struct http_client *client, http_client_peer_debug(peer, "Peer created"); -#ifdef HTTP_BUILD_SSL - if (peer->addr.ssl && peer->ssl_ctx == NULL) { - const char *source; - memset(&ssl_set, 0, sizeof(ssl_set)); - ssl_set.ca_dir = peer->client->set.ssl_ca_dir; - ssl_set.ca = peer->client->set.ssl_ca; - ssl_set.verify_remote_cert = TRUE; - ssl_set.crypto_device = peer->client->set.ssl_crypto_device; - - source = t_strdup_printf("http-client: peer %s:%u", - net_ip2addr(&peer->addr.ip), peer->addr.port); - if (ssl_iostream_context_init_client - (source, &ssl_set, &peer->ssl_ctx) < 0) { - http_client_peer_error(peer, "Couldn't initialize SSL context"); - http_client_peer_free(&peer); - return NULL; - } - } -#else - if (peer->addr.ssl) { - http_client_peer_error(peer, "HTTPS is not supported"); - http_client_peer_free(&peer); - return NULL; - } -#endif - if (http_client_peer_connect(peer, 1) < 0) { http_client_peer_free(&peer); return NULL; @@ -281,11 +254,6 @@ void http_client_peer_free(struct http_client_peer **_peer) array_free(&peer->conns); array_free(&peer->hosts); -#ifdef HTTP_BUILD_SSL - if (peer->ssl_ctx != NULL) - ssl_iostream_context_deinit(&peer->ssl_ctx); -#endif - hash_table_remove (peer->client->peers, (const struct http_client_peer_addr *)&peer->addr); DLLIST_REMOVE(&peer->client->peers_list, peer); diff --git a/src/lib-http/http-client-private.h b/src/lib-http/http-client-private.h index 6c2ef75ae6..6002935ad8 100644 --- a/src/lib-http/http-client-private.h +++ b/src/lib-http/http-client-private.h @@ -5,8 +5,6 @@ #include "http-client.h" -#define HTTP_BUILD_SSL - #define HTTP_DEFAULT_PORT 80 #define HTTPS_DEFAULT_PORT 443 @@ -113,11 +111,6 @@ struct http_client_peer { /* active connections to this peer */ ARRAY_TYPE(http_client_connection) conns; - /* ssl */ -#ifdef HTTP_BUILD_SSL - struct ssl_iostream_context *ssl_ctx; -#endif - unsigned int destroyed:1; /* peer is being destroyed */ unsigned int no_payload_sync:1; /* expect: 100-continue failed before */ unsigned int last_connect_failed:1; @@ -133,11 +126,7 @@ struct http_client_connection { unsigned int id; // DEBUG: identify parallel connections - /* ssl */ -#ifdef HTTP_BUILD_SSL struct ssl_iostream *ssl_iostream; -#endif - struct http_response_parser *http_parser; struct timeout *to_input, *to_idle, *to_response; @@ -161,6 +150,7 @@ struct http_client { struct http_client_settings set; struct ioloop *ioloop; + struct ssl_iostream_context *ssl_ctx; struct connection_list *conn_list; @@ -185,6 +175,8 @@ http_client_connection_label(struct http_client_connection *conn) net_ip2addr(&conn->conn.ip), conn->conn.port, conn->id); } +int http_client_init_ssl_ctx(struct http_client *client, const char **error_r); + void http_client_request_ref(struct http_client_request *req); void http_client_request_unref(struct http_client_request **_req); int http_client_request_send(struct http_client_request *req, diff --git a/src/lib-http/http-client.c b/src/lib-http/http-client.c index 4d9895ec65..dc134d86bc 100644 --- a/src/lib-http/http-client.c +++ b/src/lib-http/http-client.c @@ -122,6 +122,9 @@ void http_client_deinit(struct http_client **_client) hash_table_destroy(&client->hosts); connection_list_deinit(&client->conn_list); + + if (client->ssl_ctx != NULL) + ssl_iostream_context_deinit(&client->ssl_ctx); pool_unref(&client->pool); *_client = NULL; } @@ -180,3 +183,23 @@ void http_client_wait(struct http_client *client) io_loop_destroy(&client->ioloop); } +int http_client_init_ssl_ctx(struct http_client *client, const char **error_r) +{ + struct ssl_iostream_settings ssl_set; + + if (client->ssl_ctx != NULL) + return 0; + + memset(&ssl_set, 0, sizeof(ssl_set)); + ssl_set.ca_dir = client->set.ssl_ca_dir; + ssl_set.ca = client->set.ssl_ca; + ssl_set.verify_remote_cert = TRUE; + ssl_set.crypto_device = client->set.ssl_crypto_device; + + if (ssl_iostream_context_init_client("lib-http", &ssl_set, + &client->ssl_ctx) < 0) { + *error_r = "Couldn't initialize SSL context"; + return -1; + } + return 0; +}