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