Hello, I haven't seen any comment on this patch. Is it ok for you ? Kind regards. Franck.
2014-02-21 12:48 GMT+01:00 <[email protected]>: > # HG changeset patch > # User Franck Levionnois <[email protected]> > # Date 1390577176 -3600 > # Fri Jan 24 16:26:16 2014 +0100 > # Node ID 5c7ccfc96070fc8b5d775643d1e12c4e5a8b438f > # Parent 4dee5ad51e9e5b49085011e8785001e2d6c02b0d > Mail: added support for SSL client certificate. > > Add support for SSL Mutual Authentification like in mail module. > > Added mail configuration directives (like http): > ssl_verify_client, ssl_verify_depth, ssl_client_certificate, > ssl_trusted_certificate, ssl_crl. > > Added http auth headers: > Auth-Certificate, Auth-Verify, Auth-Issuer-DN, Auth-Subject-DN, > Auth-Subject-Serial. > > diff -r 4dee5ad51e9e -r 5c7ccfc96070 src/mail/ngx_mail_auth_http_module.c > --- a/src/mail/ngx_mail_auth_http_module.c Thu Feb 20 13:48:40 2014 > +0400 > +++ b/src/mail/ngx_mail_auth_http_module.c Fri Jan 24 16:26:16 2014 > +0100 > @@ -1143,6 +1143,9 @@ ngx_mail_auth_http_create_request(ngx_ma > size_t len; > ngx_buf_t *b; > ngx_str_t login, passwd; > +#if (NGX_MAIL_SSL) > + ngx_str_t cert, rawcert, verify, subject, issuer, > serial; > +#endif > ngx_mail_core_srv_conf_t *cscf; > > if (ngx_mail_auth_http_escape(pool, &s->login, &login) != NGX_OK) { > @@ -1155,6 +1158,45 @@ ngx_mail_auth_http_create_request(ngx_ma > > cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); > > +#if (NGX_MAIL_SSL) > + if (s->connection->ssl) { > + if (ngx_ssl_get_client_verify(s->connection, pool, &verify) != > NGX_OK) > + { > + return NULL; > + } > + > + if (ngx_ssl_get_subject_dn(s->connection, pool, > + &subject) != NGX_OK) { > + return NULL; > + } > + > + if (ngx_ssl_get_issuer_dn(s->connection, pool, > + &issuer) != NGX_OK) { > + return NULL; > + } > + > + if (ngx_ssl_get_serial_number(s->connection, pool, > + &serial) != NGX_OK) { > + return NULL; > + } > + > + if (ngx_ssl_get_raw_certificate(s->connection, pool, > + &rawcert) != NGX_OK) { > + return NULL; > + } > + > + if (ngx_mail_auth_http_escape(pool, &rawcert, &cert) != NGX_OK) { > + return NULL; > + } > + } else { > + verify.len = 0; > + issuer.len = 0; > + subject.len = 0; > + serial.len = 0; > + cert.len = 0; > + } > +#endif > + > len = sizeof("GET ") - 1 + ahcf->uri.len + sizeof(" HTTP/1.0" CRLF) - > 1 > + sizeof("Host: ") - 1 + ahcf->host_header.len + sizeof(CRLF) - > 1 > + sizeof("Auth-Method: ") - 1 > @@ -1163,6 +1205,14 @@ ngx_mail_auth_http_create_request(ngx_ma > + sizeof("Auth-User: ") - 1 + login.len + sizeof(CRLF) - 1 > + sizeof("Auth-Pass: ") - 1 + passwd.len + sizeof(CRLF) - 1 > + sizeof("Auth-Salt: ") - 1 + s->salt.len > +#if (NGX_MAIL_SSL) > + + sizeof("Auth-Certificate: ") - 1 + cert.len + sizeof(CRLF) - 1 > + + sizeof("Auth-Verify: ") - 1 + verify.len + sizeof(CRLF) - 1 > + + sizeof("Auth-Issuer-DN: ") - 1 + issuer.len + sizeof(CRLF) - 1 > + + sizeof("Auth-Subject-DN: ") - 1 + subject.len + sizeof(CRLF) > - 1 > + + sizeof("Auth-Subject-Serial: ") - 1 + serial.len > + + sizeof(CRLF) - 1 > +#endif > + sizeof("Auth-Protocol: ") - 1 + cscf->protocol->name.len > + sizeof(CRLF) - 1 > + sizeof("Auth-Login-Attempt: ") - 1 + NGX_INT_T_LEN > @@ -1213,6 +1263,44 @@ ngx_mail_auth_http_create_request(ngx_ma > s->passwd.data = NULL; > } > > +#if (NGX_MAIL_SSL) > + if (cert.len) { > + b->last = ngx_cpymem(b->last, "Auth-Certificate: ", > + sizeof("Auth-Certificate: ") - 1); > + b->last = ngx_copy(b->last, cert.data, cert.len); > + *b->last++ = CR; *b->last++ = LF; > + } > + > + if (verify.len) { > + b->last = ngx_cpymem(b->last, "Auth-Verify: ", > + sizeof("Auth-Verify: ") - 1); > + b->last = ngx_copy(b->last, verify.data, verify.len); > + *b->last++ = CR; *b->last++ = LF; > + } > + > + if (issuer.len) { > + b->last = ngx_cpymem(b->last, "Auth-Issuer-DN: ", > + sizeof("Auth-Issuer-DN: ") - 1); > + b->last = ngx_copy(b->last, issuer.data, issuer.len); > + *b->last++ = CR; *b->last++ = LF; > + } > + > + if (subject.len) { > + b->last = ngx_cpymem(b->last, "Auth-Subject-DN: ", > + sizeof("Auth-Subject-DN: ") - 1); > + b->last = ngx_copy(b->last, subject.data, subject.len); > + *b->last++ = CR; *b->last++ = LF; > + } > + > + if (serial.len) { > + b->last = ngx_cpymem(b->last, "Auth-Subject-Serial: ", > + sizeof("Auth-Subject-Serial: ") - 1); > + b->last = ngx_copy(b->last, serial.data, serial.len); > + *b->last++ = CR; *b->last++ = LF; > + } > + > +#endif > + > b->last = ngx_cpymem(b->last, "Auth-Protocol: ", > sizeof("Auth-Protocol: ") - 1); > b->last = ngx_cpymem(b->last, cscf->protocol->name.data, > diff -r 4dee5ad51e9e -r 5c7ccfc96070 src/mail/ngx_mail_handler.c > --- a/src/mail/ngx_mail_handler.c Thu Feb 20 13:48:40 2014 +0400 > +++ b/src/mail/ngx_mail_handler.c Fri Jan 24 16:26:16 2014 +0100 > @@ -236,11 +236,60 @@ ngx_mail_ssl_handshake_handler(ngx_conne > { > ngx_mail_session_t *s; > ngx_mail_core_srv_conf_t *cscf; > +#if (NGX_MAIL_SSL) > + ngx_mail_ssl_conf_t *sslcf; > +#endif > + > + ngx_log_debug1(NGX_LOG_DEBUG_MAIL, c->log, 0, > + "ngx_mail_ssl_handshake_handler handshaked: %d", > + c->ssl->handshaked); > > if (c->ssl->handshaked) { > > s = c->data; > > +#if (NGX_MAIL_SSL) > + sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); > + if (sslcf->verify) { > + long rc; > + > + rc = SSL_get_verify_result(c->ssl->connection); > + > + if (rc != X509_V_OK > + && (sslcf->verify != 3 || > !ngx_ssl_verify_error_optional(rc))) > + { > + ngx_log_error(NGX_LOG_INFO, c->log, 0, > + "client SSL certificate verify error: > (%l:%s)", > + rc, X509_verify_cert_error_string(rc)); > + > + ngx_ssl_remove_cached_session(sslcf->ssl.ctx, > + > (SSL_get0_session(c->ssl->connection))); > + > + ngx_mail_close_connection(c); > + return; > + } > + > + if (sslcf->verify == 1) { > + X509 *cert; > + cert = SSL_get_peer_certificate(c->ssl->connection); > + > + if (cert == NULL) { > + ngx_log_error(NGX_LOG_INFO, c->log, 0, > + "client sent no required SSL > certificate"); > + > + ngx_ssl_remove_cached_session(sslcf->ssl.ctx, > + > (SSL_get0_session(c->ssl->connection))); > + > + ngx_mail_close_connection(c); > + return; > + } > + > + X509_free(cert); > + } > + } > + > +#endif > + > if (s->starttls) { > cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); > > diff -r 4dee5ad51e9e -r 5c7ccfc96070 src/mail/ngx_mail_ssl_module.c > --- a/src/mail/ngx_mail_ssl_module.c Thu Feb 20 13:48:40 2014 +0400 > +++ b/src/mail/ngx_mail_ssl_module.c Fri Jan 24 16:26:16 2014 +0100 > @@ -43,6 +43,14 @@ static ngx_conf_bitmask_t ngx_mail_ssl_ > { ngx_null_string, 0 } > }; > > +static ngx_conf_enum_t ngx_mail_ssl_verify[] = { > + { ngx_string("off"), 0 }, > + { ngx_string("on"), 1 }, > + { ngx_string("optional"), 2 }, > + { ngx_string("optional_no_ca"), 3 }, > + { ngx_null_string, 0 } > +}; > + > > static ngx_command_t ngx_mail_ssl_commands[] = { > > @@ -102,6 +110,34 @@ static ngx_command_t ngx_mail_ssl_comma > offsetof(ngx_mail_ssl_conf_t, ciphers), > NULL }, > > + { ngx_string("ssl_verify_client"), > + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, > + ngx_conf_set_enum_slot, > + NGX_MAIL_SRV_CONF_OFFSET, > + offsetof(ngx_mail_ssl_conf_t, verify), > + &ngx_mail_ssl_verify }, > + > + { ngx_string("ssl_verify_depth"), > + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, > + ngx_conf_set_num_slot, > + NGX_MAIL_SRV_CONF_OFFSET, > + offsetof(ngx_mail_ssl_conf_t, verify_depth), > + NULL }, > + > + { ngx_string("ssl_client_certificate"), > + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, > + ngx_conf_set_str_slot, > + NGX_MAIL_SRV_CONF_OFFSET, > + offsetof(ngx_mail_ssl_conf_t, client_certificate), > + NULL }, > + > + { ngx_string("ssl_trusted_certificate"), > + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, > + ngx_conf_set_str_slot, > + NGX_MAIL_SRV_CONF_OFFSET, > + offsetof(ngx_mail_ssl_conf_t, trusted_certificate), > + NULL }, > + > { ngx_string("ssl_prefer_server_ciphers"), > NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_FLAG, > ngx_conf_set_flag_slot, > @@ -137,6 +173,13 @@ static ngx_command_t ngx_mail_ssl_comma > offsetof(ngx_mail_ssl_conf_t, session_timeout), > NULL }, > > + { ngx_string("ssl_crl"), > + NGX_MAIL_MAIN_CONF|NGX_MAIL_SRV_CONF|NGX_CONF_TAKE1, > + ngx_conf_set_str_slot, > + NGX_MAIL_SRV_CONF_OFFSET, > + offsetof(ngx_mail_ssl_conf_t, crl), > + NULL }, > + > ngx_null_command > }; > > @@ -189,6 +232,9 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf) > * scf->certificate_key = { 0, NULL }; > * scf->dhparam = { 0, NULL }; > * scf->ecdh_curve = { 0, NULL }; > + * scf->client_certificate = { 0, NULL }; > + * scf->trusted_certificate = { 0, NULL }; > + * scf->crl = { 0, NULL }; > * scf->ciphers = { 0, NULL }; > * scf->shm_zone = NULL; > */ > @@ -196,6 +242,8 @@ ngx_mail_ssl_create_conf(ngx_conf_t *cf) > scf->enable = NGX_CONF_UNSET; > scf->starttls = NGX_CONF_UNSET_UINT; > scf->prefer_server_ciphers = NGX_CONF_UNSET; > + scf->verify = NGX_CONF_UNSET_UINT; > + scf->verify_depth = NGX_CONF_UNSET_UINT; > scf->builtin_session_cache = NGX_CONF_UNSET; > scf->session_timeout = NGX_CONF_UNSET; > scf->session_tickets = NGX_CONF_UNSET; > @@ -228,11 +276,20 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, > (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1 > |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); > > + ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); > + ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); > + > ngx_conf_merge_str_value(conf->certificate, prev->certificate, ""); > ngx_conf_merge_str_value(conf->certificate_key, > prev->certificate_key, ""); > > ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, ""); > > + ngx_conf_merge_str_value(conf->client_certificate, > prev->client_certificate, > + ""); > + ngx_conf_merge_str_value(conf->trusted_certificate, > + prev->trusted_certificate, ""); > + ngx_conf_merge_str_value(conf->crl, prev->crl, ""); > + > ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve, > NGX_DEFAULT_ECDH_CURVE); > > @@ -318,6 +375,35 @@ ngx_mail_ssl_merge_conf(ngx_conf_t *cf, > return NGX_CONF_ERROR; > } > > + if (conf->verify) { > + > + if (conf->client_certificate.len == 0 && conf->verify != 3) { > + ngx_log_error(NGX_LOG_EMERG, cf->log, 0, > + "no ssl_client_certificate for > ssl_client_verify"); > + return NGX_CONF_ERROR; > + } > + > + if (ngx_ssl_client_certificate(cf, &conf->ssl, > + &conf->client_certificate, > + conf->verify_depth) > + != NGX_OK) > + { > + return NGX_CONF_ERROR; > + } > + } > + > + if (ngx_ssl_trusted_certificate(cf, &conf->ssl, > + &conf->trusted_certificate, > + conf->verify_depth) > + != NGX_OK) > + { > + return NGX_CONF_ERROR; > + } > + > + if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { > + return NGX_CONF_ERROR; > + } > + > if (conf->prefer_server_ciphers) { > SSL_CTX_set_options(conf->ssl.ctx, > SSL_OP_CIPHER_SERVER_PREFERENCE); > } > diff -r 4dee5ad51e9e -r 5c7ccfc96070 src/mail/ngx_mail_ssl_module.h > --- a/src/mail/ngx_mail_ssl_module.h Thu Feb 20 13:48:40 2014 +0400 > +++ b/src/mail/ngx_mail_ssl_module.h Fri Jan 24 16:26:16 2014 +0100 > @@ -28,6 +28,8 @@ typedef struct { > ngx_uint_t starttls; > ngx_uint_t protocols; > > + ngx_uint_t verify; > + ngx_uint_t verify_depth; > ssize_t builtin_session_cache; > > time_t session_timeout; > @@ -36,6 +38,9 @@ typedef struct { > ngx_str_t certificate_key; > ngx_str_t dhparam; > ngx_str_t ecdh_curve; > + ngx_str_t client_certificate; > + ngx_str_t trusted_certificate; > + ngx_str_t crl; > > ngx_str_t ciphers; > >
_______________________________________________ nginx-devel mailing list [email protected] http://mailman.nginx.org/mailman/listinfo/nginx-devel
