Mercurial > hg > nginx
comparison src/mail/ngx_mail_handler.c @ 5989:ec01b1d1fff1
Mail: client SSL certificates support.
The "ssl_verify_client", "ssl_verify_depth", "ssl_client_certificate",
"ssl_trusted_certificate", and "ssl_crl" directives introduced to control
SSL client certificate verification in mail proxy module.
If there is a certificate, detail of the certificate are passed to
the auth_http script configured via Auth-SSL-Verify, Auth-SSL-Subject,
Auth-SSL-Issuer, Auth-SSL-Serial, Auth-SSL-Fingerprint headers. If
the auth_http_pass_client_cert directive is set, client certificate
in PEM format will be passed in the Auth-SSL-Cert header (urlencoded).
If there is no required certificate provided during an SSL handshake
or certificate verification fails then a protocol-specific error is
returned after the SSL handshake and the connection is closed.
Based on previous work by Sven Peter, Franck Levionnois and Filipe Da Silva.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 25 Feb 2015 17:48:05 +0300 |
parents | 8e7ee4c70a3c |
children | fc99323a3d79 |
comparison
equal
deleted
inserted
replaced
5988:3b3f789655dc | 5989:ec01b1d1fff1 |
---|---|
14 static void ngx_mail_init_session(ngx_connection_t *c); | 14 static void ngx_mail_init_session(ngx_connection_t *c); |
15 | 15 |
16 #if (NGX_MAIL_SSL) | 16 #if (NGX_MAIL_SSL) |
17 static void ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); | 17 static void ngx_mail_ssl_init_connection(ngx_ssl_t *ssl, ngx_connection_t *c); |
18 static void ngx_mail_ssl_handshake_handler(ngx_connection_t *c); | 18 static void ngx_mail_ssl_handshake_handler(ngx_connection_t *c); |
19 static ngx_int_t ngx_mail_verify_cert(ngx_mail_session_t *s, | |
20 ngx_connection_t *c); | |
19 #endif | 21 #endif |
20 | 22 |
21 | 23 |
22 void | 24 void |
23 ngx_mail_init_connection(ngx_connection_t *c) | 25 ngx_mail_init_connection(ngx_connection_t *c) |
245 | 247 |
246 if (c->ssl->handshaked) { | 248 if (c->ssl->handshaked) { |
247 | 249 |
248 s = c->data; | 250 s = c->data; |
249 | 251 |
252 if (ngx_mail_verify_cert(s, c) != NGX_OK) { | |
253 return; | |
254 } | |
255 | |
250 if (s->starttls) { | 256 if (s->starttls) { |
251 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | 257 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); |
252 | 258 |
253 c->read->handler = cscf->protocol->init_protocol; | 259 c->read->handler = cscf->protocol->init_protocol; |
254 c->write->handler = ngx_mail_send; | 260 c->write->handler = ngx_mail_send; |
263 ngx_mail_init_session(c); | 269 ngx_mail_init_session(c); |
264 return; | 270 return; |
265 } | 271 } |
266 | 272 |
267 ngx_mail_close_connection(c); | 273 ngx_mail_close_connection(c); |
274 } | |
275 | |
276 | |
277 static ngx_int_t | |
278 ngx_mail_verify_cert(ngx_mail_session_t *s, ngx_connection_t *c) | |
279 { | |
280 long rc; | |
281 X509 *cert; | |
282 ngx_mail_ssl_conf_t *sslcf; | |
283 ngx_mail_core_srv_conf_t *cscf; | |
284 | |
285 sslcf = ngx_mail_get_module_srv_conf(s, ngx_mail_ssl_module); | |
286 | |
287 if (!sslcf->verify) { | |
288 return NGX_OK; | |
289 } | |
290 | |
291 rc = SSL_get_verify_result(c->ssl->connection); | |
292 | |
293 if (rc != X509_V_OK | |
294 && (sslcf->verify != 3 || !ngx_ssl_verify_error_optional(rc))) | |
295 { | |
296 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
297 "client SSL certificate verify error: (%l:%s)", | |
298 rc, X509_verify_cert_error_string(rc)); | |
299 | |
300 ngx_ssl_remove_cached_session(sslcf->ssl.ctx, | |
301 (SSL_get0_session(c->ssl->connection))); | |
302 | |
303 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
304 | |
305 s->out = cscf->protocol->cert_error; | |
306 s->quit = 1; | |
307 | |
308 c->write->handler = ngx_mail_send; | |
309 | |
310 ngx_mail_send(s->connection->write); | |
311 return NGX_ERROR; | |
312 } | |
313 | |
314 if (sslcf->verify == 1) { | |
315 cert = SSL_get_peer_certificate(c->ssl->connection); | |
316 | |
317 if (cert == NULL) { | |
318 ngx_log_error(NGX_LOG_INFO, c->log, 0, | |
319 "client sent no required SSL certificate"); | |
320 | |
321 ngx_ssl_remove_cached_session(sslcf->ssl.ctx, | |
322 (SSL_get0_session(c->ssl->connection))); | |
323 | |
324 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
325 | |
326 s->out = cscf->protocol->no_cert; | |
327 s->quit = 1; | |
328 | |
329 c->write->handler = ngx_mail_send; | |
330 | |
331 ngx_mail_send(s->connection->write); | |
332 return NGX_ERROR; | |
333 } | |
334 | |
335 X509_free(cert); | |
336 } | |
337 | |
338 return NGX_OK; | |
268 } | 339 } |
269 | 340 |
270 #endif | 341 #endif |
271 | 342 |
272 | 343 |