From 71b5ad1df203c906d46960b0400564609b97a6c8 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 28 Oct 2009 21:20:46 -0400 Subject: [PATCH] *-login: Added support for TLS SNI. --HG-- branch : HEAD --- src/login-common/login-settings.c | 2 ++ src/login-common/login-settings.h | 1 + src/login-common/main.c | 4 +-- src/login-common/ssl-proxy-openssl.c | 44 ++++++++++++++++++++++++++-- 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/login-common/login-settings.c b/src/login-common/login-settings.c index e21870bf3e..42c38840c7 100644 --- a/src/login-common/login-settings.c +++ b/src/login-common/login-settings.c @@ -185,6 +185,7 @@ struct login_settings * login_settings_read(struct master_service *service, pool_t pool, const struct ip_addr *local_ip, const struct ip_addr *remote_ip, + const char *local_host, void ***other_settings_r) { struct master_service_settings_input input; @@ -196,6 +197,7 @@ login_settings_read(struct master_service *service, pool_t pool, input.roots = login_set_roots; input.module = login_process_name; input.service = login_protocol; + input.local_host = local_host; if (local_ip != NULL) input.local_ip = *local_ip; diff --git a/src/login-common/login-settings.h b/src/login-common/login-settings.h index 8e809877c8..c13ec0163b 100644 --- a/src/login-common/login-settings.h +++ b/src/login-common/login-settings.h @@ -39,6 +39,7 @@ struct login_settings * login_settings_read(struct master_service *service, pool_t pool, const struct ip_addr *local_ip, const struct ip_addr *remote_ip, + const char *local_host, void ***other_settings_r); #endif diff --git a/src/login-common/main.c b/src/login-common/main.c index e48abf7143..bba6c7cbd4 100644 --- a/src/login-common/main.c +++ b/src/login-common/main.c @@ -72,7 +72,7 @@ static void client_connected(const struct master_service_connection *conn) pool = pool_alloconly_create("login client", 3*1024); set = login_settings_read(master_service, pool, &local_ip, - &conn->remote_ip, &other_sets); + &conn->remote_ip, NULL, &other_sets); if (!ssl_connections && !conn->ssl) { client = client_create(conn->fd, FALSE, pool, set, other_sets, @@ -224,7 +224,7 @@ int main(int argc, char *argv[]) set_pool = pool_alloconly_create("global login settings", 4096); global_login_settings = - login_settings_read(master_service, set_pool, NULL, NULL, + login_settings_read(master_service, set_pool, NULL, NULL, NULL, &global_other_settings); /* main_preinit() needs to know the client limit, which is set by diff --git a/src/login-common/ssl-proxy-openssl.c b/src/login-common/ssl-proxy-openssl.c index eda9936cf5..5268ce6665 100644 --- a/src/login-common/ssl-proxy-openssl.c +++ b/src/login-common/ssl-proxy-openssl.c @@ -590,9 +590,8 @@ ssl_proxy_alloc_common(SSL_CTX *ssl_ctx, int fd, const struct ip_addr *ip, return sfd[1]; } -int ssl_proxy_alloc(int fd, const struct ip_addr *ip, - const struct login_settings *set, - struct ssl_proxy **proxy_r) +static struct ssl_server_context * +ssl_server_context_get(const struct login_settings *set) { struct ssl_server_context *ctx, lookup_ctx; @@ -606,7 +605,16 @@ int ssl_proxy_alloc(int fd, const struct ip_addr *ip, ctx = hash_table_lookup(ssl_servers, &lookup_ctx); if (ctx == NULL) ctx = ssl_server_context_init(set); + return ctx; +} + +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; + ctx = ssl_server_context_get(set); return ssl_proxy_alloc_common(ctx->ctx, fd, ip, set, proxy_r); } @@ -1007,6 +1015,28 @@ end: return ret; } +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME +static void ssl_servername_callback(SSL *ssl, int *al ATTR_UNUSED, + void *context ATTR_UNUSED) +{ + struct ssl_server_context *ctx; + struct ssl_proxy *proxy; + struct client *client; + const char *host; + void **other_sets; + + proxy = SSL_get_ex_data(ssl, extdata_index); + host = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); + + client = proxy->client; + client->set = login_settings_read(master_service, client->pool, + &client->local_ip, &client->ip, host, + &other_sets); + ctx = ssl_server_context_get(client->set); + SSL_set_SSL_CTX(ssl, ctx->ctx); +} +#endif + static struct ssl_server_context * ssl_server_context_init(const struct login_settings *set) { @@ -1038,6 +1068,14 @@ ssl_server_context_init(const struct login_settings *set) ssl_proxy_get_use_certificate_error(ctx->cert)); } +#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME + if (SSL_CTX_set_tlsext_servername_callback(ctx->ctx, + ssl_servername_callback) != 1) { + if (set->verbose_ssl) + i_debug("OpenSSL library doesn't support SNI"); + } +#endif + ssl_proxy_ctx_use_key(ctx->ctx, set); SSL_CTX_set_info_callback(ctx->ctx, ssl_info_callback); -- 2.47.3