Any comments on this yet ? Thanks -Kunal
From: "Kunal Pariani" <[email protected]> To: "nginx-devel" <[email protected]> Sent: Tuesday, August 19, 2014 3:58:15 PM Subject: [PATCH] SSL support for the mail proxy module # HG changeset patch # User Kunal Pariani <[email protected]> # Date 1408485440 25200 # Tue Aug 19 14:57:20 2014 -0700 # Node ID 7858c2a9ac0e83aa779197fc028b4d078612e7e8 # Parent f25ab24517bb5e45b1b7fa1a1502b907f2cff213 SSL support for the mail proxy diff -r f25ab24517bb -r 7858c2a9ac0e src/mail/ngx_mail_proxy_module.c --- a/src/mail/ngx_mail_proxy_module.c Mon Aug 04 16:26:30 2014 -0700 +++ b/src/mail/ngx_mail_proxy_module.c Tue Aug 19 14:57:20 2014 -0700 @@ -18,6 +18,8 @@ ngx_flag_t xclient; size_t buffer_size; ngx_msec_t timeout; + ngx_flag_t proxy_ssl; + ngx_ssl_t *ssl; } ngx_mail_proxy_conf_t; @@ -35,7 +37,13 @@ static void *ngx_mail_proxy_create_conf(ngx_conf_t *cf); static char *ngx_mail_proxy_merge_conf(ngx_conf_t *cf, void *parent, void *child); - +#if (NGX_MAIL_SSL) +static char *ngx_mail_proxy_ssl(ngx_conf_t *cf, ngx_command_t *cmd, + void *conf); +static void ngx_mail_proxy_ssl_init_connection(ngx_mail_session_t *s, + ngx_connection_t *c); +static void ngx_mail_proxy_ssl_handshake(ngx_connection_t *c); +#endif static ngx_command_t ngx_mail_proxy_commands[] = { @@ -74,6 +82,16 @@ offsetof(ngx_mail_proxy_conf_t, xclient), NULL }, +#if (NGX_MAIL_SSL) + { ngx_string("proxy_ssl"), + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, + ngx_mail_proxy_ssl, + NGX_MAIL_SRV_CONF_OFFSET, + offsetof(ngx_mail_proxy_conf_t, proxy_ssl), + NULL }, + +#endif + ngx_null_command }; @@ -174,6 +192,15 @@ s->out.len = 0; +#if (NGX_MAIL_SSL) + + if (pcf->proxy_ssl && p->upstream.connection->ssl == NULL) { + ngx_mail_proxy_ssl_init_connection(s, p->upstream.connection); + return; + } + +#endif + switch (s->protocol) { case NGX_MAIL_POP3_PROTOCOL: @@ -1092,6 +1119,13 @@ "close mail proxy connection: %d", s->proxy->upstream.connection->fd); +#if (NGX_MAIL_SSL) + if (s->proxy->upstream.connection->ssl) { + s->proxy->upstream.connection->ssl->no_wait_shutdown = 1; + ngx_ssl_shutdown(s->proxy->upstream.connection); + } +#endif + ngx_close_connection(s->proxy->upstream.connection); } @@ -1114,6 +1148,8 @@ pcf->xclient = NGX_CONF_UNSET; pcf->buffer_size = NGX_CONF_UNSET_SIZE; pcf->timeout = NGX_CONF_UNSET_MSEC; + pcf->proxy_ssl = NGX_CONF_UNSET; + pcf->ssl = NGX_CONF_UNSET_PTR; return pcf; } @@ -1131,6 +1167,118 @@ ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, (size_t) ngx_pagesize); ngx_conf_merge_msec_value(conf->timeout, prev->timeout, 24 * 60 * 60000); + ngx_conf_merge_value(conf->proxy_ssl, prev->proxy_ssl, 0); + ngx_conf_merge_ptr_value(conf->ssl, prev->ssl, NULL); return NGX_CONF_OK; } + +#if (NGX_MAIL_SSL) + +static char * +ngx_mail_proxy_ssl(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) { + + ngx_pool_cleanup_t *cln; + char *rc; + ngx_mail_proxy_conf_t *pcf; + + rc = ngx_conf_set_flag_slot(cf, cmd, conf); + if (rc != NGX_CONF_OK) { + return rc; + } + + pcf = (ngx_mail_proxy_conf_t *)conf; + + if (!pcf->proxy_ssl) { + return NGX_CONF_OK; + } + + pcf->ssl = ngx_pcalloc(cf->pool, sizeof(ngx_ssl_t)); + + if (pcf->ssl == NULL) { + return NGX_CONF_ERROR; + } + + pcf->ssl->log = cf->log; + + // don't support SSLv2 anymore + if (ngx_ssl_create(pcf->ssl, NGX_SSL_SSLv3|NGX_SSL_TLSv1, NULL) + != NGX_OK) { + return NGX_CONF_ERROR; + } + + cln = ngx_pool_cleanup_add(cf->pool, 0); + if (cln == NULL) { + return NGX_CONF_ERROR; + } + + cln->handler = ngx_ssl_cleanup_ctx; + cln->data = pcf->ssl; + + return NGX_CONF_OK; +} + +static void +ngx_mail_proxy_ssl_init_connection(ngx_mail_session_t *s, ngx_connection_t *c) +{ + ngx_int_t rc; + ngx_mail_proxy_conf_t *pcf; + + pcf = ngx_mail_get_module_srv_conf(s, ngx_mail_proxy_module); + + if (ngx_ssl_create_connection(pcf->ssl, c, + NGX_SSL_BUFFER|NGX_SSL_CLIENT) + != NGX_OK) + { + ngx_mail_proxy_internal_server_error(s); + return; + } + + s->connection->log->action = "SSL handshaking to upstream"; + + rc = ngx_ssl_handshake(c); + + if (rc == NGX_AGAIN) { + c->ssl->handler = ngx_mail_proxy_ssl_handshake; + return; + } + + ngx_mail_proxy_ssl_handshake(c); +} + + +static void +ngx_mail_proxy_ssl_handshake(ngx_connection_t *c) +{ + ngx_mail_session_t *s; + s = c->data; + + if (c->ssl->handshaked) { + c->write->handler = ngx_mail_proxy_dummy_handler; + switch (s->protocol) { + + case NGX_MAIL_POP3_PROTOCOL: + c->read->handler = ngx_mail_proxy_pop3_handler; + s->mail_state = ngx_pop3_start; + break; + + case NGX_MAIL_IMAP_PROTOCOL: + c->read->handler = ngx_mail_proxy_imap_handler; + s->mail_state = ngx_imap_start; + break; + + default: /* NGX_MAIL_SMTP_PROTOCOL */ + c->read->handler = ngx_mail_proxy_smtp_handler; + s->mail_state = ngx_smtp_start; + break; + } + + /* server might have sent the initial welcome msg */ + c->read->handler(c->read); + } else { + /* when handshake fails, we should close the session */ + ngx_mail_proxy_upstream_error(s); + } +} + +#endif Thanks -Kunal _______________________________________________ nginx-devel mailing list [email protected] http://mailman.nginx.org/mailman/listinfo/nginx-devel
_______________________________________________ nginx-devel mailing list [email protected] http://mailman.nginx.org/mailman/listinfo/nginx-devel
