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 [email protected] --to [email protected]
> === Trying to.example:25...
> === Connected to to.example.
> <- 220 to.example ESMTP
> -> EHLO from.example
> <- 250-to.example
> <- 250-SOMETHING
> <- 250 STARTTLS
> -> MAIL FROM:<[email protected]>
> <** 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 -- [email protected]
To unsubscribe send an email to [email protected]