mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 05:38:06 +00:00
snapshot-20000531
This commit is contained in:
parent
df9542112c
commit
a8e8c4d123
205
postfix/FILTER_README
Normal file
205
postfix/FILTER_README
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
This is a very first implementation of Postfix content filtering.
|
||||||
|
It involves an incompatible change to queue file formats. Older
|
||||||
|
Postfix versions will reject mail that needs to be content filtered,
|
||||||
|
and will move the queue file to the "corrupt" mail queue subdirectory.
|
||||||
|
|
||||||
|
This document describes two approaches to content filtering.
|
||||||
|
|
||||||
|
Simple content filtering example
|
||||||
|
================================
|
||||||
|
|
||||||
|
The first example is simpler to set up, but is also more resource
|
||||||
|
intensive. With the shell script as shown you will lose a factor
|
||||||
|
of four in Postfix performance for transit mail that arrives and
|
||||||
|
leaves via SMTP. You will lose another factor in transit performance
|
||||||
|
for each additional temporary file that is created and deleted in
|
||||||
|
the process of content filtering. The performance impact is less
|
||||||
|
for mail that is submitted or delivered locally, because such
|
||||||
|
deliveries are not as fast as SMTP transit mail.
|
||||||
|
|
||||||
|
The example assumes that only mail arriving via SMTP needs to be
|
||||||
|
content filtered.
|
||||||
|
|
||||||
|
..................................
|
||||||
|
. Postfix .
|
||||||
|
------smtpd \ /local-----
|
||||||
|
. -cleanup->queue- .
|
||||||
|
-----pickup / \smtp------
|
||||||
|
^ . | .
|
||||||
|
| . \pipe-----+
|
||||||
|
| .................................. |
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
+------sendmail<-------filter<---------+
|
||||||
|
|
||||||
|
Create a dedicated local user account called "filter". The user
|
||||||
|
will never log in, and can be given a "*" password and non-existent
|
||||||
|
shell and home.
|
||||||
|
|
||||||
|
Create a directory /var/spool/filter that is accessible only to
|
||||||
|
the "filter" user. This is where the content filtering will store
|
||||||
|
its temporary files.
|
||||||
|
|
||||||
|
Define a content filtering entry in the Postfix master file:
|
||||||
|
|
||||||
|
/etc/postfix/master.cf:
|
||||||
|
filter unix - n n - - pipe
|
||||||
|
user=filter argv=/some/where/filter -f ${sender} -- ${recipient}
|
||||||
|
|
||||||
|
The filter program can start out as a simple shell script like this:
|
||||||
|
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Localize these
|
||||||
|
INSPECT_DIR=/var/spool/filter
|
||||||
|
SENDMAIL=/usr/sbin/sendmail
|
||||||
|
|
||||||
|
# Exit codes from <sysexits.h>
|
||||||
|
EX_TEMPFAIL=75
|
||||||
|
EX_UNAVAILABLE=69
|
||||||
|
|
||||||
|
cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
|
||||||
|
|
||||||
|
# Clean up when done or when aborting.
|
||||||
|
trap "rm -f in.$$; exit" 0 1 2 3 15
|
||||||
|
|
||||||
|
cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }
|
||||||
|
|
||||||
|
# filter <in.$$ || { echo Message content rejected; exit $EX_UNAVAILABLE; }
|
||||||
|
|
||||||
|
$SENDMAIL "$@" <in.$$
|
||||||
|
|
||||||
|
exit $?
|
||||||
|
|
||||||
|
The idea is to first capture the message to file and then run the
|
||||||
|
content through run a third-party content filter program. If the
|
||||||
|
mail cannot be captured to file, mail delivery is deferred by
|
||||||
|
terminating with exit status 75 (EX_TEMPFAIL). If the content
|
||||||
|
filter program finds a problem, the mail is bounced by terminating
|
||||||
|
the filter command with exit status 69 (EX_UNAVAILABLE). If the
|
||||||
|
content is OK, it is given as input to Postfix sendmail, and the
|
||||||
|
exit status of the filter command is whatever exit status Postfix
|
||||||
|
sendmail produces.
|
||||||
|
|
||||||
|
The problem with content filterings like this is that they are not
|
||||||
|
very robust, because they do not talk a well-defined protocol with
|
||||||
|
Postfix. If the filter command aborts because of some memory
|
||||||
|
allocation problem, it will not produce a nice exit status as per
|
||||||
|
/usr/include/sysexits.h and mail will probably bounce. The same
|
||||||
|
lack of robustness is possible when the content filtering software
|
||||||
|
itself runs into a resource problem.
|
||||||
|
|
||||||
|
I suggest that you play with this script for a while until you are
|
||||||
|
satisfied with the results. Run it as root or as the filter user,
|
||||||
|
with a real message (headers+body) as input:
|
||||||
|
|
||||||
|
# /some/where/filter -f sender recipient... <message-file
|
||||||
|
|
||||||
|
Turn on content filtering for mail arriving via SMTP only, by
|
||||||
|
appending "-o content_filter=filter:dummy" to the master.cf
|
||||||
|
entry that defines the Postfix SMTP server:
|
||||||
|
|
||||||
|
/etc/postfix/master.cf:
|
||||||
|
smtp inet ...stuff... smtpd
|
||||||
|
-o content_filter=filter:dummy
|
||||||
|
|
||||||
|
The content_filter configuration parameter accepts the same
|
||||||
|
syntax as the right-hand side in a Postfix transport table.
|
||||||
|
|
||||||
|
Postfix snapshot-20000529 requires that you specify a dummy
|
||||||
|
destination as shown in the example. This is no longer necessary
|
||||||
|
with later Postfix versions.
|
||||||
|
|
||||||
|
Advanced content filtering example
|
||||||
|
===================================
|
||||||
|
|
||||||
|
The second example is considerably more complex, but can give much
|
||||||
|
better performance, and is less likely to bounce mail when the
|
||||||
|
machine runs into a resource problem. This approach uses content
|
||||||
|
filtering software that can receive and deliver mail via SMTP.
|
||||||
|
You can expect to lose about a factor of two in Postfix performance
|
||||||
|
for transit mail that arrives and leaves via SMTP, provided that
|
||||||
|
you create no temporary files. Each temporary file adds another
|
||||||
|
factor to the performance loss.
|
||||||
|
|
||||||
|
We will set up a content filtering program listening on localhost
|
||||||
|
port 10025 that receives mail via the SMTP protocol, and that
|
||||||
|
submits mail back into Postfix via localhost port 10026.
|
||||||
|
|
||||||
|
..................................
|
||||||
|
. Postfix .
|
||||||
|
------smtpd \ /local-----
|
||||||
|
. -cleanup->queue- .
|
||||||
|
-----pickup / ^ | \smtp------
|
||||||
|
. | v .
|
||||||
|
. smtpd smtp .
|
||||||
|
. 10026 | .
|
||||||
|
......................|...........
|
||||||
|
^ |
|
||||||
|
| v
|
||||||
|
....|............
|
||||||
|
. | 10025 .
|
||||||
|
. filtering .
|
||||||
|
. .
|
||||||
|
.................
|
||||||
|
|
||||||
|
To enable content filtering in this manner, specify in main.cf a
|
||||||
|
new parameter:
|
||||||
|
|
||||||
|
/etc/postfix/main.cf:
|
||||||
|
content_filter = smtp:localhost:10025
|
||||||
|
|
||||||
|
This causes Postfix to add one extra content filtering record to
|
||||||
|
each incoming mail message, with content smtp:localhost:10025.
|
||||||
|
You can use the same syntax as in the right-hand side of a Postfix
|
||||||
|
transport table. The content filtering records are added by the
|
||||||
|
smtpd and pickup servers.
|
||||||
|
|
||||||
|
When a queue file has content filtering information, the queue
|
||||||
|
manager will deliver the mail to the specified content filtering
|
||||||
|
regardless of its final destination.
|
||||||
|
|
||||||
|
The content filtering can be set up with the Postfix spawn service,
|
||||||
|
which is the Postfix equivalent of inetd. For example, to instantiate
|
||||||
|
up to 10 content filtering processes on demand:
|
||||||
|
|
||||||
|
/etc/postfix/master.cf:
|
||||||
|
localhost:10025 inet n n n - 10 spawn
|
||||||
|
user=filter argv=/some/where/filter localhost 10026
|
||||||
|
|
||||||
|
"filter" is a dedicated local user account. The user will never
|
||||||
|
log in, and can be given a "*" password and non-existent shell and
|
||||||
|
home.
|
||||||
|
|
||||||
|
The spawn server is part of Postfix but is not installed by default.
|
||||||
|
Edit the top-level Makefile.in file, run "make makefiles", "make",
|
||||||
|
and "make install". The manual page isn't installed by default,
|
||||||
|
either. See the spawn.c source file.
|
||||||
|
|
||||||
|
The /some/where/filter command is most likely a PERL script. PERL
|
||||||
|
has modules that make talking SMTP easy. The command-line specifies
|
||||||
|
that mail should be sent back into Postfix via localhost port 10026.
|
||||||
|
|
||||||
|
For now, it is left up to the Postfix users to come up with a
|
||||||
|
PERL/SMTP framework for Postfix content filtering. If done well,
|
||||||
|
it can be used with other mailers too, which is a nice spin-off.
|
||||||
|
|
||||||
|
The simplest content filtering just copies SMTP commands and data
|
||||||
|
between its inputs and outputs. If it has a problem, all it has to
|
||||||
|
do is to reply to an input of `.' with `550 content rejected', and
|
||||||
|
to disconnect its output side instead of sending `.'.
|
||||||
|
|
||||||
|
The job of the content filtering is to either bounce mail with a
|
||||||
|
suitable diagnostic, or to feed the mail back into Postfix through
|
||||||
|
a dedicated listener on port localhost 10026:
|
||||||
|
|
||||||
|
/etc/postfix/master.cf:
|
||||||
|
localhost:10026 inet n - n - 10 smtpd
|
||||||
|
-o content_filter= myhostname=localhost.domain.name
|
||||||
|
|
||||||
|
This is just another SMTP server. It is configured NOT to request
|
||||||
|
content filtering for incoming mail, has the same process limit
|
||||||
|
as the filter master.cf entry, and is configured to use a different
|
||||||
|
hostname in the greeting message (this is necessary for testing
|
||||||
|
when I simply use no filtering program and let the SMTP content
|
||||||
|
filtering interfaces talk directly to each other).
|
@ -4010,11 +4010,25 @@ Apologies for any names omitted.
|
|||||||
feature. File: cleanup/cleanup_message.c. See also the
|
feature. File: cleanup/cleanup_message.c. See also the
|
||||||
conf/sample-filter.cf file.
|
conf/sample-filter.cf file.
|
||||||
|
|
||||||
20000529
|
20000530
|
||||||
|
|
||||||
Feature: full content inspection through external software.
|
Feature: full content filtering through external software.
|
||||||
This uses existing interfaces for sending and receiving mail
|
This uses existing interfaces for sending mail to the
|
||||||
from and to the content inspector. Currently, only the SMTP
|
external content filter and for injecting it back into
|
||||||
server is suitable for receiving inspected mail. Details
|
Postfix. Details in FILTER_README. Files: pickup/pickup.c,
|
||||||
in INSPECTION_README. Files: pickup/pickup.c, smtpd/smtpd.c,
|
smtpd/smtpd.c, qmgr/qmgr_message.c.
|
||||||
qmgr/qmgr_message.c.
|
|
||||||
|
20000531
|
||||||
|
|
||||||
|
More SASL feedback by Liviu Daia, regarding the use of
|
||||||
|
authentication realms. File smtpd/smtpd_sasl_glue.c.
|
||||||
|
|
||||||
|
Added a simple shell-script based content filtering example
|
||||||
|
to the FILTER_README file.
|
||||||
|
|
||||||
|
Content filtering support for nqmgr by Patrik Rak. File:
|
||||||
|
nqmgr/qmgr_message.c.
|
||||||
|
|
||||||
|
Renamed "content inspection" etc. to "content filtering"
|
||||||
|
in anticipation of a new hook for content inspection that
|
||||||
|
only inspects mail without re-injecting it into Postfix.
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
This is a very first implementation of Postfix content inspection.
|
|
||||||
It involves an incompatible change to queue file formats. Older
|
|
||||||
Postfix versions will move the mail aside to the "corrupt" mail
|
|
||||||
queue subdirectory.
|
|
||||||
|
|
||||||
The example uses content inspection software that can receive and
|
|
||||||
deliver mail via SMTP. At present, Postfix can receive already
|
|
||||||
inspected mail only via SMTP. In the future it may become possible
|
|
||||||
to submit already filtered mail via the postdrop command. However,
|
|
||||||
doing business over SMTP is much less inefficient.
|
|
||||||
|
|
||||||
We will set up a content inspector program listening on localhost
|
|
||||||
port 10025 that receives mail via the SMTP protocol, and that
|
|
||||||
submits mail back into Postfix via localhost port 10026.
|
|
||||||
|
|
||||||
..................................
|
|
||||||
. Postfix .
|
|
||||||
------smtpd \ /local-----
|
|
||||||
. -cleanup->queue- .
|
|
||||||
-----pickup / ^ | \smtp------
|
|
||||||
. | v .
|
|
||||||
. smtpd smtp .
|
|
||||||
. 10026 | .
|
|
||||||
......................|...........
|
|
||||||
^ |
|
|
||||||
| v
|
|
||||||
....|............
|
|
||||||
. | 10025 .
|
|
||||||
. inspector .
|
|
||||||
. .
|
|
||||||
.................
|
|
||||||
|
|
||||||
To enable content inspection in this manner, specify in main.cf a
|
|
||||||
new parameter:
|
|
||||||
|
|
||||||
/etc/postfix/main.cf:
|
|
||||||
content_inspector = smtp:localhost:10025
|
|
||||||
|
|
||||||
This causes Postfix to add one extra content inspection record to
|
|
||||||
each incoming mail message, with content smtp:localhost:10025.
|
|
||||||
You can use the same syntax as in the right-hand side of a Postfix
|
|
||||||
transport table. The content inspection records are added by the
|
|
||||||
smtpd and pickup servers.
|
|
||||||
|
|
||||||
When a queue file has content inspection information, the queue
|
|
||||||
manager will deliver the mail to the specified content inspector
|
|
||||||
regardless of its final destination.
|
|
||||||
|
|
||||||
Setting up the content inspector could be done with the Postfix
|
|
||||||
spawn service, to instantiate up to 10 processes on demand:
|
|
||||||
|
|
||||||
/etc/postfix/master.cf:
|
|
||||||
localhost:10025 inet - n n - 10 spawn
|
|
||||||
user=inspect argv=/some/where/inspect localhost 10026
|
|
||||||
|
|
||||||
The spawn server is part of Postfix but is not installed by default.
|
|
||||||
Edit the top-level Makefile.in file, run "make makefiles", "make",
|
|
||||||
and "make install".
|
|
||||||
|
|
||||||
The /some/where/inspect command is most likely a PERL script. PERL
|
|
||||||
has modules that make talking SMTP easy. The command-line specifies
|
|
||||||
that mail shouldbe sent back into Postfix via localhost port 10026.
|
|
||||||
|
|
||||||
The job of the content inspector is to either bounce mail with a
|
|
||||||
suitable diagnostic, or to feed the mail back into Postfix through
|
|
||||||
a dedicated listener on port localhost 10026:
|
|
||||||
|
|
||||||
/etc/postfix/master.cf:
|
|
||||||
localhost:10026 inet n - n - 0 smtpd
|
|
||||||
-o content_inspector= myhostname=localhost.domain.name
|
|
||||||
|
|
||||||
This is just another SMTP server. It is configured NOT to request
|
|
||||||
content inspection for incoming mail, has no process limit (so
|
|
||||||
Postfix will not deadlock), and is configured to use a different
|
|
||||||
hostname in the greeting message (this is necessary for testing
|
|
||||||
when I simply use no inspector program and let the SMTP content
|
|
||||||
inspection interfaces talk directly to each other).
|
|
@ -1,22 +1,30 @@
|
|||||||
|
Incompatible changes with snapshot-20000531
|
||||||
|
===========================================
|
||||||
|
|
||||||
|
All references to "content inspection" have been replaced by "content
|
||||||
|
filtering", in anticipation of hooks for true content inspection
|
||||||
|
that does not re-inject mail back into Postfix.
|
||||||
|
|
||||||
Incompatible changes with snapshot-20000529
|
Incompatible changes with snapshot-20000529
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
This version introduces an incompatible queue file format change
|
This version introduces an incompatible queue file format change
|
||||||
when content inspection is enabled. Old Postfix queue files will
|
when content filtering is enabled. Old Postfix queue files will
|
||||||
work fine, but new queue files will not work with old Postfix
|
work fine, but new queue files with content filtering info will
|
||||||
versions. They log a warning and move incompatible queue files to
|
not work with old Postfix versions. They log a warning and move
|
||||||
the "corrupt" mail queue subdirectory.
|
incompatible queue files to the "corrupt" mail queue subdirectory.
|
||||||
|
|
||||||
Major changes with snapshot-20000529
|
Major changes with snapshot-20000529
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
This version introduces full content inspection through an external
|
This version introduces full content filtering through an external
|
||||||
process. This involves an incompatible change in queue file format.
|
process. This involves an incompatible change in queue file format.
|
||||||
Mail is delivered to content inspection software via an existing
|
Mail is delivered to content filtering software via an existing
|
||||||
mail delivery agent, and is re-injected into Postfix via an existing
|
mail delivery agent, and is re-injected into Postfix via an existing
|
||||||
mail submission agent. Presently, only the Postfix SMTP server is
|
mail submission agent. See examples in the FILTER_README file.
|
||||||
suitable for receiving already inspected mail. Details in the
|
Depending on how the filter is implemented, you can expect to lose
|
||||||
INSPECTION_README file.
|
a factor of 2 to 4 in delivery performance of SMTP transit mail,
|
||||||
|
more if the content filtering software needs lots of CPU or memory.
|
||||||
|
|
||||||
Major changes with snapshot-20000528
|
Major changes with snapshot-20000528
|
||||||
====================================
|
====================================
|
||||||
|
@ -1046,12 +1046,11 @@ extern bool var_allow_min_user;
|
|||||||
extern void mail_params_init(void);
|
extern void mail_params_init(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Content inspection transport. The things we have to do because some
|
* Content inspection and filtering.
|
||||||
* over-paid peecee programmers could not do a proper job.
|
|
||||||
*/
|
*/
|
||||||
#define VAR_INSPECT_XPORT "content_inspector"
|
#define VAR_FILTER_XPORT "content_filter"
|
||||||
#define DEF_INSPECT_XPORT ""
|
#define DEF_FILTER_XPORT ""
|
||||||
extern char *var_inspect_xport;
|
extern char *var_filter_xport;
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
/* .ad
|
/* .ad
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* Version of this program.
|
* Version of this program.
|
||||||
*/
|
*/
|
||||||
#define VAR_MAIL_VERSION "mail_version"
|
#define VAR_MAIL_VERSION "mail_version"
|
||||||
#define DEF_MAIL_VERSION "Snapshot-20000529"
|
#define DEF_MAIL_VERSION "Snapshot-20000531"
|
||||||
extern char *var_mail_version;
|
extern char *var_mail_version;
|
||||||
|
|
||||||
/* LICENSE
|
/* LICENSE
|
||||||
|
@ -44,6 +44,7 @@ REC_TYPE_NAME rec_type_names[] = {
|
|||||||
REC_TYPE_TIME, "time",
|
REC_TYPE_TIME, "time",
|
||||||
REC_TYPE_FULL, "fullname",
|
REC_TYPE_FULL, "fullname",
|
||||||
REC_TYPE_INSP, "content_inspector",
|
REC_TYPE_INSP, "content_inspector",
|
||||||
|
REC_TYPE_FILT, "content_filter",
|
||||||
REC_TYPE_FROM, "sender",
|
REC_TYPE_FROM, "sender",
|
||||||
REC_TYPE_DONE, "done",
|
REC_TYPE_DONE, "done",
|
||||||
REC_TYPE_RCPT, "recipient",
|
REC_TYPE_RCPT, "recipient",
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#define REC_TYPE_TIME 'T' /* time stamp, required */
|
#define REC_TYPE_TIME 'T' /* time stamp, required */
|
||||||
#define REC_TYPE_FULL 'F' /* full name, optional */
|
#define REC_TYPE_FULL 'F' /* full name, optional */
|
||||||
#define REC_TYPE_INSP 'I' /* inspector transport */
|
#define REC_TYPE_INSP 'I' /* inspector transport */
|
||||||
|
#define REC_TYPE_FILT 'L' /* loop filter transport */
|
||||||
#define REC_TYPE_FROM 'S' /* sender, required */
|
#define REC_TYPE_FROM 'S' /* sender, required */
|
||||||
#define REC_TYPE_DONE 'D' /* delivered recipient, optional */
|
#define REC_TYPE_DONE 'D' /* delivered recipient, optional */
|
||||||
#define REC_TYPE_RCPT 'R' /* todo recipient, optional */
|
#define REC_TYPE_RCPT 'R' /* todo recipient, optional */
|
||||||
@ -52,7 +53,7 @@
|
|||||||
* record groups. The first member in each set is the record type that
|
* record groups. The first member in each set is the record type that
|
||||||
* indicates the end of that record group.
|
* indicates the end of that record group.
|
||||||
*/
|
*/
|
||||||
#define REC_TYPE_ENVELOPE "MCTFISDRW"
|
#define REC_TYPE_ENVELOPE "MCTFILSDRW"
|
||||||
#define REC_TYPE_CONTENT "XLN"
|
#define REC_TYPE_CONTENT "XLN"
|
||||||
#define REC_TYPE_EXTRACT "EDRPre"
|
#define REC_TYPE_EXTRACT "EDRPre"
|
||||||
#define REC_TYPE_NOEXTRACT "E"
|
#define REC_TYPE_NOEXTRACT "E"
|
||||||
|
@ -48,9 +48,10 @@ PICKUP(8) PICKUP(8)
|
|||||||
command after a configuration change.
|
command after a configuration change.
|
||||||
|
|
||||||
<b>Content</b> <b>inspection</b> <b>controls</b>
|
<b>Content</b> <b>inspection</b> <b>controls</b>
|
||||||
<b>content</b><i>_</i><b>inspector</b>
|
<b>content</b><i>_</i><b>filter</b>
|
||||||
The name of a mail delivery transport that inspects
|
The name of a mail delivery transport that filters
|
||||||
mail prior to delivery. This parameter uses the
|
mail and that either bounces mail or re-injects the
|
||||||
|
result back into Postfix. This parameter uses the
|
||||||
same syntax as the right-hand side of a Postfix
|
same syntax as the right-hand side of a Postfix
|
||||||
transport table.
|
transport table.
|
||||||
|
|
||||||
@ -61,7 +62,6 @@ PICKUP(8) PICKUP(8)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
1
|
1
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,9 +81,10 @@ SMTPD(8) SMTPD(8)
|
|||||||
comments, like Sendmail does.
|
comments, like Sendmail does.
|
||||||
|
|
||||||
<b>Content</b> <b>inspection</b> <b>controls</b>
|
<b>Content</b> <b>inspection</b> <b>controls</b>
|
||||||
<b>content</b><i>_</i><b>inspector</b>
|
<b>content</b><i>_</i><b>filter</b>
|
||||||
The name of a mail delivery transport that inspects
|
The name of a mail delivery transport that filters
|
||||||
mail prior to delivery. This parameter uses the
|
mail and that either bounces mail or re-injects the
|
||||||
|
result back into Postfix. This parameter uses the
|
||||||
same syntax as the right-hand side of a Postfix
|
same syntax as the right-hand side of a Postfix
|
||||||
transport table.
|
transport table.
|
||||||
|
|
||||||
@ -124,7 +125,6 @@ SMTPD(8) SMTPD(8)
|
|||||||
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
|
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
|
||||||
Increment in verbose logging level when a remote
|
Increment in verbose logging level when a remote
|
||||||
host matches a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
|
host matches a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
|
||||||
parameter.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -137,6 +137,8 @@ SMTPD(8) SMTPD(8)
|
|||||||
SMTPD(8) SMTPD(8)
|
SMTPD(8) SMTPD(8)
|
||||||
|
|
||||||
|
|
||||||
|
parameter.
|
||||||
|
|
||||||
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
|
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
|
||||||
List of domain or network patterns. When a remote
|
List of domain or network patterns. When a remote
|
||||||
host matches a pattern, increase the verbose log-
|
host matches a pattern, increase the verbose log-
|
||||||
@ -192,8 +194,6 @@ SMTPD(8) SMTPD(8)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
3
|
3
|
||||||
|
|
||||||
|
|
||||||
|
@ -57,9 +57,9 @@ this program. See the Postfix \fBmain.cf\fR file for syntax details
|
|||||||
and for default values. Use the \fBpostfix reload\fR command after
|
and for default values. Use the \fBpostfix reload\fR command after
|
||||||
a configuration change.
|
a configuration change.
|
||||||
.SH "Content inspection controls"
|
.SH "Content inspection controls"
|
||||||
.IP \fBcontent_inspector\fR
|
.IP \fBcontent_filter\fR
|
||||||
The name of a mail delivery transport that inspects mail prior
|
The name of a mail delivery transport that filters mail and that
|
||||||
to delivery.
|
either bounces mail or re-injects the result back into Postfix.
|
||||||
This parameter uses the same syntax as the right-hand side of
|
This parameter uses the same syntax as the right-hand side of
|
||||||
a Postfix transport table.
|
a Postfix transport table.
|
||||||
.SH Miscellaneous
|
.SH Miscellaneous
|
||||||
|
@ -76,9 +76,9 @@ a configuration change.
|
|||||||
Disallow non-RFC 821 style addresses in envelopes. For example,
|
Disallow non-RFC 821 style addresses in envelopes. For example,
|
||||||
allow RFC822-style address forms with comments, like Sendmail does.
|
allow RFC822-style address forms with comments, like Sendmail does.
|
||||||
.SH "Content inspection controls"
|
.SH "Content inspection controls"
|
||||||
.IP \fBcontent_inspector\fR
|
.IP \fBcontent_filter\fR
|
||||||
The name of a mail delivery transport that inspects mail prior
|
The name of a mail delivery transport that filters mail and that
|
||||||
to delivery.
|
either bounces mail or re-injects the result back into Postfix.
|
||||||
This parameter uses the same syntax as the right-hand side of
|
This parameter uses the same syntax as the right-hand side of
|
||||||
a Postfix transport table.
|
a Postfix transport table.
|
||||||
.SH "Authenication controls"
|
.SH "Authenication controls"
|
||||||
|
@ -249,6 +249,7 @@ struct QMGR_MESSAGE {
|
|||||||
char *sender; /* complete address */
|
char *sender; /* complete address */
|
||||||
char *errors_to; /* error report address */
|
char *errors_to; /* error report address */
|
||||||
char *return_receipt; /* confirm receipt address */
|
char *return_receipt; /* confirm receipt address */
|
||||||
|
char *filter_xport; /* inspection transport */
|
||||||
long data_size; /* message content size */
|
long data_size; /* message content size */
|
||||||
long rcpt_offset; /* more recipients here */
|
long rcpt_offset; /* more recipients here */
|
||||||
long unread_offset; /* more unread recipients here */
|
long unread_offset; /* more unread recipients here */
|
||||||
|
@ -149,6 +149,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name,
|
|||||||
message->sender = 0;
|
message->sender = 0;
|
||||||
message->errors_to = 0;
|
message->errors_to = 0;
|
||||||
message->return_receipt = 0;
|
message->return_receipt = 0;
|
||||||
|
message->filter_xport = 0;
|
||||||
message->data_size = 0;
|
message->data_size = 0;
|
||||||
message->warn_offset = 0;
|
message->warn_offset = 0;
|
||||||
message->warn_time = 0;
|
message->warn_time = 0;
|
||||||
@ -358,6 +359,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
|
|||||||
} else if (rec_type == REC_TYPE_TIME) {
|
} else if (rec_type == REC_TYPE_TIME) {
|
||||||
if (message->arrival_time == 0)
|
if (message->arrival_time == 0)
|
||||||
message->arrival_time = atol(start);
|
message->arrival_time = atol(start);
|
||||||
|
} else if (rec_type == REC_TYPE_FILT) {
|
||||||
|
if (message->filter_xport == 0)
|
||||||
|
message->filter_xport = mystrdup(start);
|
||||||
} else if (rec_type == REC_TYPE_FROM) {
|
} else if (rec_type == REC_TYPE_FROM) {
|
||||||
if (message->sender == 0) {
|
if (message->sender == 0) {
|
||||||
message->sender = mystrdup(start);
|
message->sender = mystrdup(start);
|
||||||
@ -541,6 +545,7 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
|
|||||||
char **cpp;
|
char **cpp;
|
||||||
char *domain;
|
char *domain;
|
||||||
const char *junk;
|
const char *junk;
|
||||||
|
char *nexthop;
|
||||||
|
|
||||||
#define STREQ(x,y) (strcasecmp(x,y) == 0)
|
#define STREQ(x,y) (strcasecmp(x,y) == 0)
|
||||||
#define STR vstring_str
|
#define STR vstring_str
|
||||||
@ -570,9 +575,16 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
|
|||||||
* result address may differ from the one specified by the sender.
|
* result address may differ from the one specified by the sender.
|
||||||
*/
|
*/
|
||||||
resolve_clnt_query(recipient->address, &reply);
|
resolve_clnt_query(recipient->address, &reply);
|
||||||
|
if (message->filter_xport) {
|
||||||
|
vstring_strcpy(reply.transport, message->filter_xport);
|
||||||
|
if ((nexthop = split_at(STR(reply.transport), ':')) == 0
|
||||||
|
|| *nexthop == 0)
|
||||||
|
nexthop = var_myhostname;
|
||||||
|
vstring_strcpy(reply.nexthop, nexthop);
|
||||||
|
} else {
|
||||||
if (!STREQ(recipient->address, STR(reply.recipient)))
|
if (!STREQ(recipient->address, STR(reply.recipient)))
|
||||||
UPDATE(recipient->address, STR(reply.recipient));
|
UPDATE(recipient->address, STR(reply.recipient));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Bounce recipients that have moved. We do it here instead of in the
|
* Bounce recipients that have moved. We do it here instead of in the
|
||||||
@ -815,6 +827,8 @@ void qmgr_message_free(QMGR_MESSAGE *message)
|
|||||||
myfree(message->errors_to);
|
myfree(message->errors_to);
|
||||||
if (message->return_receipt)
|
if (message->return_receipt)
|
||||||
myfree(message->return_receipt);
|
myfree(message->return_receipt);
|
||||||
|
if (message->filter_xport)
|
||||||
|
myfree(message->filter_xport);
|
||||||
qmgr_rcpt_list_free(&message->rcpt_list);
|
qmgr_rcpt_list_free(&message->rcpt_list);
|
||||||
qmgr_message_count--;
|
qmgr_message_count--;
|
||||||
myfree((char *) message);
|
myfree((char *) message);
|
||||||
|
@ -41,9 +41,9 @@
|
|||||||
/* and for default values. Use the \fBpostfix reload\fR command after
|
/* and for default values. Use the \fBpostfix reload\fR command after
|
||||||
/* a configuration change.
|
/* a configuration change.
|
||||||
/* .SH "Content inspection controls"
|
/* .SH "Content inspection controls"
|
||||||
/* .IP \fBcontent_inspector\fR
|
/* .IP \fBcontent_filter\fR
|
||||||
/* The name of a mail delivery transport that inspects mail prior
|
/* The name of a mail delivery transport that filters mail and that
|
||||||
/* to delivery.
|
/* either bounces mail or re-injects the result back into Postfix.
|
||||||
/* This parameter uses the same syntax as the right-hand side of
|
/* This parameter uses the same syntax as the right-hand side of
|
||||||
/* a Postfix transport table.
|
/* a Postfix transport table.
|
||||||
/* .SH Miscellaneous
|
/* .SH Miscellaneous
|
||||||
@ -112,7 +112,7 @@
|
|||||||
/* Application-specific. */
|
/* Application-specific. */
|
||||||
|
|
||||||
char *var_always_bcc;
|
char *var_always_bcc;
|
||||||
char *var_inspect_xport;
|
char *var_filter_xport;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Structure to bundle a bunch of information about a queue file.
|
* Structure to bundle a bunch of information about a queue file.
|
||||||
@ -180,7 +180,7 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info,
|
|||||||
info->rcpt = mystrdup(vstring_str(buf));
|
info->rcpt = mystrdup(vstring_str(buf));
|
||||||
if (type == REC_TYPE_TIME)
|
if (type == REC_TYPE_TIME)
|
||||||
continue;
|
continue;
|
||||||
if (type == REC_TYPE_INSP)
|
if (type == REC_TYPE_FILT)
|
||||||
continue;
|
continue;
|
||||||
else {
|
else {
|
||||||
|
|
||||||
@ -235,8 +235,8 @@ static int pickup_copy(VSTREAM *qfile, VSTREAM *cleanup,
|
|||||||
/*
|
/*
|
||||||
* Add content inspection transport.
|
* Add content inspection transport.
|
||||||
*/
|
*/
|
||||||
if (*var_inspect_xport)
|
if (*var_filter_xport)
|
||||||
rec_fprintf(cleanup, REC_TYPE_INSP, "%s", var_inspect_xport);
|
rec_fprintf(cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy the message envelope segment. Allow only those records that we
|
* Copy the message envelope segment. Allow only those records that we
|
||||||
@ -457,7 +457,7 @@ int main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
static CONFIG_STR_TABLE str_table[] = {
|
static CONFIG_STR_TABLE str_table[] = {
|
||||||
VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0,
|
VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0,
|
||||||
VAR_INSPECT_XPORT, DEF_INSPECT_XPORT, &var_inspect_xport, 0, 0,
|
VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ struct QMGR_MESSAGE {
|
|||||||
char *sender; /* complete address */
|
char *sender; /* complete address */
|
||||||
char *errors_to; /* error report address */
|
char *errors_to; /* error report address */
|
||||||
char *return_receipt; /* confirm receipt address */
|
char *return_receipt; /* confirm receipt address */
|
||||||
char *inspect_xport; /* inspection transport */
|
char *filter_xport; /* inspection transport */
|
||||||
long data_size; /* message content size */
|
long data_size; /* message content size */
|
||||||
long rcpt_offset; /* more recipients here */
|
long rcpt_offset; /* more recipients here */
|
||||||
QMGR_RCPT_LIST rcpt_list; /* complete addresses */
|
QMGR_RCPT_LIST rcpt_list; /* complete addresses */
|
||||||
|
@ -144,7 +144,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name,
|
|||||||
message->sender = 0;
|
message->sender = 0;
|
||||||
message->errors_to = 0;
|
message->errors_to = 0;
|
||||||
message->return_receipt = 0;
|
message->return_receipt = 0;
|
||||||
message->inspect_xport = 0;
|
message->filter_xport = 0;
|
||||||
message->data_size = 0;
|
message->data_size = 0;
|
||||||
message->warn_offset = 0;
|
message->warn_offset = 0;
|
||||||
message->warn_time = 0;
|
message->warn_time = 0;
|
||||||
@ -247,9 +247,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
|
|||||||
} else if (rec_type == REC_TYPE_TIME) {
|
} else if (rec_type == REC_TYPE_TIME) {
|
||||||
if (message->arrival_time == 0)
|
if (message->arrival_time == 0)
|
||||||
message->arrival_time = atol(start);
|
message->arrival_time = atol(start);
|
||||||
} else if (rec_type == REC_TYPE_INSP) {
|
} else if (rec_type == REC_TYPE_FILT) {
|
||||||
if (message->inspect_xport == 0)
|
if (message->filter_xport == 0)
|
||||||
message->inspect_xport = mystrdup(start);
|
message->filter_xport = mystrdup(start);
|
||||||
} else if (rec_type == REC_TYPE_FROM) {
|
} else if (rec_type == REC_TYPE_FROM) {
|
||||||
if (message->sender == 0) {
|
if (message->sender == 0) {
|
||||||
message->sender = mystrdup(start);
|
message->sender = mystrdup(start);
|
||||||
@ -462,9 +462,11 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message)
|
|||||||
* result address may differ from the one specified by the sender.
|
* result address may differ from the one specified by the sender.
|
||||||
*/
|
*/
|
||||||
resolve_clnt_query(recipient->address, &reply);
|
resolve_clnt_query(recipient->address, &reply);
|
||||||
if (message->inspect_xport) {
|
if (message->filter_xport) {
|
||||||
vstring_strcpy(reply.transport, message->inspect_xport);
|
vstring_strcpy(reply.transport, message->filter_xport);
|
||||||
if ((nexthop = split_at(STR(reply.transport), ':')) != 0)
|
if ((nexthop = split_at(STR(reply.transport), ':')) == 0
|
||||||
|
|| *nexthop == 0)
|
||||||
|
nexthop = var_myhostname;
|
||||||
vstring_strcpy(reply.nexthop, nexthop);
|
vstring_strcpy(reply.nexthop, nexthop);
|
||||||
} else {
|
} else {
|
||||||
if (!STREQ(recipient->address, STR(reply.recipient)))
|
if (!STREQ(recipient->address, STR(reply.recipient)))
|
||||||
@ -702,8 +704,8 @@ void qmgr_message_free(QMGR_MESSAGE *message)
|
|||||||
myfree(message->errors_to);
|
myfree(message->errors_to);
|
||||||
if (message->return_receipt)
|
if (message->return_receipt)
|
||||||
myfree(message->return_receipt);
|
myfree(message->return_receipt);
|
||||||
if (message->inspect_xport)
|
if (message->filter_xport)
|
||||||
myfree(message->inspect_xport);
|
myfree(message->filter_xport);
|
||||||
qmgr_rcpt_list_free(&message->rcpt_list);
|
qmgr_rcpt_list_free(&message->rcpt_list);
|
||||||
qmgr_message_count--;
|
qmgr_message_count--;
|
||||||
myfree((char *) message);
|
myfree((char *) message);
|
||||||
|
@ -60,9 +60,9 @@
|
|||||||
/* Disallow non-RFC 821 style addresses in envelopes. For example,
|
/* Disallow non-RFC 821 style addresses in envelopes. For example,
|
||||||
/* allow RFC822-style address forms with comments, like Sendmail does.
|
/* allow RFC822-style address forms with comments, like Sendmail does.
|
||||||
/* .SH "Content inspection controls"
|
/* .SH "Content inspection controls"
|
||||||
/* .IP \fBcontent_inspector\fR
|
/* .IP \fBcontent_filter\fR
|
||||||
/* The name of a mail delivery transport that inspects mail prior
|
/* The name of a mail delivery transport that filters mail and that
|
||||||
/* to delivery.
|
/* either bounces mail or re-injects the result back into Postfix.
|
||||||
/* This parameter uses the same syntax as the right-hand side of
|
/* This parameter uses the same syntax as the right-hand side of
|
||||||
/* a Postfix transport table.
|
/* a Postfix transport table.
|
||||||
/* .SH "Authenication controls"
|
/* .SH "Authenication controls"
|
||||||
@ -341,7 +341,7 @@ int var_smtpd_junk_cmd_limit;
|
|||||||
bool var_smtpd_sasl_enable;
|
bool var_smtpd_sasl_enable;
|
||||||
char *var_smtpd_sasl_opts;
|
char *var_smtpd_sasl_opts;
|
||||||
char *var_smtpd_sasl_realm;
|
char *var_smtpd_sasl_realm;
|
||||||
char *var_inspect_xport;
|
char *var_filter_xport;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Global state, for stand-alone mode queue file cleanup. When this is
|
* Global state, for stand-alone mode queue file cleanup. When this is
|
||||||
@ -667,8 +667,8 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
|
|||||||
*/
|
*/
|
||||||
rec_fprintf(state->cleanup, REC_TYPE_TIME, "%ld",
|
rec_fprintf(state->cleanup, REC_TYPE_TIME, "%ld",
|
||||||
(long) time((time_t *) 0));
|
(long) time((time_t *) 0));
|
||||||
if (*var_inspect_xport)
|
if (*var_filter_xport)
|
||||||
rec_fprintf(state->cleanup, REC_TYPE_INSP, "%s", var_inspect_xport);
|
rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
|
||||||
rec_fputs(state->cleanup, REC_TYPE_FROM, argv[2].strval);
|
rec_fputs(state->cleanup, REC_TYPE_FROM, argv[2].strval);
|
||||||
state->sender = mystrdup(argv[2].strval);
|
state->sender = mystrdup(argv[2].strval);
|
||||||
smtpd_chat_reply(state, "250 Ok");
|
smtpd_chat_reply(state, "250 Ok");
|
||||||
@ -1434,7 +1434,7 @@ int main(int argc, char **argv)
|
|||||||
VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0,
|
VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0,
|
||||||
VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
|
VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
|
||||||
VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 1, 0,
|
VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 1, 0,
|
||||||
VAR_INSPECT_XPORT, DEF_INSPECT_XPORT, &var_inspect_xport, 0, 0,
|
VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -193,11 +193,10 @@ void smtpd_sasl_connect(SMTPD_STATE *state)
|
|||||||
/*
|
/*
|
||||||
* Set up a new server context for this connection.
|
* Set up a new server context for this connection.
|
||||||
*/
|
*/
|
||||||
#define DEFAULT_USER_REALM ((char *) 0)
|
|
||||||
#define NO_SECURITY_LAYERS (0)
|
#define NO_SECURITY_LAYERS (0)
|
||||||
#define NO_SESSION_CALLBACKS ((sasl_callback_t *) 0)
|
#define NO_SESSION_CALLBACKS ((sasl_callback_t *) 0)
|
||||||
|
|
||||||
if (sasl_server_new("smtp", var_smtpd_sasl_realm, DEFAULT_USER_REALM,
|
if (sasl_server_new("smtp", var_myhostname, var_smtpd_sasl_realm,
|
||||||
NO_SESSION_CALLBACKS, NO_SECURITY_LAYERS,
|
NO_SESSION_CALLBACKS, NO_SECURITY_LAYERS,
|
||||||
&state->sasl_conn) != SASL_OK)
|
&state->sasl_conn) != SASL_OK)
|
||||||
msg_fatal("SASL per-connection server initialization");
|
msg_fatal("SASL per-connection server initialization");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user