2
0
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:
Wietse Venema 2009-06-07 00:00:00 -05:00 committed by Viktor Dukhovni
parent c3440e3338
commit e3121fd2b8
25 changed files with 336 additions and 103 deletions

View File

@ -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.

View File

@ -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.

View File

@ -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
;;

View File

@ -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:

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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 \

View File

@ -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

View File

@ -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);

View 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

View 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

View File

@ -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

View File

@ -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

View 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

View 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 ***

View 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

View 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 ***

View File

@ -0,0 +1,2 @@
/YES/ reject whatever
/NO/ filter x:y:z

View File

@ -0,0 +1,2 @@
/YES/ reject whatever
/NO/ filter x:y:z

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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)