[PATCH] SSL support for the mail proxy module

Kunal Pariani kpariani at zimbra.com
Tue Aug 19 22:58:15 UTC 2014



# HG changeset patch 

# User Kunal Pariani <kpariani at zimbra.com> 

# 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 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.nginx.org/pipermail/nginx-devel/attachments/20140819/9d614093/attachment-0001.html>


More information about the nginx-devel mailing list