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;