Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 53 additions & 2 deletions plugin-add-received.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
17 changes: 17 additions & 0 deletions starttls-gnutls.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down