From cec3230c9b2a96bac1ea42c69475e8aea4b91eab Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 28 Oct 2009 21:17:53 -0400 Subject: [PATCH] ssl: Don't start handshake until client has been set. --HG-- branch : HEAD --- src/login-common/client-common.c | 5 ++-- src/login-common/login-proxy.c | 9 +++---- src/login-common/main.c | 4 +++- src/login-common/ssl-proxy-openssl.c | 35 ++++++++++++++-------------- src/login-common/ssl-proxy.c | 20 +++++++++------- src/login-common/ssl-proxy.h | 14 ++++++----- 6 files changed, 48 insertions(+), 39 deletions(-) diff --git a/src/login-common/client-common.c b/src/login-common/client-common.c index 913a834859..18da8d81a6 100644 --- a/src/login-common/client-common.c +++ b/src/login-common/client-common.c @@ -254,8 +254,8 @@ static void client_start_tls(struct client *client) if (!client_unref(&client) || client->destroyed) return; - fd_ssl = ssl_proxy_new(client->fd, &client->ip, - client->set, &client->ssl_proxy); + fd_ssl = ssl_proxy_alloc(client->fd, &client->ip, + client->set, &client->ssl_proxy); if (fd_ssl == -1) { client_send_line(client, CLIENT_CMD_REPLY_BYE, "TLS initialization failed."); @@ -264,6 +264,7 @@ static void client_start_tls(struct client *client) return; } ssl_proxy_set_client(client->ssl_proxy, client); + ssl_proxy_start(client->ssl_proxy); client->starttls = TRUE; client->tls = TRUE; diff --git a/src/login-common/login-proxy.c b/src/login-common/login-proxy.c index 7b405fc51e..20cabf34fa 100644 --- a/src/login-common/login-proxy.c +++ b/src/login-common/login-proxy.c @@ -423,10 +423,10 @@ int login_proxy_starttls(struct login_proxy *proxy) o_stream_destroy(&proxy->server_output); io_remove(&proxy->server_io); - fd = ssl_proxy_client_new(proxy->server_fd, &proxy->client->ip, - proxy->client->set, - login_proxy_ssl_handshaked, proxy, - &proxy->ssl_server_proxy); + fd = ssl_proxy_client_alloc(proxy->server_fd, &proxy->client->ip, + proxy->client->set, + login_proxy_ssl_handshaked, proxy, + &proxy->ssl_server_proxy); if (fd < 0) { client_log_err(proxy->client, t_strdup_printf( "proxy: SSL handshake failed to %s:%u", @@ -434,6 +434,7 @@ int login_proxy_starttls(struct login_proxy *proxy) return -1; } ssl_proxy_set_client(proxy->ssl_server_proxy, proxy->client); + ssl_proxy_start(proxy->ssl_server_proxy); proxy->server_fd = fd; proxy_plain_connected(proxy); diff --git a/src/login-common/main.c b/src/login-common/main.c index c126064d7a..e48abf7143 100644 --- a/src/login-common/main.c +++ b/src/login-common/main.c @@ -78,7 +78,8 @@ static void client_connected(const struct master_service_connection *conn) client = client_create(conn->fd, FALSE, pool, set, other_sets, &local_ip, &conn->remote_ip); } else { - fd_ssl = ssl_proxy_new(conn->fd, &conn->remote_ip, set, &proxy); + fd_ssl = ssl_proxy_alloc(conn->fd, &conn->remote_ip, set, + &proxy); if (fd_ssl == -1) { net_disconnect(conn->fd); pool_unref(&pool); @@ -89,6 +90,7 @@ static void client_connected(const struct master_service_connection *conn) &local_ip, &conn->remote_ip); client->ssl_proxy = proxy; ssl_proxy_set_client(proxy, client); + ssl_proxy_start(proxy); } client->remote_port = conn->remote_port; diff --git a/src/login-common/ssl-proxy-openssl.c b/src/login-common/ssl-proxy-openssl.c index 0a7a12cf63..eda9936cf5 100644 --- a/src/login-common/ssl-proxy-openssl.c +++ b/src/login-common/ssl-proxy-openssl.c @@ -533,9 +533,9 @@ static void ssl_step(struct ssl_proxy *proxy) } static int -ssl_proxy_new_common(SSL_CTX *ssl_ctx, int fd, const struct ip_addr *ip, - const struct login_settings *set, - struct ssl_proxy **proxy_r) +ssl_proxy_alloc_common(SSL_CTX *ssl_ctx, int fd, const struct ip_addr *ip, + const struct login_settings *set, + struct ssl_proxy **proxy_r) { struct ssl_proxy *proxy; SSL *ssl; @@ -590,11 +590,11 @@ ssl_proxy_new_common(SSL_CTX *ssl_ctx, int fd, const struct ip_addr *ip, return sfd[1]; } -int ssl_proxy_new(int fd, const struct ip_addr *ip, - const struct login_settings *set, struct ssl_proxy **proxy_r) +int ssl_proxy_alloc(int fd, const struct ip_addr *ip, + const struct login_settings *set, + struct ssl_proxy **proxy_r) { struct ssl_server_context *ctx, lookup_ctx; - int ret; memset(&lookup_ctx, 0, sizeof(lookup_ctx)); lookup_ctx.cert = set->ssl_cert; @@ -607,32 +607,31 @@ int ssl_proxy_new(int fd, const struct ip_addr *ip, if (ctx == NULL) ctx = ssl_server_context_init(set); - ret = ssl_proxy_new_common(ctx->ctx, fd, ip, set, proxy_r); - if (ret < 0) - return -1; - - ssl_step(*proxy_r); - return ret; + return ssl_proxy_alloc_common(ctx->ctx, fd, ip, set, proxy_r); } -int ssl_proxy_client_new(int fd, struct ip_addr *ip, - const struct login_settings *set, - ssl_handshake_callback_t *callback, void *context, - struct ssl_proxy **proxy_r) +int ssl_proxy_client_alloc(int fd, struct ip_addr *ip, + const struct login_settings *set, + ssl_handshake_callback_t *callback, void *context, + struct ssl_proxy **proxy_r) { int ret; - ret = ssl_proxy_new_common(ssl_client_ctx, fd, ip, set, proxy_r); + ret = ssl_proxy_alloc_common(ssl_client_ctx, fd, ip, set, proxy_r); if (ret < 0) return -1; (*proxy_r)->handshake_callback = callback; (*proxy_r)->handshake_context = context; (*proxy_r)->client_proxy = TRUE; - ssl_step(*proxy_r); return ret; } +void ssl_proxy_start(struct ssl_proxy *proxy) +{ + ssl_step(proxy); +} + void ssl_proxy_set_client(struct ssl_proxy *proxy, struct client *client) { i_assert(proxy->client == NULL); diff --git a/src/login-common/ssl-proxy.c b/src/login-common/ssl-proxy.c index d4d4443103..0ae72ff62d 100644 --- a/src/login-common/ssl-proxy.c +++ b/src/login-common/ssl-proxy.c @@ -9,24 +9,28 @@ bool ssl_initialized = FALSE; /* no SSL support */ -int ssl_proxy_new(int fd ATTR_UNUSED, const struct ip_addr *ip ATTR_UNUSED, - const struct login_settings *set ATTR_UNUSED, - struct ssl_proxy **proxy_r ATTR_UNUSED) +int ssl_proxy_alloc(int fd ATTR_UNUSED, const struct ip_addr *ip ATTR_UNUSED, + const struct login_settings *set ATTR_UNUSED, + struct ssl_proxy **proxy_r ATTR_UNUSED) { i_error("Dovecot wasn't built with SSL support"); return -1; } -int ssl_proxy_client_new(int fd ATTR_UNUSED, struct ip_addr *ip ATTR_UNUSED, - const struct login_settings *set ATTR_UNUSED, - ssl_handshake_callback_t *callback ATTR_UNUSED, - void *context ATTR_UNUSED, - struct ssl_proxy **proxy_r ATTR_UNUSED) +int ssl_proxy_client_alloc(int fd ATTR_UNUSED, struct ip_addr *ip ATTR_UNUSED, + const struct login_settings *set ATTR_UNUSED, + ssl_handshake_callback_t *callback ATTR_UNUSED, + void *context ATTR_UNUSED, + struct ssl_proxy **proxy_r ATTR_UNUSED) { i_error("Dovecot wasn't built with SSL support"); return -1; } +void ssl_proxy_start(struct ssl_proxy *proxy ATTR_UNUSED) +{ +} + void ssl_proxy_set_client(struct ssl_proxy *proxy ATTR_UNUSED, struct client *client ATTR_UNUSED) { diff --git a/src/login-common/ssl-proxy.h b/src/login-common/ssl-proxy.h index 0c99428986..7bf58c7a0f 100644 --- a/src/login-common/ssl-proxy.h +++ b/src/login-common/ssl-proxy.h @@ -13,12 +13,14 @@ typedef int ssl_handshake_callback_t(void *context); /* establish SSL connection with the given fd, returns a new fd which you must use from now on, or -1 if error occurred. Unless -1 is returned, the given fd must be simply forgotten. */ -int ssl_proxy_new(int fd, const struct ip_addr *ip, - const struct login_settings *set, struct ssl_proxy **proxy_r); -int ssl_proxy_client_new(int fd, struct ip_addr *ip, - const struct login_settings *set, - ssl_handshake_callback_t *callback, void *context, - struct ssl_proxy **proxy_r); +int ssl_proxy_alloc(int fd, const struct ip_addr *ip, + const struct login_settings *set, + struct ssl_proxy **proxy_r); +int ssl_proxy_client_alloc(int fd, struct ip_addr *ip, + const struct login_settings *set, + ssl_handshake_callback_t *callback, void *context, + struct ssl_proxy **proxy_r); +void ssl_proxy_start(struct ssl_proxy *proxy); void ssl_proxy_set_client(struct ssl_proxy *proxy, struct client *client); bool ssl_proxy_has_valid_client_cert(const struct ssl_proxy *proxy) ATTR_PURE; bool ssl_proxy_has_broken_client_cert(struct ssl_proxy *proxy); -- 2.47.3