summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJeremy Harris <jgh146exb@wizmail.org>2019-11-14 15:59:42 +0000
committerJeremy Harris <jgh146exb@wizmail.org>2019-11-14 15:59:42 +0000
commit5b195d6b9592fcef09b0b3b31390e73226deffc9 (patch)
tree2f27a37ef3c0604b3aaf209a81e33357108252da /src
parent5694b9058458fa8bd0a1f28bcb874f5108543ce3 (diff)
TLS: variables $tls_(in,out)_tlsver
Diffstat (limited to 'src')
-rw-r--r--src/src/deliver.c8
-rw-r--r--src/src/expand.c2
-rw-r--r--src/src/globals.h1
-rw-r--r--src/src/smtp_in.c2
-rw-r--r--src/src/spool_in.c19
-rw-r--r--src/src/spool_out.c1
-rw-r--r--src/src/structs.h1
-rw-r--r--src/src/tls-gnu.c4
-rw-r--r--src/src/tls-openssl.c28
-rw-r--r--src/src/transports/smtp.c3
10 files changed, 51 insertions, 18 deletions
diff --git a/src/src/deliver.c b/src/src/deliver.c
index b89671c57..58874add4 100644
--- a/src/src/deliver.c
+++ b/src/src/deliver.c
@@ -1610,6 +1610,7 @@ if (result == OK)
tls_out.peercert = addr->peercert;
addr->peercert = NULL;
+ tls_out.ver = addr->tlsver;
tls_out.cipher = addr->cipher;
tls_out.peerdn = addr->peerdn;
tls_out.ocsp = addr->ocsp;
@@ -1623,6 +1624,7 @@ if (result == OK)
#ifndef DISABLE_TLS
tls_free_cert(&tls_out.ourcert);
tls_free_cert(&tls_out.peercert);
+ tls_out.ver = NULL;
tls_out.cipher = NULL;
tls_out.peerdn = NULL;
tls_out.ocsp = OCSP_NOT_REQ;
@@ -3480,11 +3482,13 @@ while (!done)
switch (*subid)
{
case '1':
- addr->cipher = NULL;
- addr->peerdn = NULL;
+ addr->tlsver = addr->cipher = addr->peerdn = NULL;
if (*ptr)
+ {
addr->cipher = string_copy(ptr);
+ addr->tlsver = string_copyn(ptr, Ustrchr(ptr, ':') - ptr);
+ }
while (*ptr++);
if (*ptr)
addr->peerdn = string_copy(ptr);
diff --git a/src/src/expand.c b/src/src/expand.c
index 1cd08df89..366cd737a 100644
--- a/src/src/expand.c
+++ b/src/src/expand.c
@@ -776,6 +776,7 @@ static var_entry var_table[] = {
#ifndef DISABLE_TLS
{ "tls_in_sni", vtype_stringptr, &tls_in.sni },
#endif
+ { "tls_in_ver", vtype_stringptr, &tls_in.ver },
{ "tls_out_bits", vtype_int, &tls_out.bits },
{ "tls_out_certificate_verified", vtype_int,&tls_out.certificate_verified },
{ "tls_out_cipher", vtype_stringptr, &tls_out.cipher },
@@ -796,6 +797,7 @@ static var_entry var_table[] = {
#ifdef SUPPORT_DANE
{ "tls_out_tlsa_usage", vtype_int, &tls_out.tlsa_usage },
#endif
+ { "tls_out_ver", vtype_stringptr, &tls_out.ver },
{ "tls_peerdn", vtype_stringptr, &tls_in.peerdn }, /* mind the alphabetical order! */
#ifndef DISABLE_TLS
diff --git a/src/src/globals.h b/src/src/globals.h
index ee89fd1f5..1754d3e89 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -89,6 +89,7 @@ typedef struct {
#endif
uschar *cipher; /* Cipher used */
const uschar *cipher_stdname; /* Cipher used, RFC version */
+ const uschar *ver; /* TLS version */
BOOL on_connect; /* For older MTAs that don't STARTTLS */
uschar *on_connect_ports; /* Ports always tls-on-connect */
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index bd29d2c1f..ddf98ec61 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -2466,7 +2466,7 @@ if (!host_checking && !f.sender_host_notsocket)
authenticated_by = NULL;
#ifndef DISABLE_TLS
-tls_in.cipher = tls_in.peerdn = NULL;
+tls_in.ver = tls_in.cipher = tls_in.peerdn = NULL;
tls_in.ourcert = tls_in.peercert = NULL;
tls_in.sni = NULL;
tls_in.ocsp = OCSP_NOT_REQ;
diff --git a/src/src/spool_in.c b/src/src/spool_in.c
index f393d4d3e..cbd2751ac 100644
--- a/src/src/spool_in.c
+++ b/src/src/spool_in.c
@@ -278,7 +278,7 @@ tls_in.certificate_verified = FALSE;
# ifdef SUPPORT_DANE
tls_in.dane_verified = FALSE;
# endif
-tls_in.cipher = NULL;
+tls_in.ver = tls_in.cipher = NULL;
# ifndef COMPILE_UTILITY /* tls support fns not built in */
tls_free_cert(&tls_in.ourcert);
tls_free_cert(&tls_in.peercert);
@@ -665,24 +665,25 @@ for (;;)
if (Ustrncmp(q, "certificate_verified", 20) == 0)
tls_in.certificate_verified = TRUE;
else if (Ustrncmp(q, "cipher", 6) == 0)
- tls_in.cipher = string_copy_taint(var + 11, tainted);
+ tls_in.cipher = string_copy_taint(q+7, tainted);
# ifndef COMPILE_UTILITY /* tls support fns not built in */
else if (Ustrncmp(q, "ourcert", 7) == 0)
- (void) tls_import_cert(var + 12, &tls_in.ourcert);
+ (void) tls_import_cert(q+8, &tls_in.ourcert);
else if (Ustrncmp(q, "peercert", 8) == 0)
- (void) tls_import_cert(var + 13, &tls_in.peercert);
+ (void) tls_import_cert(q+9, &tls_in.peercert);
# endif
else if (Ustrncmp(q, "peerdn", 6) == 0)
- tls_in.peerdn = string_unprinting(string_copy_taint(var + 11, tainted));
+ tls_in.peerdn = string_unprinting(string_copy_taint(q+7, tainted));
else if (Ustrncmp(q, "sni", 3) == 0)
- tls_in.sni = string_unprinting(string_copy_taint(var + 8, tainted));
+ tls_in.sni = string_unprinting(string_copy_taint(q+4, tainted));
else if (Ustrncmp(q, "ocsp", 4) == 0)
- tls_in.ocsp = var[9] - '0';
+ tls_in.ocsp = q[5] - '0';
# ifdef EXPERIMENTAL_TLS_RESUME
else if (Ustrncmp(q, "resumption", 10) == 0)
- tls_in.resumption = var[15] - 'A';
+ tls_in.resumption = q[11] - 'A';
# endif
-
+ else if (Ustrncmp(q, "ver", 3) == 0)
+ tls_in.ver = string_copy_taint(q+4, tainted);
}
break;
#endif
diff --git a/src/src/spool_out.c b/src/src/spool_out.c
index acc6c7b5f..c766b147d 100644
--- a/src/src/spool_out.c
+++ b/src/src/spool_out.c
@@ -263,6 +263,7 @@ if (tls_in.ocsp) fprintf(fp, "-tls_ocsp %d\n", tls_in.ocsp);
# ifdef EXPERIMENTAL_TLS_RESUME
fprintf(fp, "-tls_resumption %c\n", 'A' + tls_in.resumption);
# endif
+if (tls_in.ver) spool_var_write(fp, US"tls_ver", tls_in.ver);
#endif
#ifdef SUPPORT_I18N
diff --git a/src/src/structs.h b/src/src/structs.h
index 6662e6458..1d867c5b6 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -570,6 +570,7 @@ typedef struct address_item {
uschar *shadow_message; /* info about shadow transporting */
#ifndef DISABLE_TLS
+ const uschar *tlsver; /* version used for transport */
uschar *cipher; /* Cipher used for transport */
void *ourcert; /* Certificate offered to peer, binary */
void *peercert; /* Certificate from peer, binary */
diff --git a/src/src/tls-gnu.c b/src/src/tls-gnu.c
index 6cd9bf75b..eaec862aa 100644
--- a/src/src/tls-gnu.c
+++ b/src/src/tls-gnu.c
@@ -468,6 +468,7 @@ Sets:
tls_bits strength indicator
tls_certificate_verified bool indicator
tls_channelbinding_b64 for some SASL mechanisms
+ tls_ver a string
tls_cipher a string
tls_peercert pointer to library internal
tls_peerdn a string
@@ -1754,6 +1755,7 @@ old_pool = store_pool;
/* debug_printf("peer_status: gnutls_session_get_desc %s\n", s); */
for (s++; (c = *s) && c != ')'; s++) g = string_catn(g, s, 1);
+ tlsp->ver = string_copyn(g->s, g->ptr);
g = string_catn(g, US":", 1);
if (*s) s++; /* now on _ between groups */
while ((c = *s))
@@ -1778,6 +1780,8 @@ old_pool = store_pool;
releases did return "TLS 1.0"; play it safe, just in case. */
for (uschar * p = state->ciphersuite; *p; p++) if (isspace(*p)) *p = '-';
+ tlsp->ver = string_copyn(state->ciphersuite,
+ Ustrchr(state->ciphersuite, ':') - state->ciphersuite);
#endif
/* debug_printf("peer_status: ciphersuite %s\n", state->ciphersuite); */
diff --git a/src/src/tls-openssl.c b/src/src/tls-openssl.c
index c5e1abfe9..7a82e1d55 100644
--- a/src/src/tls-openssl.c
+++ b/src/src/tls-openssl.c
@@ -2212,14 +2212,13 @@ Returns: pointer to allocated string in perm-pool
*/
static uschar *
-construct_cipher_name(SSL * ssl, int * bits)
+construct_cipher_name(SSL * ssl, const uschar * ver, int * bits)
{
int pool = store_pool;
/* With OpenSSL 1.0.0a, 'c' needs to be const but the documentation doesn't
yet reflect that. It should be a safe change anyway, even 0.9.8 versions have
the accessor functions use const in the prototype. */
-const uschar * ver = CUS SSL_get_version(ssl);
const SSL_CIPHER * c = (const SSL_CIPHER *) SSL_get_current_cipher(ssl);
uschar * s;
@@ -2250,6 +2249,21 @@ return cipher_stdname(id >> 8, id & 0xff);
}
+static const uschar *
+tlsver_name(SSL * ssl)
+{
+uschar * s, * p;
+int pool = store_pool;
+
+store_pool = POOL_PERM;
+s = string_copy(US SSL_get_version(ssl));
+store_pool = pool;
+if ((p = Ustrchr(s, 'v'))) /* TLSv1.2 -> TLS1.2 */
+ for (;; p++) if (!(*p = p[1])) break;
+return CUS s;
+}
+
+
static void
peer_cert(SSL * ssl, tls_support * tlsp, uschar * peerdn, unsigned siz)
{
@@ -2688,12 +2702,13 @@ if (SSL_session_reused(server_ssl))
}
#endif
-/* TLS has been set up. Adjust the input functions to read via TLS,
-and initialize things. */
+/* TLS has been set up. Record data for the connection,
+adjust the input functions to read via TLS, and initialize things. */
peer_cert(server_ssl, &tls_in, peerdn, sizeof(peerdn));
-tls_in.cipher = construct_cipher_name(server_ssl, &tls_in.bits);
+tls_in.ver = tlsver_name(server_ssl);
+tls_in.cipher = construct_cipher_name(server_ssl, tls_in.ver, &tls_in.bits);
tls_in.cipher_stdname = cipher_stdname_ssl(server_ssl);
DEBUG(D_tls)
@@ -3278,7 +3293,8 @@ tls_client_resume_posthandshake(exim_client_ctx, tlsp);
peer_cert(exim_client_ctx->ssl, tlsp, peerdn, sizeof(peerdn));
-tlsp->cipher = construct_cipher_name(exim_client_ctx->ssl, &tlsp->bits);
+tlsp->ver = tlsver_name(exim_client_ctx->ssl);
+tlsp->cipher = construct_cipher_name(exim_client_ctx->ssl, tlsp->ver, &tlsp->bits);
tlsp->cipher_stdname = cipher_stdname_ssl(exim_client_ctx->ssl);
/* Record the certificate we presented */
diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c
index 383d202b9..dee546ce1 100644
--- a/src/src/transports/smtp.c
+++ b/src/src/transports/smtp.c
@@ -2084,6 +2084,7 @@ tls_out.ocsp = OCSP_NOT_REQ;
#ifdef EXPERIMENTAL_TLS_RESUME
tls_out.resumption = 0;
#endif
+tls_out.ver = NULL;
/* Flip the legacy TLS-related variables over to the outbound set in case
they're used in the context of the transport. Don't bother resetting
@@ -2604,6 +2605,7 @@ if ( smtp_peer_options & OPTION_TLS
addr->peercert = tls_out.peercert;
addr->peerdn = tls_out.peerdn;
addr->ocsp = tls_out.ocsp;
+ addr->tlsver = tls_out.ver;
}
}
}
@@ -4560,6 +4562,7 @@ for (address_item * addr = addrlist; addr; addr = addr->next)
addr->peercert = NULL;
addr->peerdn = NULL;
addr->ocsp = OCSP_NOT_REQ;
+ addr->tlsver = NULL;
#endif
#ifdef EXPERIMENTAL_DSN_INFO
addr->smtp_greeting = NULL;