[PATCH] SSL support for the mail proxy module

Quanah Gibson-Mount quanah at zimbra.com
Mon Sep 8 17:19:17 UTC 2014


--On Friday, August 22, 2014 5:13 PM -0500 Kunal Pariani 
<kpariani at zimbra.com> wrote:

>
>
> Any comments on this yet ?

Any nginx developers who could comment on this?

--Quanah


> __________________________________________________
>
> From: "Kunal Pariani" <kpariani at zimbra.com>
> To: "nginx-devel" <nginx-devel at nginx.org>
> Sent: Tuesday, August 19, 2014 3:58:15 PM
> Subject: [PATCH] SSL support for the mail proxy module
>
>
>
>
>
># 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
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel



--

Quanah Gibson-Mount
Server Architect
Zimbra, Inc.
--------------------
Zimbra ::  the leader in open source messaging and collaboration



More information about the nginx-devel mailing list