X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2Fsrc%2Ftls-openssl.c;h=4636f3c320ff44ff669d18258f4175d8b965c70e;hb=753739fdef6d9753ee4a7e89afd959a4034d2ad9;hp=cc72b2eeb40edef3de9f02a8f377ee8c33f82ea6;hpb=90315b85f88beec520dad795442d5ba806093ab4;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c index cc72b2eeb..4636f3c32 100644 --- a/src/src/tls-openssl.c +++ b/src/src/tls-openssl.c @@ -48,6 +48,7 @@ functions from the OpenSSL library. */ #if OPENSSL_VERSION_NUMBER >= 0x10100000L # define EXIM_HAVE_OCSP_RESP_COUNT # define OPENSSL_AUTO_SHA256 +# define EXIM_HAVE_ALPN #else # define EXIM_HAVE_EPHEM_RSA_KEX # define EXIM_HAVE_RAND_PSEUDO @@ -418,9 +419,6 @@ setup_certs(SSL_CTX *sctx, uschar *certs, uschar *crl, host_item *host, uschar ** errstr ); /* Callbacks */ -#ifdef EXIM_HAVE_OPENSSL_TLSEXT -static int tls_servername_cb(SSL *s, int *ad ARG_UNUSED, void *arg); -#endif #ifndef DISABLE_OCSP static int tls_server_stapling_cb(SSL *s, void *arg); #endif @@ -2137,6 +2135,53 @@ bad: return SSL_TLSEXT_ERR_ALERT_FATAL; +#ifdef EXIM_HAVE_ALPN +/************************************************* +* Callback to handle ALPN * +*************************************************/ + +/* SSL_CTX_set_alpn_select_cb() */ +/* Called on server when client offers ALPN, after the SNI callback. +If set and not e?smtp then we dump the connection */ + +static int +tls_server_alpn_cb(SSL *ssl, const uschar ** out, uschar * outlen, + const uschar * in, unsigned int inlen, void * arg) +{ +const exim_openssl_state_st * state = arg; + +DEBUG(D_tls) + { + debug_printf("Received TLS ALPN offer:"); + for (int pos = 0, siz; pos < inlen; pos += siz+1) + { + siz = in[pos]; + if (pos + 1 + siz > inlen) siz = inlen - pos - 1; + debug_printf(" '%.*s'", siz, in + pos + 1); + } + debug_printf("\n"); + } + +/* Look for an acceptable ALPN */ +if ( inlen > 1 /* at least one name */ + && in[0]+1 == inlen /* filling the vector, so exactly one name */ + && ( Ustrncmp(in+1, "smtp", in[0]) == 0 + || Ustrncmp(in+1, "esmtp", in[0]) == 0 + ) ) + { + *out = in; /* we checked for exactly one, so can just point to it */ + *outlen = inlen; + return SSL_TLSEXT_ERR_OK; /* use ALPN */ + } + +/* Reject unacceptable ALPN */ +/* This will be fatal to the TLS conn; would be nice to kill TCP also */ +return SSL_TLSEXT_ERR_ALERT_FATAL; +} +#endif /* EXIM_HAVE_ALPN */ + + + #ifndef DISABLE_OCSP /************************************************* @@ -2604,6 +2649,9 @@ if (!host) /* server */ tls_certificate */ SSL_CTX_set_tlsext_servername_callback(ctx, tls_servername_cb); SSL_CTX_set_tlsext_servername_arg(ctx, state); +# ifdef EXIM_HAVE_ALPN + SSL_CTX_set_alpn_select_cb(ctx, tls_server_alpn_cb, state); +# endif } # ifndef DISABLE_OCSP else /* client */ @@ -4481,7 +4529,6 @@ tls_openssl_options_parse(uschar *option_spec, long *results) { long result, item; uschar * exp, * end; -uschar keep_c; BOOL adding, item_parsed; /* Server: send no (<= TLS1.2) session tickets */ @@ -4523,11 +4570,8 @@ for (uschar * s = exp; *s; /**/) return FALSE; } adding = *s++ == '+'; - for (end = s; (*end != '\0') && !isspace(*end); ++end) /**/ ; - keep_c = *end; - *end = '\0'; - item_parsed = tls_openssl_one_option_parse(s, &item); - *end = keep_c; + for (end = s; *end && !isspace(*end); ) end++; + item_parsed = tls_openssl_one_option_parse(string_copyn(s, end-s), &item); if (!item_parsed) { DEBUG(D_tls) debug_printf("openssl option setting unrecognised: \"%s\"\n", s);