Am 10.09.25 um 18:58 schrieb Wietse Venema via Postfix-users:
The attached backport is just code, not documentation.

Thanks, Wietse!

I confirm, a slightly updated version (attached) works at a first test with 
postfix-3.10.4

master.cf
  12345 inet n - - - - smtpd
    -o smtpd_tls_security_level=encrypt
    -o 
smtpd_reject_filter_maps=pcre:${config_directory}/smtpd_reject_filter.pcre

smtpd_reject_filter.pcre
  # https://www.postfix.org/postconf.5.html#smtpd_reject_filter_maps
  /^(5.+[^.])\.*$/ $1. See you later.

$ swaks --from '<>' --to root --port 12345
=== Trying localhost:12345...
=== Connected to localhost.
<-  220 localhost ESMTP
 -> EHLO localhost
<-  250-localhost
<-  250-MUMBLE
<-  250 STARTTLS
 -> MAIL FROM:<>
<** 530 5.7.0 Must issue a STARTTLS command first. See you later.
 -> QUIT
<-  221 2.0.0 Bye
=== Connection closed with remote host.

Andreas
diff -Naur postfix-3.10.4.orig/src/global/mail_params.h postfix-3.10.4/src/global/mail_params.h
--- postfix-3.10.4.orig/src/global/mail_params.h	2025-08-18 22:06:41.000000000 +0200
+++ postfix-3.10.4/src/global/mail_params.h	2025-09-10 22:34:18.259190123 +0200
@@ -2548,7 +2548,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"
@@ -4513,6 +4514,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 -Naur postfix-3.10.4.orig/src/smtpd/smtpd.c postfix-3.10.4/src/smtpd/smtpd.c
--- postfix-3.10.4.orig/src/smtpd/smtpd.c	2025-02-05 23:04:14.000000000 +0100
+++ postfix-3.10.4/src/smtpd/smtpd.c	2025-09-10 22:34:18.259190123 +0200
@@ -1478,6 +1478,7 @@
 char   *var_smtpd_cmd_filter;
 char   *var_smtpd_rej_footer;
 char   *var_smtpd_rej_ftr_maps;
+char   *var_smtpd_reject_filter_maps;
 char   *var_smtpd_acl_perm_log;
 char   *var_smtpd_dns_re_filter;
 
@@ -6635,9 +6636,9 @@
 			      var_smtpd_dns_re_filter);
 
     /*
-     * Reject footer.
+     * Reject filter and footer.
      */
-    if (*var_smtpd_rej_ftr_maps)
+    if (*var_smtpd_rej_ftr_maps || *var_smtpd_reject_filter_maps)
 	smtpd_chat_pre_jail_init();
 }
 
@@ -6911,6 +6912,7 @@
 	VAR_SMTPD_POLICY_CONTEXT, DEF_SMTPD_POLICY_CONTEXT, &var_smtpd_policy_context, 0, 0,
 	VAR_SMTPD_DNS_RE_FILTER, DEF_SMTPD_DNS_RE_FILTER, &var_smtpd_dns_re_filter, 0, 0,
 	VAR_SMTPD_REJ_FTR_MAPS, DEF_SMTPD_REJ_FTR_MAPS, &var_smtpd_rej_ftr_maps, 0, 0,
+	VAR_SMTPD_REJECT_FILTER_MAPS, DEF_SMTPD_REJECT_FILTER_MAPS, &var_smtpd_reject_filter_maps, 0, 0,
 	VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
 	VAR_SMTPD_FORBID_BARE_LF_EXCL, DEF_SMTPD_FORBID_BARE_LF_EXCL, &var_smtpd_forbid_bare_lf_excl, 0, 0,
 	VAR_SMTPD_FORBID_BARE_LF, DEF_SMTPD_FORBID_BARE_LF, &var_smtpd_forbid_bare_lf, 1, 0,
diff -Naur postfix-3.10.4.orig/src/smtpd/smtpd_chat.c postfix-3.10.4/src/smtpd/smtpd_chat.c
--- postfix-3.10.4.orig/src/smtpd/smtpd_chat.c	2021-10-02 16:46:46.000000000 +0200
+++ postfix-3.10.4/src/smtpd/smtpd_chat.c	2025-09-10 22:34:18.259190123 +0200
@@ -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

Reply via email to