A. Schulze via Postfix-users: > > Hello, > > We've an SMTP-Server, running intentionally with > "smtpd_tls_security_level = encrypt" > > If an SMTP-Client fail to establish an TLS connection, the client > fallback to plaintext. > That's nothing we could avoid. > > What I see, is a session like this: > > # swaks --from from@from.example --to to@to.example > === Trying to.example:25... > === Connected to to.example. > <- 220 to.example ESMTP > -> EHLO from.example > <- 250-to.example > <- 250-SOMETHING > <- 250 STARTTLS > -> MAIL FROM:<from@from.example> > <** 530 5.7.0 Must issue a STARTTLS command first > -> QUIT > <- 221 2.0.0 Bye > > The response "Must issue a STARTTLS command first" is correct. But > it's hard for a SMTP client's admin to notice, > an TLS session failed before. So I would like to see a response like > "530 5.7.0 check why TLS wasn't established, maybe update yout client, > see https://example/more_text_here" > > One would suggest to use smtpd_reject_footer. It's already used here > and it's generic for many different replys (with generic informations > about the SMTP-client in our case) > > I know, there is an smtpd_recipient_restriction > "reject_plaintext_session" but I only found the option to change the > replycode (plaintext_reject_code) > So, this doesn't help directly and it also may be an other layer... > > Is there any other option than patching postfix' source code?
The options are Postfix 3.11 smtpd_reject_filter (supported), or backport (attached), or custom patch (not supported). The attached backport is just code, not documentation. Wietse
diff '--exclude=man' '--exclude=html' '--exclude=README_FILES' '--exclude=INSTALL' --no-dereference -r -ur --new-file /var/tmp/postfix-3.11-20250624/src/global/mail_params.h ./src/global/mail_params.h --- /var/tmp/postfix-3.11-20250624/src/global/mail_params.h 2025-06-23 16:35:19.000000000 -0400 +++ ./src/global/mail_params.h 2025-08-03 15:10:06.485751291 -0400 @@ -2568,7 +2568,8 @@ " $" VAR_SMTP_BODY_CHKS \ " $" VAR_SMTP_HEAD_CHKS \ " $" VAR_SMTP_MIME_CHKS \ - " $" VAR_SMTP_NEST_CHKS + " $" VAR_SMTP_NEST_CHKS \ + " $" VAR_SMTPD_REJECT_FILTER_MAPS extern char *var_proxy_read_maps; #define VAR_PROXY_WRITE_MAPS "proxy_write_maps" @@ -4529,6 +4530,13 @@ #define DEF_SMTPD_HIDE_CLIENT_SESSION "no" extern int var_smtpd_hide_client_session; + /* + * SMTP server reject response filter. + */ +#define VAR_SMTPD_REJECT_FILTER_MAPS "smtpd_reject_filter_maps" +#define DEF_SMTPD_REJECT_FILTER_MAPS "" +extern char *var_smtpd_reject_filter_maps; + /* LICENSE /* .ad /* .fi diff '--exclude=man' '--exclude=html' '--exclude=README_FILES' '--exclude=INSTALL' --no-dereference -r -ur --new-file /var/tmp/postfix-3.11-20250624/src/smtpd/smtpd.c ./src/smtpd/smtpd.c --- /var/tmp/postfix-3.11-20250624/src/smtpd/smtpd_chat.c 2021-10-02 10:46:46.000000000 -0400 +++ ./src/smtpd/smtpd_chat.c 2025-08-03 15:27:57.097704332 -0400 @@ -112,8 +112,9 @@ #include "smtpd_chat.h" /* - * Reject footer. + * Reject filter and footer maps. */ +static MAPS *smtpd_reject_filter_maps; static MAPS *smtpd_rej_ftr_maps; #define STR vstring_str @@ -129,6 +130,14 @@ msg_panic("smtpd_chat_pre_jail_init: multiple calls"); /* + * SMTP server reject filter. + */ + if (*var_smtpd_reject_filter_maps) + smtpd_reject_filter_maps = maps_create(VAR_SMTPD_REJECT_FILTER_MAPS, + var_smtpd_reject_filter_maps, + DICT_FLAG_LOCK); + + /* * SMTP server reject footer. */ if (*var_smtpd_rej_ftr_maps) @@ -206,6 +215,7 @@ char *cp; char *next; char *end; + const char *alt_reply; const char *footer; /* @@ -215,8 +225,30 @@ if (state->error_count >= var_smtpd_soft_erlim) sleep(delay = var_smtpd_err_sleep); + /* + * Postfix generates single-line reject responses, but Milters may + * generate multi-line rejects with the SMFIR_REPLYCODE request. + */ vstring_vsprintf(state->buffer, format, ap); - + cp = STR(state->buffer); + if ((*cp == '4' || *cp == '5') + && smtpd_reject_filter_maps != 0 + && (alt_reply = maps_find(smtpd_reject_filter_maps, cp, 0)) != 0) { + const char *queue_id = state->queue_id ? state->queue_id : "NOQUEUE"; + + /* XXX Enforce this for each line of a multi-line reply. */ + if ((alt_reply[0] != '4' && alt_reply[0] != '5') + || !ISDIGIT(alt_reply[1]) || !ISDIGIT(alt_reply[2]) + || (alt_reply[3] != ' ' && alt_reply[3] != '-') + || (ISDIGIT(alt_reply[4]) && (alt_reply[4] != alt_reply[0]))) { + msg_warn("%s: ignoring invalid reject filter result: %s", + queue_id, alt_reply); + } else { + msg_info("%s: reply filter in: %s", queue_id, cp); + msg_info("%s: reply filter out: %s", queue_id, alt_reply); + vstring_strcpy(state->buffer, alt_reply); + } + } if ((*(cp = STR(state->buffer)) == '4' || *cp == '5') && ((smtpd_rej_ftr_maps != 0 && (footer = maps_find(smtpd_rej_ftr_maps, cp, 0)) != 0)
_______________________________________________ Postfix-users mailing list -- postfix-users@postfix.org To unsubscribe send an email to postfix-users-le...@postfix.org