Mercurial > hg > nginx
comparison src/mail/ngx_mail_ssl_module.c @ 7938:dc955d274130
Mail: connections with wrong ALPN protocols are now rejected.
This is a recommended behavior by RFC 7301 and is useful
for mitigation of protocol confusion attacks [1].
For POP3 and IMAP protocols IANA-assigned ALPN IDs are used [2].
For the SMTP protocol "smtp" is used.
[1] https://alpaca-attack.com/
[2] https://www.iana.org/assignments/tls-extensiontype-values/
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 20 Oct 2021 09:45:34 +0300 |
parents | 419c066cb710 |
children | e32b48848add |
comparison
equal
deleted
inserted
replaced
7937:db6b630e6086 | 7938:dc955d274130 |
---|---|
11 | 11 |
12 | 12 |
13 #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" | 13 #define NGX_DEFAULT_CIPHERS "HIGH:!aNULL:!MD5" |
14 #define NGX_DEFAULT_ECDH_CURVE "auto" | 14 #define NGX_DEFAULT_ECDH_CURVE "auto" |
15 | 15 |
16 | |
17 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation | |
18 static int ngx_mail_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, | |
19 const unsigned char **out, unsigned char *outlen, | |
20 const unsigned char *in, unsigned int inlen, void *arg); | |
21 #endif | |
16 | 22 |
17 static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf); | 23 static void *ngx_mail_ssl_create_conf(ngx_conf_t *cf); |
18 static char *ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child); | 24 static char *ngx_mail_ssl_merge_conf(ngx_conf_t *cf, void *parent, void *child); |
19 | 25 |
20 static char *ngx_mail_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, | 26 static char *ngx_mail_ssl_enable(ngx_conf_t *cf, ngx_command_t *cmd, |
242 | 248 |
243 | 249 |
244 static ngx_str_t ngx_mail_ssl_sess_id_ctx = ngx_string("MAIL"); | 250 static ngx_str_t ngx_mail_ssl_sess_id_ctx = ngx_string("MAIL"); |
245 | 251 |
246 | 252 |
253 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation | |
254 | |
255 static int | |
256 ngx_mail_ssl_alpn_select(ngx_ssl_conn_t *ssl_conn, const unsigned char **out, | |
257 unsigned char *outlen, const unsigned char *in, unsigned int inlen, | |
258 void *arg) | |
259 { | |
260 unsigned int srvlen; | |
261 unsigned char *srv; | |
262 ngx_connection_t *c; | |
263 ngx_mail_session_t *s; | |
264 ngx_mail_core_srv_conf_t *cscf; | |
265 #if (NGX_DEBUG) | |
266 unsigned int i; | |
267 #endif | |
268 | |
269 c = ngx_ssl_get_connection(ssl_conn); | |
270 s = c->data; | |
271 | |
272 #if (NGX_DEBUG) | |
273 for (i = 0; i < inlen; i += in[i] + 1) { | |
274 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
275 "SSL ALPN supported by client: %*s", | |
276 (size_t) in[i], &in[i + 1]); | |
277 } | |
278 #endif | |
279 | |
280 cscf = ngx_mail_get_module_srv_conf(s, ngx_mail_core_module); | |
281 | |
282 srv = cscf->protocol->alpn.data; | |
283 srvlen = cscf->protocol->alpn.len; | |
284 | |
285 if (SSL_select_next_proto((unsigned char **) out, outlen, srv, srvlen, | |
286 in, inlen) | |
287 != OPENSSL_NPN_NEGOTIATED) | |
288 { | |
289 return SSL_TLSEXT_ERR_ALERT_FATAL; | |
290 } | |
291 | |
292 ngx_log_debug2(NGX_LOG_DEBUG_MAIL, c->log, 0, | |
293 "SSL ALPN selected: %*s", (size_t) *outlen, *out); | |
294 | |
295 return SSL_TLSEXT_ERR_OK; | |
296 } | |
297 | |
298 #endif | |
299 | |
300 | |
247 static void * | 301 static void * |
248 ngx_mail_ssl_create_conf(ngx_conf_t *cf) | 302 ngx_mail_ssl_create_conf(ngx_conf_t *cf) |
249 { | 303 { |
250 ngx_mail_ssl_conf_t *scf; | 304 ngx_mail_ssl_conf_t *scf; |
251 | 305 |
392 } | 446 } |
393 | 447 |
394 cln->handler = ngx_ssl_cleanup_ctx; | 448 cln->handler = ngx_ssl_cleanup_ctx; |
395 cln->data = &conf->ssl; | 449 cln->data = &conf->ssl; |
396 | 450 |
451 #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation | |
452 SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_mail_ssl_alpn_select, NULL); | |
453 #endif | |
454 | |
397 if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, | 455 if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, |
398 conf->prefer_server_ciphers) | 456 conf->prefer_server_ciphers) |
399 != NGX_OK) | 457 != NGX_OK) |
400 { | 458 { |
401 return NGX_CONF_ERROR; | 459 return NGX_CONF_ERROR; |