diff --git a/plugin-add-received.c b/plugin-add-received.c index 10cb259..2b26e89 100644 --- a/plugin-add-received.c +++ b/plugin-add-received.c @@ -78,16 +78,67 @@ static int add_header_add(str* s) return 1; } +/* Determine the RFC 3848 protocol token. + * ESMTPS = ESMTP + TLS, ESMTPA = ESMTP + AUTH, ESMTPSA = both. + * TLS or AUTH implies ESMTP-level features + */ +static const char* received_protocol(int tls, int authenticated) +{ + const char* proto = session_protocol(); + /* Only decorate SMTP/ESMTP — leave other protocols alone */ + if (strcmp(proto, "ESMTP") == 0 || + strcmp(proto, "SMTP") == 0) { + if (tls && authenticated) return "ESMTPSA"; + if (tls) return "ESMTPS"; + if (authenticated) return "ESMTPA"; + } + return proto; +} + +/* Append the RFC 8314 4.3 tls cipher clause and optional group clause. + * Format: " (TLS1.3) tls TLS_AES_256_GCM_SHA384 group x25519" + * The leading space is part of the CFWS before "tls". + */ +static int build_tls_clause(str* s) +{ + const char* ciphersuite = session_getstr("tls_ciphersuite"); + const char* proto; + const char* group; + + if (ciphersuite == NULL) + return 1; + + proto = session_getstr("tls_protocol"); + if (proto != NULL) { + if (!str_cat3s(s, " (", proto, ")")) return 0; + } + + if (!str_cat2s(s, " tls ", ciphersuite)) return 0; + + group = session_getstr("tls_group"); + if (group != NULL) { + if (!str_cat2s(s, " group ", group)) return 0; + } + + return 1; +} + static int build_received(str* s) { + int tls = session_getnum("tls_state", 0) > 0; + int authenticated = session_getnum("authenticated", 0); + if (!str_cats(s, "Received: from ")) return 0; if (!str_catfromby(s, session_getstr("helo_domain"), remote_host, &remote_ip)) return 0; if (!str_cats(s, "\n by ")) return 0; if (!str_catfromby(s, local_host, 0, &local_ip)) return 0; - if (!str_cat4s(s, "\n with ", session_protocol(), - " via ", linkproto)) + if (!str_cat2s(s, "\n with ", received_protocol(tls, authenticated))) + return 0; + if (tls) + if (!build_tls_clause(s)) return 0; + if (!str_cat2s(s, "\n via ", linkproto)) return 0; if (!str_cat3s(s, "; ", date_string(), "\n")) return 0; return 1; diff --git a/starttls-gnutls.c b/starttls-gnutls.c index 9dd46b3..d809671 100644 --- a/starttls-gnutls.c +++ b/starttls-gnutls.c @@ -172,6 +172,23 @@ static void set_tlsparams(void) session_setstr("tls_keyex", keyex); session_setstr("tls_cipher", cipher); session_setstr("tls_mac", mac); + + session_setnum("tls_state", 1); /* fixes TLS_IMMEDIATE mode */ + +#ifdef GNUTLS_VERSION_NUMBER +#if GNUTLS_VERSION_NUMBER >= 0x030704 + const char* ciphersuite = gnutls_ciphersuite_get(gsession); + if (ciphersuite != NULL) + session_setstr("tls_ciphersuite", ciphersuite); + + gnutls_group_t group = gnutls_group_get(gsession); + if (group != GNUTLS_GROUP_INVALID) { + const char* group_name = gnutls_group_get_name(group); + if (group_name != NULL) + session_setstr("tls_group", group_name); + } +#endif +#endif } int starttls_start(void)