mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 09:57:34 +00:00
postfix-2.7-20090607
This commit is contained in:
parent
c3440e3338
commit
e3121fd2b8
@ -15301,3 +15301,10 @@ Apologies for any names omitted.
|
||||
outside those those trees (e.g. by symlink race attacks).
|
||||
We don't want to be nailed with a bunch of CVEs for unsafe
|
||||
pathname handling. File: conf/postmulti-script.
|
||||
|
||||
20090607
|
||||
|
||||
Cleanup: revise milter_header_checks action implementation,
|
||||
and avoid redundant logging and work when milter_header_checks
|
||||
and Milters make redundant or conflicting decisions. File:
|
||||
cleanup_milter.c.
|
||||
|
@ -21,13 +21,13 @@ The "postmulti -e destroy" command no longer attempts to remove
|
||||
files that are created AFTER "postmulti -e create". It still works
|
||||
as expected immediately after creating an instance by mistake.
|
||||
Trying to automatically remove other files is too risky because
|
||||
Postfix-owned directories are not trusted.
|
||||
Postfix-owned directories are by design not trusted.
|
||||
|
||||
Major changes with snapshot 20090606
|
||||
====================================
|
||||
|
||||
Support for header checks on headers that are generated by Milter
|
||||
applications. This can be used, for example, to direct mail flow
|
||||
based on headers that indicate spam levels. See postconf(5) for
|
||||
"milter_header_checks. All header_checks features are implemented
|
||||
except PREPEND.
|
||||
Support for header checks on Milter-generated message headers. This
|
||||
can be used, for example, to control mail flow with Milter-generated
|
||||
headers with indicators for badness or goodness. For details, see
|
||||
the postconf(5) section for "milter_header_checks". Currently, all
|
||||
header_checks features are implemented except PREPEND.
|
||||
|
@ -27,13 +27,6 @@ umask 022
|
||||
# multi_instance_group - New value for target instance
|
||||
# multi_instance_name - New value for target instance
|
||||
|
||||
# For security reasons we don't take pathnames from the file system
|
||||
# when destroying instances. Instead we use known-to-be-safe names
|
||||
# and nothing with a / because that could be subject to races.
|
||||
QUEUE_DIRECTORIES="active bounce corrupt defer deferred flush hold incoming \
|
||||
maildrop pid private public saved trace"
|
||||
#DEBUG=echo
|
||||
|
||||
: ${MAIL_CONFIG:?"do not invoke this command directly"}
|
||||
: ${command_directory:?"do not invoke this command directly"}
|
||||
: ${daemon_directory:?"do not invoke this command directly"}
|
||||
@ -43,7 +36,6 @@ usage() { echo "$0: Error: Usage: $USAGE" >&2; exit 1; }
|
||||
|
||||
TAG="$MAIL_LOGTAG/postmulti-script"
|
||||
fatal() { postlog -p fatal -t "$TAG" "$1"; exit 1; }
|
||||
WARN="postlog -p warn -t $TAG"
|
||||
|
||||
# args: add|del $dir
|
||||
#
|
||||
@ -236,6 +228,22 @@ deport)
|
||||
;;
|
||||
|
||||
destroy)
|
||||
|
||||
# "postmulti -e destroy" will remove an entire instance only
|
||||
# when invoked immediately after "postmulti -e create". Trying
|
||||
# to remove more files is too dangerous.
|
||||
#
|
||||
# By design, postfix-owned directory trees are not trusted, and
|
||||
# any action within those directory trees must not affect files
|
||||
# outside those trees (e.g. via symlink race attacks). Therefore
|
||||
# we use only known-to-be-safe names and nothing with a / because
|
||||
# that could be subject to races.
|
||||
#
|
||||
QUEUE_SUBDIRS="active bounce corrupt defer deferred flush hold \
|
||||
incoming maildrop pid private public saved trace"
|
||||
#DEBUG=echo
|
||||
WARN="postlog -p warn -t $TAG"
|
||||
|
||||
# Locate the target instance
|
||||
#
|
||||
[ -f "$config_directory/main.cf" ] ||
|
||||
@ -247,23 +255,15 @@ destroy)
|
||||
# Update multi_instance directories
|
||||
# and also (just in case) drop from alternate_config_directories
|
||||
#
|
||||
$DEBUG update_cfdirs del $config_directory || exit 1
|
||||
$DEBUG update_cfdirs del "$config_directory" || exit 1
|
||||
|
||||
# "postmulti -e destroy" will remove an entire instance only
|
||||
# when invoked immediately after "postmulti -e create". Trying
|
||||
# to remove more files is too dangerous.
|
||||
#
|
||||
# By design, postfix-owned directory trees are not trusted, and
|
||||
# any action within those directory trees must not affect files
|
||||
# outside those trees (e.g. via symlink race attacks).
|
||||
#
|
||||
# XXX: Internal "postfix /some/cmd" interface.
|
||||
#
|
||||
postfix -c "$config_directory" /bin/sh -c "
|
||||
for q in $QUEUE_DIRECTORIES
|
||||
for q in $QUEUE_SUBDIRS
|
||||
do
|
||||
$DEBUG rmdir -- \$q ||
|
||||
$WARN `pwd`/\$q: please verify contents and remove by hand
|
||||
$WARN \`pwd\`/\$q: please verify contents and remove by hand
|
||||
done
|
||||
"
|
||||
|
||||
@ -278,7 +278,7 @@ destroy)
|
||||
# In the configuration directory remove just the main.cf and master.cf
|
||||
# files.
|
||||
$DEBUG rm -f -- "$config_directory/master.cf" "$config_directory/main.cf" 2>/dev/null
|
||||
$DEBUG rmdir -- "$config_directory" ||
|
||||
$DEBUG rmdir -- "$config_directory" ||
|
||||
$WARN $config_directory: please verify contents and remove by hand
|
||||
;;
|
||||
|
||||
|
@ -224,12 +224,12 @@ CLEANUP(8) CLEANUP(8)
|
||||
The macros that are sent to Milter (mail filter)
|
||||
applications after the end of the message header.
|
||||
|
||||
Available in Postfix version 2.5 and later:
|
||||
Available in Postfix version 2.7 and later:
|
||||
|
||||
<b><a href="postconf.5.html#milter_header_checks">milter_header_checks</a> (empty)</b>
|
||||
Optional lookup tables for content inspection of
|
||||
primary message headers that are produced by Milter
|
||||
applications.
|
||||
message headers that are produced by Milter appli-
|
||||
cations.
|
||||
|
||||
<b>MIME PROCESSING CONTROLS</b>
|
||||
Available in Postfix version 2.0 and later:
|
||||
|
@ -5694,15 +5694,14 @@ of available macro names and their meanings. </p>
|
||||
<DT><b><a name="milter_header_checks">milter_header_checks</a>
|
||||
(default: empty)</b></DT><DD>
|
||||
|
||||
<p>
|
||||
Optional lookup tables for content inspection of primary
|
||||
message headers that are produced by Milter applications.
|
||||
See the <a href="header_checks.5.html">header_checks(5)</a> manual page for usage.
|
||||
<p> Optional lookup tables for content inspection of message headers
|
||||
that are produced by Milter applications. See the <a href="header_checks.5.html">header_checks(5)</a>
|
||||
manual page available actions. Currently, PREPEND is not implemented.
|
||||
</p>
|
||||
|
||||
<p> The following example sends mail that is marked as SPAM to a
|
||||
spam sanization machine. Note that matches are case-insensitive by
|
||||
default. </p>
|
||||
<p> The following example sends all mail that is marked as SPAM to
|
||||
a spam handling machine. Note that matches are case-insensitive
|
||||
by default. </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
@ -5715,6 +5714,13 @@ default. </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> The <a href="postconf.5.html#milter_header_checks">milter_header_checks</a> mechanism could also be used for
|
||||
whitelisting. For example it could be used to skip heavy content
|
||||
scanning for DKIM-signed mail from known friendly domains. </p>
|
||||
|
||||
<p> This feature is available in Postfix 2.7, and as an optional
|
||||
patch for Postfix 2.6. </p>
|
||||
|
||||
|
||||
</DD>
|
||||
|
||||
|
@ -3159,13 +3159,13 @@ of available macro names and their meanings.
|
||||
.PP
|
||||
This feature is available in Postfix 2.5 and later.
|
||||
.SH milter_header_checks (default: empty)
|
||||
Optional lookup tables for content inspection of primary
|
||||
message headers that are produced by Milter applications.
|
||||
See the \fBheader_checks\fR(5) manual page for usage.
|
||||
Optional lookup tables for content inspection of message headers
|
||||
that are produced by Milter applications. See the \fBheader_checks\fR(5)
|
||||
manual page available actions. Currently, PREPEND is not implemented.
|
||||
.PP
|
||||
The following example sends mail that is marked as SPAM to a
|
||||
spam sanization machine. Note that matches are case-insensitive by
|
||||
default.
|
||||
The following example sends all mail that is marked as SPAM to
|
||||
a spam handling machine. Note that matches are case-insensitive
|
||||
by default.
|
||||
.sp
|
||||
.in +4
|
||||
.nf
|
||||
@ -3185,6 +3185,13 @@ default.
|
||||
.ad
|
||||
.ft R
|
||||
.in -4
|
||||
.PP
|
||||
The milter_header_checks mechanism could also be used for
|
||||
whitelisting. For example it could be used to skip heavy content
|
||||
scanning for DKIM-signed mail from known friendly domains.
|
||||
.PP
|
||||
This feature is available in Postfix 2.7, and as an optional
|
||||
patch for Postfix 2.6.
|
||||
.SH milter_helo_macros (default: see "postconf -d" output)
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
after the SMTP HELO or EHLO command. See
|
||||
|
@ -191,10 +191,10 @@ Available in Postfix version 2.5 and later:
|
||||
The macros that are sent to Milter (mail filter) applications
|
||||
after the end of the message header.
|
||||
.PP
|
||||
Available in Postfix version 2.5 and later:
|
||||
Available in Postfix version 2.7 and later:
|
||||
.IP "\fBmilter_header_checks (empty)\fR"
|
||||
Optional lookup tables for content inspection of primary
|
||||
message headers that are produced by Milter applications.
|
||||
Optional lookup tables for content inspection of message headers
|
||||
that are produced by Milter applications.
|
||||
.SH "MIME PROCESSING CONTROLS"
|
||||
.na
|
||||
.nf
|
||||
|
@ -12302,15 +12302,14 @@ parameter. See there for details. </p>
|
||||
|
||||
%PARAM milter_header_checks
|
||||
|
||||
<p>
|
||||
Optional lookup tables for content inspection of primary
|
||||
message headers that are produced by Milter applications.
|
||||
See the header_checks(5) manual page for usage.
|
||||
<p> Optional lookup tables for content inspection of message headers
|
||||
that are produced by Milter applications. See the header_checks(5)
|
||||
manual page available actions. Currently, PREPEND is not implemented.
|
||||
</p>
|
||||
|
||||
<p> The following example sends mail that is marked as SPAM to a
|
||||
spam sanization machine. Note that matches are case-insensitive by
|
||||
default. </p>
|
||||
<p> The following example sends all mail that is marked as SPAM to
|
||||
a spam handling machine. Note that matches are case-insensitive
|
||||
by default. </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
@ -12322,3 +12321,10 @@ default. </p>
|
||||
/^X-SPAM-FLAG:\s+YES]/ FILTER mysmtp:sanitizer.example.com:25
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> The milter_header_checks mechanism could also be used for
|
||||
whitelisting. For example it could be used to skip heavy content
|
||||
scanning for DKIM-signed mail from known friendly domains. </p>
|
||||
|
||||
<p> This feature is available in Postfix 2.7, and as an optional
|
||||
patch for Postfix 2.6. </p>
|
||||
|
@ -78,9 +78,11 @@ milter_tests: cleanup_milter_test bug_tests \
|
||||
cleanup_milter_test13a cleanup_milter_test13b cleanup_milter_test13c \
|
||||
cleanup_milter_test13d \
|
||||
cleanup_milter_test14a cleanup_milter_test14b cleanup_milter_test14c \
|
||||
cleanup_milter_test14d cleanup_milter_test14e \
|
||||
cleanup_milter_test14d cleanup_milter_test14e cleanup_milter_test14f \
|
||||
cleanup_milter_test14g \
|
||||
cleanup_milter_test15a cleanup_milter_test15b cleanup_milter_test15c \
|
||||
cleanup_milter_test15d cleanup_milter_test15e
|
||||
cleanup_milter_test15d cleanup_milter_test15e cleanup_milter_test15f \
|
||||
cleanup_milter_test15g cleanup_milter_test15h cleanup_milter_test15i
|
||||
|
||||
root_tests:
|
||||
|
||||
@ -388,6 +390,26 @@ cleanup_milter_test14e: cleanup_milter test-queue-file14 cleanup_milter.in14e \
|
||||
diff cleanup_milter.ref14e2 cleanup_milter.tmp2
|
||||
rm -f test-queue-file14e.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
|
||||
|
||||
cleanup_milter_test14f: cleanup_milter test-queue-file14 cleanup_milter.in14f \
|
||||
cleanup_milter.ref14f1 ../postcat/postcat cleanup_milter.ref14f2
|
||||
cp test-queue-file14 test-queue-file14f.tmp
|
||||
chmod u+w test-queue-file14f.tmp
|
||||
./cleanup_milter <cleanup_milter.in14f 2>cleanup_milter.tmp1
|
||||
diff cleanup_milter.ref14f1 cleanup_milter.tmp1
|
||||
../postcat/postcat -ov test-queue-file14f.tmp 2>/dev/null >cleanup_milter.tmp2
|
||||
diff cleanup_milter.ref14f2 cleanup_milter.tmp2
|
||||
rm -f test-queue-file14f.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
|
||||
|
||||
cleanup_milter_test14g: cleanup_milter test-queue-file14 cleanup_milter.in14g \
|
||||
cleanup_milter.ref14g1 ../postcat/postcat cleanup_milter.ref14g2
|
||||
cp test-queue-file14 test-queue-file14g.tmp
|
||||
chmod u+w test-queue-file14g.tmp
|
||||
./cleanup_milter <cleanup_milter.in14g 2>cleanup_milter.tmp1
|
||||
diff cleanup_milter.ref14g1 cleanup_milter.tmp1
|
||||
../postcat/postcat -ov test-queue-file14g.tmp 2>/dev/null >cleanup_milter.tmp2
|
||||
diff cleanup_milter.ref14g2 cleanup_milter.tmp2
|
||||
rm -f test-queue-file14g.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
|
||||
|
||||
cleanup_milter_test15a: cleanup_milter test-queue-file15 cleanup_milter.in15a \
|
||||
cleanup_milter.ref15a1 ../postcat/postcat cleanup_milter.ref15a2
|
||||
cp test-queue-file15 test-queue-file15a.tmp
|
||||
@ -438,6 +460,46 @@ cleanup_milter_test15e: cleanup_milter test-queue-file15 cleanup_milter.in15e \
|
||||
diff cleanup_milter.ref15e2 cleanup_milter.tmp2
|
||||
rm -f test-queue-file15e.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
|
||||
|
||||
cleanup_milter_test15f: cleanup_milter test-queue-file15 cleanup_milter.in15f \
|
||||
cleanup_milter.ref15f1 ../postcat/postcat cleanup_milter.ref15f2
|
||||
cp test-queue-file15 test-queue-file15f.tmp
|
||||
chmod u+w test-queue-file15f.tmp
|
||||
./cleanup_milter <cleanup_milter.in15f 2>cleanup_milter.tmp1
|
||||
diff cleanup_milter.ref15f1 cleanup_milter.tmp1
|
||||
../postcat/postcat -ov test-queue-file15f.tmp 2>/dev/null >cleanup_milter.tmp2
|
||||
diff cleanup_milter.ref15f2 cleanup_milter.tmp2
|
||||
rm -f test-queue-file15f.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
|
||||
|
||||
cleanup_milter_test15g: cleanup_milter test-queue-file15 cleanup_milter.in15g \
|
||||
cleanup_milter.ref15g1 ../postcat/postcat cleanup_milter.ref15g2
|
||||
cp test-queue-file15 test-queue-file15g.tmp
|
||||
chmod u+w test-queue-file15g.tmp
|
||||
./cleanup_milter <cleanup_milter.in15g 2>cleanup_milter.tmp1
|
||||
diff cleanup_milter.ref15g1 cleanup_milter.tmp1
|
||||
../postcat/postcat -ov test-queue-file15g.tmp 2>/dev/null >cleanup_milter.tmp2
|
||||
diff cleanup_milter.ref15g2 cleanup_milter.tmp2
|
||||
rm -f test-queue-file15g.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
|
||||
|
||||
cleanup_milter_test15h: cleanup_milter test-queue-file15 cleanup_milter.in15h \
|
||||
cleanup_milter.ref15h1 ../postcat/postcat cleanup_milter.ref15h2
|
||||
cp test-queue-file15 test-queue-file15h.tmp
|
||||
chmod u+w test-queue-file15h.tmp
|
||||
./cleanup_milter <cleanup_milter.in15h 2>cleanup_milter.tmp1
|
||||
diff cleanup_milter.ref15h1 cleanup_milter.tmp1
|
||||
../postcat/postcat -ov test-queue-file15h.tmp 2>/dev/null >cleanup_milter.tmp2
|
||||
diff cleanup_milter.ref15h2 cleanup_milter.tmp2
|
||||
rm -f test-queue-file15h.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
|
||||
|
||||
cleanup_milter_test15i: cleanup_milter test-queue-file15 cleanup_milter.in15i \
|
||||
cleanup_milter.ref15i1 ../postcat/postcat cleanup_milter.ref15i2
|
||||
cp test-queue-file15 test-queue-file15i.tmp
|
||||
chmod u+w test-queue-file15i.tmp
|
||||
./cleanup_milter <cleanup_milter.in15i 2>cleanup_milter.tmp1
|
||||
diff cleanup_milter.ref15i1 cleanup_milter.tmp1
|
||||
../postcat/postcat -ov test-queue-file15i.tmp 2>/dev/null >cleanup_milter.tmp2
|
||||
diff cleanup_milter.ref15i2 cleanup_milter.tmp2
|
||||
rm -f test-queue-file15i.tmp cleanup_milter.tmp1 cleanup_milter.tmp2
|
||||
|
||||
depend: $(MAKES)
|
||||
(sed '1,/^# do not edit/!d' Makefile.in; \
|
||||
set -e; for i in [a-z][a-z0-9]*.c; do \
|
||||
|
@ -171,10 +171,10 @@
|
||||
/* The macros that are sent to Milter (mail filter) applications
|
||||
/* after the end of the message header.
|
||||
/* .PP
|
||||
/* Available in Postfix version 2.5 and later:
|
||||
/* Available in Postfix version 2.7 and later:
|
||||
/* .IP "\fBmilter_header_checks (empty)\fR"
|
||||
/* Optional lookup tables for content inspection of primary
|
||||
/* message headers that are produced by Milter applications.
|
||||
/* Optional lookup tables for content inspection of message headers
|
||||
/* that are produced by Milter applications.
|
||||
/* MIME PROCESSING CONTROLS
|
||||
/* .ad
|
||||
/* .fi
|
||||
|
@ -263,15 +263,40 @@ static char *cleanup_milter_hbc_extend(void *context, const char *command,
|
||||
#define STREQUAL(x,y,l) (strncasecmp((x), (y), (l)) == 0 && (y)[l] == 0)
|
||||
|
||||
/*
|
||||
* We log all header/body-checks actions here, because we know the
|
||||
* details of the message content that triggered the action. We also
|
||||
* report detail-free milter-reply values to the caller through the
|
||||
* milter_hbc_reply state member, so that up-stream code can stop sending
|
||||
* requests after e.g., reject or discard.
|
||||
*
|
||||
* As enforced elsewhere, this code is not called when (state->flags &
|
||||
* CLEANUP_FLAG_FILTER_ALL) == 0.
|
||||
* These are currently our mutually-exclusive ways of not receiving mail:
|
||||
* "reject" and "discard". Only these can be reported to the up-stream
|
||||
* Postfix libmilter code, because sending any reply there causes Postfix
|
||||
* libmilter to skip further "edit" requests. By way of safety net, each
|
||||
* of these must also reset CLEANUP_FLAG_FILTER_ALL.
|
||||
*/
|
||||
#define CLEANUP_MILTER_REJECTING_OR_DISCARDING_MESSAGE(state) \
|
||||
((state->flags & CLEANUP_FLAG_DISCARD) || (state->errs & CLEANUP_STAT_CONT))
|
||||
|
||||
/*
|
||||
* We log all header/body-checks actions here, because we know the
|
||||
* details of the message content that triggered the action. We report
|
||||
* detail-free milter-reply values (reject/discard, stored in the
|
||||
* milter_hbc_reply state member) to the Postfix libmilter code, so that
|
||||
* Postfix libmilter can stop sending requests.
|
||||
*
|
||||
* We also set all applicable cleanup flags here, because there is no
|
||||
* guarantee that Postfix libmilter will propagate our own milter-reply
|
||||
* value to cleanup_milter_inspect() which calls cleanup_milter_apply().
|
||||
* The latter translates responses from Milter applications into cleanup
|
||||
* flags, and logs the response text. Postfix libmilter can convey only
|
||||
* one milter-reply value per email message, and that reply may even come
|
||||
* from outside Postfix.
|
||||
*
|
||||
* To suppress redundant logging, cleanup_milter_apply() does nothing when
|
||||
* the milter-reply value matches the saved text in the milter_hbc_reply
|
||||
* state member. As we remember only one milter-reply value, we can't
|
||||
* report multiple milter-reply values per email message. We satisfy this
|
||||
* constraint, because we already clear the CLEANUP_FLAG_FILTER_ALL flags
|
||||
* to terminate further header inspection.
|
||||
*/
|
||||
if ((state->flags & CLEANUP_FLAG_FILTER_ALL) == 0)
|
||||
return ((char *) buf);
|
||||
|
||||
if (STREQUAL(command, "REJECT", cmd_len)) {
|
||||
const CLEANUP_STAT_DETAIL *detail;
|
||||
|
||||
@ -288,9 +313,14 @@ static char *cleanup_milter_hbc_extend(void *context, const char *command,
|
||||
} else {
|
||||
state->reason = dsn_prepend(detail->dsn, detail->text);
|
||||
}
|
||||
if (*state->reason == '4')
|
||||
state->errs |= CLEANUP_STAT_DEFER;
|
||||
else
|
||||
state->errs |= CLEANUP_STAT_CONT;
|
||||
state->flags &= ~CLEANUP_FLAG_FILTER_ALL;
|
||||
cleanup_milter_hbc_log((void *) state, "reject", where, buf, state->reason);
|
||||
vstring_sprintf(state->milter_hbc_reply, "%d %s", detail->smtp, state->reason);
|
||||
cleanup_milter_hbc_log(context, "reject", where, buf, state->reason);
|
||||
vstring_sprintf(state->milter_hbc_reply, "%d %s",
|
||||
detail->smtp, state->reason);
|
||||
STR(state->milter_hbc_reply)[0] = *state->reason;
|
||||
return ((char *) buf);
|
||||
}
|
||||
@ -305,21 +335,22 @@ static char *cleanup_milter_hbc_extend(void *context, const char *command,
|
||||
if (state->filter)
|
||||
myfree(state->filter);
|
||||
state->filter = mystrdup(optional_text);
|
||||
cleanup_milter_hbc_log((void *) state, "filter", where, buf,
|
||||
cleanup_milter_hbc_log(context, "filter", where, buf,
|
||||
optional_text);
|
||||
}
|
||||
return ((char *) buf);
|
||||
}
|
||||
if (STREQUAL(command, "DISCARD", cmd_len)) {
|
||||
cleanup_milter_hbc_log((void *) state, "discard", where, buf, optional_text);
|
||||
cleanup_milter_hbc_log(context, "discard", where, buf, optional_text);
|
||||
vstring_strcpy(state->milter_hbc_reply, "D");
|
||||
state->flags |= CLEANUP_FLAG_DISCARD;
|
||||
state->flags &= ~CLEANUP_FLAG_FILTER_ALL;
|
||||
return ((char *) buf);
|
||||
}
|
||||
if (STREQUAL(command, "HOLD", cmd_len)) {
|
||||
if ((state->flags & CLEANUP_FLAG_HOLD) == 0) {
|
||||
cleanup_milter_hbc_log((void *) state, "hold", where, buf, optional_text);
|
||||
vstring_strcpy(state->milter_hbc_reply, "H");
|
||||
if ((state->flags & (CLEANUP_FLAG_HOLD | CLEANUP_FLAG_DISCARD)) == 0) {
|
||||
cleanup_milter_hbc_log(context, "hold", where, buf, optional_text);
|
||||
state->flags |= CLEANUP_FLAG_HOLD;
|
||||
}
|
||||
return ((char *) buf);
|
||||
}
|
||||
@ -332,7 +363,7 @@ static char *cleanup_milter_hbc_extend(void *context, const char *command,
|
||||
if (state->redirect)
|
||||
myfree(state->redirect);
|
||||
state->redirect = mystrdup(optional_text);
|
||||
cleanup_milter_hbc_log((void *) state, "redirect", where, buf,
|
||||
cleanup_milter_hbc_log(context, "redirect", where, buf,
|
||||
optional_text);
|
||||
state->flags &= ~CLEANUP_FLAG_FILTER_ALL;
|
||||
}
|
||||
@ -367,17 +398,17 @@ static int cleanup_milter_header_checks(CLEANUP_STATE *state, VSTRING *buf)
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup_milter_hbc_add_meta - add REDIRECT or FILTER meta records */
|
||||
/* cleanup_milter_hbc_add_meta_records - add REDIRECT or FILTER meta records */
|
||||
|
||||
static void cleanup_milter_hbc_add_meta(CLEANUP_STATE *state)
|
||||
static void cleanup_milter_hbc_add_meta_records(CLEANUP_STATE *state)
|
||||
{
|
||||
const char *myname = "cleanup_milter_hbc_add_meta";
|
||||
const char *myname = "cleanup_milter_hbc_add_meta_records";
|
||||
off_t reverse_ptr_offset;
|
||||
off_t new_meta_offset;
|
||||
|
||||
/*
|
||||
* Note: this code runs while the Milter infrastructure is being torn
|
||||
* down. For this reason we handle all I/O errors here on the spot
|
||||
* down. For this reason we handle all I/O errors here on the spot,
|
||||
* instead of reporting them back through the Milter infrastructure.
|
||||
*/
|
||||
|
||||
@ -395,7 +426,7 @@ static void cleanup_milter_hbc_add_meta(CLEANUP_STATE *state)
|
||||
* target of the old "meta record append" pointer record. This reverse
|
||||
* pointer record becomes the new "meta record append" pointer record.
|
||||
* Although the new "meta record append" pointer record will never be
|
||||
* used we update it here to make the code more similar to other code
|
||||
* used, we update it here to make the code more similar to other code
|
||||
* that inserts/appends content, so that common code can be factored out
|
||||
* later.
|
||||
*/
|
||||
@ -436,6 +467,10 @@ static void cleanup_milter_hbc_add_meta(CLEANUP_STATE *state)
|
||||
* that was written while Postfix received the message.
|
||||
*/
|
||||
state->append_meta_pt_offset = reverse_ptr_offset;
|
||||
|
||||
/*
|
||||
* Note: state->append_meta_pt_target never changes.
|
||||
*/
|
||||
}
|
||||
|
||||
/* cleanup_milter_header_checks_init - initialize post-Milter header checks */
|
||||
@ -477,8 +512,10 @@ static void cleanup_milter_hbc_finish(CLEANUP_STATE *state)
|
||||
if (state->milter_hbc_reply)
|
||||
vstring_free(state->milter_hbc_reply);
|
||||
state->milter_hbc_reply = 0;
|
||||
if (CLEANUP_OUT_OK(state) && (state->filter || state->redirect))
|
||||
cleanup_milter_hbc_add_meta(state);
|
||||
if (CLEANUP_OUT_OK(state)
|
||||
&& !CLEANUP_MILTER_REJECTING_OR_DISCARDING_MESSAGE(state)
|
||||
&& (state->filter || state->redirect))
|
||||
cleanup_milter_hbc_add_meta_records(state);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -577,7 +614,6 @@ static const char *cleanup_add_header(void *context, const char *name,
|
||||
buf = vstring_alloc(100);
|
||||
vstring_sprintf(buf, "%s:%s%s", name, space, value);
|
||||
if (state->milter_hbc_checks
|
||||
&& (state->flags & CLEANUP_FLAG_FILTER_ALL)
|
||||
&& cleanup_milter_header_checks(state, buf) == 0) {
|
||||
vstring_free(buf);
|
||||
return (0);
|
||||
@ -637,7 +673,7 @@ static const char *cleanup_add_header(void *context, const char *name,
|
||||
STR(state->milter_hbc_reply) : 0);
|
||||
|
||||
/*
|
||||
* Note: state->append_meta_pt_target never changes.
|
||||
* Note: state->append_hdr_pt_target never changes.
|
||||
*/
|
||||
}
|
||||
|
||||
@ -960,7 +996,6 @@ static const char *cleanup_patch_header(CLEANUP_STATE *state,
|
||||
*/
|
||||
vstring_sprintf(buf, "%s:%s%s", new_hdr_name, hdr_space, new_hdr_value);
|
||||
if (state->milter_hbc_checks
|
||||
&& (state->flags & CLEANUP_FLAG_FILTER_ALL)
|
||||
&& cleanup_milter_header_checks(state, buf) == 0)
|
||||
CLEANUP_PATCH_HEADER_RETURN(0);
|
||||
|
||||
@ -1786,6 +1821,29 @@ static const char *cleanup_milter_apply(CLEANUP_STATE *state, const char *event,
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s", myname, resp);
|
||||
|
||||
/*
|
||||
* Don't process our own milter_header/body checks replies. See comments
|
||||
* in cleanup_milter_hbc_extend().
|
||||
*/
|
||||
if (state->milter_hbc_reply &&
|
||||
strcmp(resp, STR(state->milter_hbc_reply)) == 0)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Don't process Milter replies that are redundant because header/body
|
||||
* checks already decided that we will not receive the message; or Milter
|
||||
* replies that would have conflicting effect with the outcome of
|
||||
* header/body checks (for example, header_checks "discard" action
|
||||
* followed by Milter "reject" reply). Logging both actions would look
|
||||
* silly.
|
||||
*/
|
||||
if (CLEANUP_MILTER_REJECTING_OR_DISCARDING_MESSAGE(state)) {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: ignoring redundant or conflicting milter reply: %s",
|
||||
state->queue_id, resp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
*/
|
||||
@ -1847,13 +1905,6 @@ static const char *cleanup_milter_apply(CLEANUP_STATE *state, const char *event,
|
||||
default:
|
||||
msg_panic("%s: unexpected mail filter reply: %s", myname, resp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't log milter_header/body checks actions again.
|
||||
*/
|
||||
if (state->milter_hbc_reply && strcmp(resp, STR(state->milter_hbc_reply)) == 0)
|
||||
return (ret);
|
||||
|
||||
vstring_sprintf(state->temp1, "%s: %s: %s from %s[%s]: %s;",
|
||||
state->queue_id, action, event, state->client_name,
|
||||
state->client_addr, text);
|
||||
@ -2137,8 +2188,12 @@ static void usage(void)
|
||||
msg_warn(" ins_header index name [value]");
|
||||
msg_warn(" upd_header index name [value]");
|
||||
msg_warn(" del_header index name");
|
||||
msg_warn(" chg_from addr parameters");
|
||||
msg_warn(" add_rcpt addr");
|
||||
msg_warn(" add_rcpt_par addr parameters");
|
||||
msg_warn(" del_rcpt addr");
|
||||
msg_warn(" replbody pathname");
|
||||
msg_warn(" header_checks type:name");
|
||||
}
|
||||
|
||||
/* flatten_args - unparse partial command line */
|
||||
@ -2327,9 +2382,17 @@ int main(int unused_argc, char **argv)
|
||||
} else if (state->dst == 0) {
|
||||
msg_warn("no open queue file");
|
||||
} else if (strcmp(argv->argv[0], "close") == 0) {
|
||||
if (*var_milt_head_checks)
|
||||
if (*var_milt_head_checks) {
|
||||
cleanup_milter_hbc_finish(state);
|
||||
var_milt_head_checks = "";
|
||||
}
|
||||
close_queue_file(state);
|
||||
} else if (state->milter_hbc_reply && LEN(state->milter_hbc_reply)) {
|
||||
/* Postfix libmilter would skip further requests. */
|
||||
msg_info("ignoring: %s %s %s", argv->argv[0],
|
||||
argv->argc > 1 ? argv->argv[1] : "",
|
||||
argv->argc > 2 ? argv->argv[2] : "");
|
||||
continue;
|
||||
} else if (strcmp(argv->argv[0], "add_header") == 0) {
|
||||
if (argv->argc < 2) {
|
||||
msg_warn("bad add_header argument count: %d", argv->argc);
|
||||
|
11
postfix/src/cleanup/cleanup_milter.in15h
Normal file
11
postfix/src/cleanup/cleanup_milter.in15h
Normal file
@ -0,0 +1,11 @@
|
||||
#verbose on
|
||||
open test-queue-file15h.tmp
|
||||
|
||||
# Test the CLEANUP_FILTER_FLAG_ALL feature. The first header with
|
||||
# YES clears the flag, and the second add_header is ignored.
|
||||
|
||||
header_checks regexp:cleanup_milter.reg15h
|
||||
add_header X-SPAM-FLAG YES
|
||||
add_header X-SPAM-FLAG NO
|
||||
|
||||
close
|
11
postfix/src/cleanup/cleanup_milter.in15i
Normal file
11
postfix/src/cleanup/cleanup_milter.in15i
Normal file
@ -0,0 +1,11 @@
|
||||
#verbose on
|
||||
open test-queue-file15i.tmp
|
||||
|
||||
# Test the CLEANUP_STAT_CONT flag. The first header triggers FILTER,
|
||||
# but the second header triggers REJECT, so the filter is not saved.
|
||||
|
||||
header_checks regexp:cleanup_milter.reg15i
|
||||
add_header X-SPAM-FLAG NO
|
||||
add_header X-SPAM-FLAG YES
|
||||
|
||||
close
|
@ -16,9 +16,7 @@
|
||||
402 regular_text: Message-Id: <20090605180519.DA4892510C1@ahost.example.com>
|
||||
462 regular_text: Date: Fri, 5 Jun 2009 14:05:19 -0400 (EDT)
|
||||
507 regular_text: From: wietse@ahost.example.com (Wietse Venema)
|
||||
555 pointer_record: 642
|
||||
642 regular_text: X-SPAM-FLAG: YES
|
||||
660 pointer_record: 572
|
||||
555 pointer_record: 0
|
||||
572 regular_text:
|
||||
574 regular_text: Fri Jun 5 14:05:19 EDT 2009
|
||||
604 pointer_record: 0
|
||||
|
@ -14,9 +14,7 @@
|
||||
367 regular_text: Message-Id: <20090605180634.06F8B2510C2@ahost.example.com>
|
||||
427 regular_text: Date: Fri, 5 Jun 2009 14:06:34 -0400 (EDT)
|
||||
472 regular_text: From: wietse@ahost.example.com (Wietse Venema)
|
||||
520 pointer_record: 641
|
||||
641 regular_text: X-SPAM-FLAG: YES
|
||||
659 pointer_record: 537
|
||||
520 pointer_record: 0
|
||||
537 regular_text:
|
||||
539 regular_text: Fri Jun 5 14:06:34 EDT 2009
|
||||
569 pointer_record: 0
|
||||
|
3
postfix/src/cleanup/cleanup_milter.ref15h1
Normal file
3
postfix/src/cleanup/cleanup_milter.ref15h1
Normal file
@ -0,0 +1,3 @@
|
||||
./cleanup_milter: NOQUEUE: milter-header-reject: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: 5.7.1 whatever
|
||||
./cleanup_milter: ignoring: add_header X-SPAM-FLAG NO
|
||||
./cleanup_milter: errs = message content rejected
|
27
postfix/src/cleanup/cleanup_milter.ref15h2
Normal file
27
postfix/src/cleanup/cleanup_milter.ref15h2
Normal file
@ -0,0 +1,27 @@
|
||||
*** ENVELOPE RECORDS test-queue-file15h.tmp ***
|
||||
0 message_size: 365 221 1 0 365
|
||||
81 message_arrival_time: Fri Jun 5 14:06:34 2009
|
||||
99 create_time: Fri Jun 5 14:06:34 2009
|
||||
123 named_attribute: rewrite_context=local
|
||||
146 sender_fullname: Wietse Venema
|
||||
161 sender: wietse@ahost.example.com
|
||||
187 pointer_record: 0
|
||||
202 pointer_record: 0
|
||||
219 *** MESSAGE CONTENTS test-queue-file15h.tmp ***
|
||||
221 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
|
||||
281 regular_text: id 06F8B2510C2; Fri, 5 Jun 2009 14:06:34 -0400 (EDT)
|
||||
337 regular_text: To: wietse@ahost.example.com
|
||||
367 regular_text: Message-Id: <20090605180634.06F8B2510C2@ahost.example.com>
|
||||
427 regular_text: Date: Fri, 5 Jun 2009 14:06:34 -0400 (EDT)
|
||||
472 regular_text: From: wietse@ahost.example.com (Wietse Venema)
|
||||
520 pointer_record: 641
|
||||
641 regular_text: X-SPAM-FLAG: YES
|
||||
659 pointer_record: 537
|
||||
537 regular_text:
|
||||
539 regular_text: Fri Jun 5 14:06:34 EDT 2009
|
||||
569 pointer_record: 0
|
||||
586 *** HEADER EXTRACTED test-queue-file15h.tmp ***
|
||||
588 pointer_record: 0
|
||||
605 original_recipient: wietse
|
||||
613 recipient: wietse@ahost.example.com
|
||||
639 *** MESSAGE FILE END test-queue-file15h.tmp ***
|
3
postfix/src/cleanup/cleanup_milter.ref15i1
Normal file
3
postfix/src/cleanup/cleanup_milter.ref15i1
Normal file
@ -0,0 +1,3 @@
|
||||
./cleanup_milter: NOQUEUE: milter-header-filter: header X-SPAM-FLAG: NO from client_name[client_addr]; from=<sender> to=<recipient>: x:y:z
|
||||
./cleanup_milter: NOQUEUE: milter-header-reject: header X-SPAM-FLAG: YES from client_name[client_addr]; from=<sender> to=<recipient>: 5.7.1 whatever
|
||||
./cleanup_milter: errs = message content rejected
|
29
postfix/src/cleanup/cleanup_milter.ref15i2
Normal file
29
postfix/src/cleanup/cleanup_milter.ref15i2
Normal file
@ -0,0 +1,29 @@
|
||||
*** ENVELOPE RECORDS test-queue-file15i.tmp ***
|
||||
0 message_size: 365 221 1 0 365
|
||||
81 message_arrival_time: Fri Jun 5 14:06:34 2009
|
||||
99 create_time: Fri Jun 5 14:06:34 2009
|
||||
123 named_attribute: rewrite_context=local
|
||||
146 sender_fullname: Wietse Venema
|
||||
161 sender: wietse@ahost.example.com
|
||||
187 pointer_record: 0
|
||||
202 pointer_record: 0
|
||||
219 *** MESSAGE CONTENTS test-queue-file15i.tmp ***
|
||||
221 regular_text: Received: by ahost.example.com (Postfix, from userid 1001)
|
||||
281 regular_text: id 06F8B2510C2; Fri, 5 Jun 2009 14:06:34 -0400 (EDT)
|
||||
337 regular_text: To: wietse@ahost.example.com
|
||||
367 regular_text: Message-Id: <20090605180634.06F8B2510C2@ahost.example.com>
|
||||
427 regular_text: Date: Fri, 5 Jun 2009 14:06:34 -0400 (EDT)
|
||||
472 regular_text: From: wietse@ahost.example.com (Wietse Venema)
|
||||
520 pointer_record: 641
|
||||
641 regular_text: X-SPAM-FLAG: NO
|
||||
658 pointer_record: 675
|
||||
675 regular_text: X-SPAM-FLAG: YES
|
||||
693 pointer_record: 537
|
||||
537 regular_text:
|
||||
539 regular_text: Fri Jun 5 14:06:34 EDT 2009
|
||||
569 pointer_record: 0
|
||||
586 *** HEADER EXTRACTED test-queue-file15i.tmp ***
|
||||
588 pointer_record: 0
|
||||
605 original_recipient: wietse
|
||||
613 recipient: wietse@ahost.example.com
|
||||
639 *** MESSAGE FILE END test-queue-file15i.tmp ***
|
2
postfix/src/cleanup/cleanup_milter.reg15h
Normal file
2
postfix/src/cleanup/cleanup_milter.reg15h
Normal file
@ -0,0 +1,2 @@
|
||||
/YES/ reject whatever
|
||||
/NO/ filter x:y:z
|
2
postfix/src/cleanup/cleanup_milter.reg15i
Normal file
2
postfix/src/cleanup/cleanup_milter.reg15i
Normal file
@ -0,0 +1,2 @@
|
||||
/YES/ reject whatever
|
||||
/NO/ filter x:y:z
|
@ -20,7 +20,7 @@
|
||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||
* patchlevel; they change the release date only.
|
||||
*/
|
||||
#define MAIL_RELEASE_DATE "20090606"
|
||||
#define MAIL_RELEASE_DATE "20090607"
|
||||
#define MAIL_VERSION_NUMBER "2.7"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
|
@ -39,7 +39,7 @@
|
||||
/* Insert header at specified position.
|
||||
/* .IP "\fB-l\fR"
|
||||
/* Header values include leading space. Specify this option
|
||||
/* before \fB-i\fR or \fB-r\fR.
|
||||
/* before \fB-i\fR or \fB-h\fR.
|
||||
/* .IP "\fB-m connect|helo|mail|rcpt|data|eoh|eom\fR"
|
||||
/* The protocol stage that receives the list of macros specified
|
||||
/* with \fB-M\fR. The default protocol stage is \fBconnect\fR.
|
||||
@ -342,8 +342,6 @@ static sfsistat test_eom(SMFICTX *ctx)
|
||||
#ifdef SMFIR_CHGFROM
|
||||
if (chg_from != 0 && smfi_chgfrom(ctx, chg_from, "whatever") == MI_FAILURE)
|
||||
fprintf(stderr, "smfi_chgfrom failed\n");
|
||||
else
|
||||
printf("smfi_chgfrom OK\n");
|
||||
#endif
|
||||
#ifdef SMFIR_INSHEADER
|
||||
if (ins_hdr && smfi_insheader(ctx, ins_idx, ins_hdr, ins_val) == MI_FAILURE)
|
||||
|
@ -10,7 +10,7 @@ MAKES = bool_table.h bool_vars.h int_table.h int_vars.h str_table.h \
|
||||
str_vars.h time_table.h time_vars.h raw_table.h raw_vars.h \
|
||||
nint_table.h nint_vars.h
|
||||
AUTOS = auto_table.h auto_vars.h
|
||||
DUMMIES = makes_dummy autos_dummy
|
||||
DUMMIES = makes_dummy autos_dummy # for "make -j"
|
||||
PROG = postconf
|
||||
SAMPLES = ../../conf/main.cf.default
|
||||
INC_DIR = ../../include
|
||||
|
@ -1471,7 +1471,7 @@ typedef int pid_t;
|
||||
* sections above.
|
||||
*/
|
||||
#ifndef PRINTFLIKE
|
||||
#if (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) || __GNUC__ == 3
|
||||
#if (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) || __GNUC__ >= 3
|
||||
#define PRINTFLIKE(x,y) __attribute__ ((format (printf, (x), (y))))
|
||||
#else
|
||||
#define PRINTFLIKE(x,y)
|
||||
|
Loading…
x
Reference in New Issue
Block a user