]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.8-20110112
authorWietse Venema <wietse@porcupine.org>
Wed, 12 Jan 2011 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:36:57 +0000 (06:36 +0000)
24 files changed:
postfix/HISTORY
postfix/README_FILES/POSTSCREEN_README
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/html/POSTSCREEN_README.html
postfix/html/postconf.5.html
postfix/html/postscreen.8.html
postfix/man/man5/postconf.5
postfix/man/man8/postscreen.8
postfix/mantools/postlink
postfix/proto/POSTSCREEN_README.html
postfix/proto/postconf.proto
postfix/src/global/Makefile.in
postfix/src/global/addr_match_list.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/postscreen/Makefile.in
postfix/src/postscreen/postscreen.c
postfix/src/postscreen/postscreen.h
postfix/src/postscreen/postscreen_access.c [new file with mode: 0644]
postfix/src/postscreen/postscreen_send.c
postfix/src/postscreen/postscreen_smtpd.c
postfix/src/util/Makefile.in
postfix/src/util/unix_pass_trigger.c

index cad0567ef441c9d2289e7533258da3335d863455..43f0b42b7833db44c1abce180a7413f90d1b31e0 100644 (file)
@@ -16418,11 +16418,26 @@ Apologies for any names omitted.
        was useless code. Files: util/stream_pass_connect.c,
        util/unix_pass_listen.c, util/unix_pass_trigger.c.
 
-       Cleanup: on Solaris the Postfix event engine was deaf for
-       SIGHUP and SIGALRM (and probably more) signals after the
-       switch to /dev/poll. Symptoms were delayed "postfix reload"
-       response, and killed processes when the watchdog timeout
-       was less than max_idle.  The fix is to set up SIGHUP and
-       SIGALRM handlers that write to a pipe, and to monitor that
-       pipe for read events via the Postfix event engine. Files:
-       master/master_sig.c, util/watchdog.c.
+       Bugfix (introduced Postfix 2.4): on Solaris the Postfix
+       event engine was deaf for SIGHUP and SIGALRM signals after
+       the switch to /dev/poll. Symptoms were delayed "postfix
+       reload" response, and killed processes when the watchdog
+       timeout was less than max_idle.  The fix is to set up SIGHUP
+       and SIGALRM handlers that write to a pipe, and to monitor
+       that pipe for read events via the Postfix event engine.
+       Files: master/master_sig.c, util/watchdog.c, util/sys_defs.h.
+
+20110111
+
+       Cleanup: replaced the postscreen(8) separate blacklist and
+       whitelist lookup tables by one postscreen_access_list table.
+       See postconf(5) and POSTSCREEN_README for examples.  Files:
+       postscreen/postscreen_access.c, postscreen/postscreen.c,
+       proto/postconf.proto, proto/POSTSCREEN_README.html.
+
+20110112
+
+       Cleanup: suspend/resume logic for postscreen(8) SMTP sessions
+       that temporarily switch control to an external program such
+       as tlsproxy, or perhaps a future policy plugin.  Files:
+       postscreen/postscreen_smtpd, postscreen/postscreen_starttls.c.
index 428d5d6a0eda1b9e9e501b80bc1743199a92c7c5..6badf305a2569783304297761c98b1a3d9739638 100644 (file)
@@ -106,28 +106,40 @@ Q\bQu\bui\bic\bck\bk t\bte\bes\bst\bts\bs b\bbe\bef\bfo\bor\bre\be e\bev\bve\ber\bry\byt\bth\bhi\bin\bng\b
 Before engaging in SMTP-level tests. postscreen(8) queries a number of local
 black and whitelists. These tests speed up the handling of known clients.
 
-  * Permanent whitelist test
-  * Permanent blacklist test
+  * Permanent white/blacklist test
   * Temporary whitelist test
 
-P\bPe\ber\brm\bma\ban\bne\ben\bnt\bt w\bwh\bhi\bit\bte\bel\bli\bis\bst\bt t\bte\bes\bst\bt
+P\bPe\ber\brm\bma\ban\bne\ben\bnt\bt w\bwh\bhi\bit\bte\be/\b/b\bbl\bla\bac\bck\bkl\bli\bis\bst\bt t\bte\bes\bst\bt
 
-The postscreen_whitelist_networks parameter (default: $mynetworks) specifies a
-permanent whitelist for SMTP client IP addresses. When the SMTP client address
-matches the permanent whitelist, postscreen(8) logs this with the client
-address and port number as:
+The postscreen_access_list parameter (default: permit_mynetworks) specifies a
+permanent access list for SMTP client IP addresses. Typically one would specify
+something that whitelists local networks, followed by a CIDR table for
+selective white- and blacklisting.
 
-    W\bWH\bHI\bIT\bTE\bEL\bLI\bIS\bST\bTE\bED\bD [address]:port
+Example:
 
-The action is not configurable: immediately hand off the connection to a
-Postfix SMTP server process.
+/etc/postfix/main.cf:
+    postscreen_access_list = permit_mynetworks,
+        /etc/postfix/postscreen_access.cidr
 
-P\bPe\ber\brm\bma\ban\bne\ben\bnt\bt b\bbl\bla\bac\bck\bkl\bli\bis\bst\bt t\bte\bes\bst\bt
+/etc/postfix/postscreen_access.cidr:
+   # Rules are evaluated in the order as specified.
+   # Blacklist 192.168.* except 192.168.0.1.
+   192.168.0.1          permit
+   192.168.0.0/16       reject
 
-The postscreen_blacklist_networks parameter (default: empty) specifies a
-permanent blacklist for SMTP client IP addresses. The address syntax is as with
-mynetworks. When the SMTP client address matches the permanent blacklist,
-postscreen(8) logs this with the client address and port number as:
+See the postscreen_access_list manpage documentation for more details.
+
+When the SMTP client address matches a "permit" action, postscreen(8) logs this
+with the client address and port number as:
+
+    W\bWH\bHI\bIT\bTE\bEL\bLI\bIS\bST\bTE\bED\bD [address]:port
+
+The whitelist action is not configurable: immediately hand off the connection
+to a Postfix SMTP server process.
+
+When the SMTP client address matches a "reject" action, postscreen(8) logs this
+with the client address and port number as:
 
     B\bBL\bLA\bAC\bCK\bKL\bLI\bIS\bST\bTE\bED\bD [address]:port
 
@@ -165,7 +177,7 @@ continue as if postscreen(8) never even existed (except of course for the short
 postscreen_greet_wait delay).
 
   * Pregreet test
-  * DNS Blocklist test
+  * DNS White/blacklist test
   * When tests fail before the 220 SMTP server greeting
 
 P\bPr\bre\beg\bgr\bre\bee\bet\bt t\bte\bes\bst\bt
@@ -183,11 +195,16 @@ effect on SMTP clients that correctly implement the protocol.
 
 To avoid problems with poorly-implemented SMTP engines in network appliances or
 network testing tools, either exclude them from all tests with the
-postscreen_whitelist_networks feature or else specify an empty teaser banner:
+postscreen_access_list feature or else specify an empty teaser banner:
 
 /etc/postfix/main.cf:
-    # Exclude broken clients by whitelisting. $mynetworks is default.
-    postscreen_whitelist_networks = $mynetworks, 192.168.254.0/24
+    # Exclude broken clients by whitelisting. Clients in mynetworks
+    # should always be whitelisted.
+    postscreen_access_list = permit_mynetworks,
+        cidr:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.cidr:
+    192.168.254.0/24 permit
 
 /etc/postfix/main.cf:
     # Disable the teaser banner (try whitelisting first if you can).
@@ -207,12 +224,12 @@ return and \n for newline).
 The postscreen_greet_action parameter specifies the action that is taken next.
 See "When tests fail before the 220 SMTP server greeting" below.
 
-D\bDN\bNS\bB\bBl\blo\boc\bck\bkl\bli\bis\bst\bt t\bte\bes\bst\bt
+D\bDN\bNS\bW\bWh\bhi\bit\bte\be/\b/b\bbl\bla\bac\bck\bkl\bli\bis\bst\bt t\bte\bes\bst\bt
 
 The postscreen_dnsbl_sites parameter (default: empty) specifies a list of DNS
-blocklist servers with optional filters and weight factors. These servers will
-be queried in parallel with the reverse client IP address. This test is
-disabled by default.
+blocklist servers with optional filters and weight factors (positive weights
+for blacklisting, negative for whitelisting). These servers will be queried in
+parallel with the reverse client IP address. This test is disabled by default.
 
     CAUTION: when postscreen rejects mail, its SMTP reply contains the DNSBL
     domain name. Use the postscreen_dnsbl_reply_map feature to hide "password"
@@ -574,9 +591,8 @@ more of:
     after all. Wietse enables "deep protocol tests" on his own internet-facing
     mail server.
 
-  * There is also support for permanent blacklists and whitelists; see the
-    description of the postscreen_whitelist_networks and
-    postscreen_blacklist_networks parameters for details.
+  * There is also support for permanent blacklisting and whitelisting; see the
+    description of the postscreen_access_list parameter for details.
 
 T\bTu\bur\brn\bni\bin\bng\bg o\bof\bff\bf p\bpo\bos\bst\bts\bsc\bcr\bre\bee\ben\bn(\b(8\b8)\b)
 
index 79f4421c677d4a7a4e0ab5662523d1e5ac4b9b08..5ea4c491f242f7f35ad85b7dd10a7462367dd20f 100644 (file)
@@ -34,6 +34,16 @@ is the $name of an smtpd_xxx parameter with a stress-dependent
 default).  Other postscreen parameters always evaluate as if the
 stress value is equal to the empty string.
 
+Incompatibility with snapshot 20110111
+======================================
+
+For performance reasons the postscreen_access_list feature replaces
+the postscreen_whitelist_networks and postscreen_blacklist_networks
+features. CIDR-style access maps are some 100x faster than the code
+that implemented the postscreen_white/blacklist_networks support.
+It can match about 100 million CIDR patterns/second on a modern CPU,
+which is not blindingly fast but adequate for the near future.
+
 Major changes with snapshot 20110105
 ====================================
 
index 39f17a30e6595d882f8ecaf76f2385d7705389d6..b6ef68996d6920c75f30381882e3948a06a1297d 100644 (file)
@@ -4,26 +4,13 @@ Wish list:
 
        Remove this file from the stable release.
 
-       To speed up postscreen_whitelist/blacklist_networks lookups 
-       invent match_list support that does not recompile CIDR
-        patterns on every call. Otherwise, large CIDR files will
-       make postscreen unacceptably slow.
-
-       Better, replace the postscreen_whitelist/blacklist_networks
-       mechanisms with one single postscreen_client_restrictions
-       mechanism that understands "permit_mynetworks" and (cidr)
-       access maps with entries of "pattern permit", "pattern
-       reject", or "pattern dunno". Tables that require locking
-       should not be used for performance reasons. The new mechanism
-       can reduce the number of table lookups when sites have both
-       whitelists and blacklists.  We then use "permit_mynetworks"
-       to whitelist local networks by default.  Unlike match_lists,
-       PCRE maps in access tables are compiled once, and even
-       Stan's very large tables resolve in a millisecond or so on
-       modern hardware.
-
        Things to do after the stable release:
 
+       inline table where the "whitespace replacement" character
+       is specified in-line. Ex: inline:XYname1Xvalue1Yname2Xvalue2
+       would instantiate a table with (name1, value1) and (name2,
+       value2).  I'm afraid this is just too ugly.
+
        tlsproxy(8) should receive TLS preferences from postscreen(8)
        and smtpd(8), instead of reading them from main.cf. This
        means that many tlsproxy_ parameters become postscreen_
index d16b5afbd52da1b0556016ec2dfd969940f2d8eb..784d12b56faa65d6fe047239bf03a8511727c958 100644 (file)
@@ -146,35 +146,50 @@ handling of known clients. </p>
 
 <ul>
 
-<li> <a href="#perm_white"> Permanent whitelist test </a>
-
-<li> <a href="#perm_black"> Permanent blacklist test </a>
+<li> <a href="#perm_white_black"> Permanent white/blacklist test </a>
 
 <li> <a href="#temp_white"> Temporary whitelist test </a>
 
 </ul>
 
-<h3> <a name="perm_white"> Permanent whitelist test </a> </h3>
+<h3> <a name="perm_white_black"> Permanent white/blacklist test </a> </h3>
+
+<p> The <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> parameter (default: <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>)
+specifies a permanent access list for SMTP client IP addresses. Typically
+one would specify something that whitelists local networks, followed
+by a CIDR table for selective white- and blacklisting. </p>
 
-<p> The <a href="postconf.5.html#postscreen_whitelist_networks">postscreen_whitelist_networks</a> parameter (default: $<a href="postconf.5.html#mynetworks">mynetworks</a>)
-specifies a permanent whitelist for SMTP client IP addresses.  When
-the SMTP client address matches the permanent whitelist, <a href="postscreen.8.html">postscreen(8)</a>
-logs this with the client address and port number as: </p>
+<p> Example: </p>
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+    <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> = <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>,
+        /etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.<a href="cidr_table.5.html">cidr</a>:
+   # Rules are evaluated in the order as specified.
+   # Blacklist 192.168.* except 192.168.0.1.
+   192.168.0.1          permit
+   192.168.0.0/16       reject
+</pre>
+
+<p> See the <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> manpage documentation for more
+details.  </p>
+
+<p> When the SMTP client address matches a "permit" action,
+<a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port number as:
+</p>
 
 <pre>
     <b>WHITELISTED</b> <i>[address]:port</i>
 </pre>
 
-<p> The action is not configurable: immediately hand off the
+<p> The whitelist action is not configurable: immediately hand off the
 connection to a Postfix SMTP server process. </p>
 
-<h3> <a name="perm_black"> Permanent blacklist test </a>  </h3>
-
-<p> The <a href="postconf.5.html#postscreen_blacklist_networks">postscreen_blacklist_networks</a> parameter (default: empty)
-specifies a permanent blacklist for SMTP client IP addresses.  The
-address syntax is as with <a href="postconf.5.html#mynetworks">mynetworks</a>.  When the SMTP client address
-matches the permanent blacklist, <a href="postscreen.8.html">postscreen(8)</a> logs this with the
-client address and port number as: </p>
+<p> When the SMTP client address matches a "reject" action,
+<a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port number as:
+</p>
 
 <pre>
     <b>BLACKLISTED</b> <i>[address]:port</i>
@@ -224,7 +239,7 @@ for the short <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_w
 
 <li> <a href="#pregreet"> Pregreet test </a>
 
-<li> <a href="#dnsbl"> DNS Blocklist test </a>
+<li> <a href="#dnsbl"> DNS White/blacklist test </a>
 
 <li> <a href="#fail_before_220">When tests fail before the 220 SMTP server greeting</a>
 
@@ -247,13 +262,18 @@ SMTP clients that correctly implement the protocol.  </p>
 
 <p> To avoid problems with poorly-implemented SMTP engines in network
 appliances or network testing tools, either exclude them from all
-tests with the <a href="postconf.5.html#postscreen_whitelist_networks">postscreen_whitelist_networks</a> feature or else specify
+tests with the <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> feature or else specify
 an empty teaser banner: </p>
 
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    # Exclude broken clients by whitelisting. $<a href="postconf.5.html#mynetworks">mynetworks</a> is default.
-    <a href="postconf.5.html#postscreen_whitelist_networks">postscreen_whitelist_networks</a> = $<a href="postconf.5.html#mynetworks">mynetworks</a>, 192.168.254.0/24
+    # Exclude broken clients by whitelisting. Clients in <a href="postconf.5.html#mynetworks">mynetworks</a>
+    # should always be whitelisted.
+    <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> = <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>, 
+        <a href="cidr_table.5.html">cidr</a>:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.<a href="cidr_table.5.html">cidr</a>:
+    192.168.254.0/24 permit
 </pre>
 
 <pre>
@@ -281,12 +301,13 @@ and \n for newline). </p>
 is taken next.  See "<a href="#fail_before_220">When tests fail
 before the 220 SMTP server greeting</a>" below. </p>
 
-<h3> <a name="dnsbl"> DNS Blocklist test </a> </h3>
+<h3> <a name="dnsbl"> DNS White/blacklist test </a> </h3>
 
 <p> The <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> parameter (default: empty) specifies
 a list of DNS blocklist servers with optional filters and weight
-factors.  These servers will be queried in parallel with the reverse
-client IP address. This test is disabled by default. </p>
+factors (positive weights for blacklisting, negative for whitelisting).
+These servers will be queried in parallel with the reverse client
+IP address.  This test is disabled by default. </p>
 
 <blockquote>
 <p>
@@ -799,9 +820,9 @@ reply; these clients were not so good after all.  Wietse enables
 "<a href="#after_220">deep protocol tests</a>" on his own internet-facing
 mail server.  </p>
 
-<li> <p> There is also support for permanent blacklists and whitelists;
-see the description of the <a href="postconf.5.html#postscreen_whitelist_networks">postscreen_whitelist_networks</a> and
-<a href="postconf.5.html#postscreen_blacklist_networks">postscreen_blacklist_networks</a> parameters for details. </p>
+<li> <p> There is also support for permanent blacklisting and
+whitelisting; see the description of the <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a>
+parameter for details. </p>
 
 </ul>
 
index 817fbe3da933876d9595d74fdea22f5fc7ca3531..d9d88afb3b763da981f744c04b64ef586728e6a1 100644 (file)
@@ -6618,6 +6618,67 @@ and enabled instances are processed in reverse order. </p>
 <p> This feature is available in Postfix 2.6 and later. </p>
 
 
+</DD>
+
+<DT><b><a name="postscreen_access_list">postscreen_access_list</a>
+(default: <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>)</b></DT><DD>
+
+<p> Permanent white/blacklist for remote SMTP client IP addresses;
+<a href="postscreen.8.html">postscreen(8)</a> searches this list immediately after a remote SMTP
+client connects.  Specify a comma- or whitespace-separated list of
+commands (in upper or lower case) or lookup tables. The search stops
+upon the first command that fires for the client IP address. </p>
+
+<dl>
+
+<dt> <b> <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a> </b> </dt> <dd> Whitelist the client and
+terminate the search if the client IP address matches $<a href="postconf.5.html#mynetworks">mynetworks</a>.
+Do not subject the client to any before/after 220 greeting tests.
+Pass the connection immediately to a Postfix SMTP server process.
+</dd>
+
+<dt> <b> <a href="DATABASE_README.html">type:table</a> </b> </dt> <dd> Query the specified lookup
+table. Each table lookup result is an access list, except that
+access lists inside a table cannot specify <a href="DATABASE_README.html">type:table</a> entries.  <br>
+To discourage the use of hash, btree, etc. tables, there is no
+support for substring matching like <a href="smtpd.8.html">smtpd(8)</a>. Use CIDR tables
+instead.  </dd>
+
+<dt> <b> permit </b> </dt> <dd> Whitelist the client and terminate
+the search. Do not subject the client to any before/after 220
+greeting tests. Pass the connection immediately to a Postfix SMTP
+server process. </dd>
+
+<dt> <b> reject </b> </dt> <dd> Blacklist the client and terminate
+the search. Subject the client to the action configured with the
+<a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> configuration parameter. </dd>
+
+<dt> <b> dunno </b> </dt> <dd> When used inside a lookup table,
+return from the lookup table and evaluate the next command.  <br>
+When used outside a lookup table, terminate the search, and subject
+the client to the configured before/after 220 greeting tests. </dd>
+
+</dl>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+    <a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> = <a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>,
+               <a href="cidr_table.5.html">cidr</a>:/etc/postfix/postscreen_access.cidr
+</pre>
+
+<pre>
+/etc/postfix/postscreen_access.<a href="cidr_table.5.html">cidr</a>:
+    # Rules are evaluated in the order as specified.
+    # Blacklist 192.168.* except 192.168.0.1.
+    192.168.0.1         dunno
+    192.168.0.0/16      reject
+</pre>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+
 </DD>
 
 <DT><b><a name="postscreen_bare_newline_action">postscreen_bare_newline_action</a>
@@ -6718,20 +6779,6 @@ this test the next time the client connects. </dd>
 <p> This feature is available in Postfix 2.8. </p>
 
 
-</DD>
-
-<DT><b><a name="postscreen_blacklist_networks">postscreen_blacklist_networks</a>
-(default: empty)</b></DT><DD>
-
-<p> Network addresses that are permanently blacklisted; see the
-<a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> parameter for possible actions.  This
-parameter uses the same address syntax as the <a href="postconf.5.html#mynetworks">mynetworks</a> parameter.
-The blacklist has higher precedence than whitelists. This feature
-never uses the remote SMTP client hostname.  </p>
-
-<p> This feature is available in Postfix 2.8. </p>
-
-
 </DD>
 
 <DT><b><a name="postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a>
@@ -7381,19 +7428,6 @@ one-letter suffix that specifies the time unit).  Time units: s
 <p> This feature is available in Postfix 2.8.  </p>
 
 
-</DD>
-
-<DT><b><a name="postscreen_whitelist_networks">postscreen_whitelist_networks</a>
-(default: $<a href="postconf.5.html#mynetworks">mynetworks</a>)</b></DT><DD>
-
-<p> Network addresses that are permanently whitelisted, and that
-will not be subjected to <a href="postscreen.8.html">postscreen(8)</a> checks. This parameter uses
-the same address syntax as the <a href="postconf.5.html#mynetworks">mynetworks</a> parameter. This feature
-never uses the remote SMTP client hostname.  </p>
-
-<p> This feature is available in Postfix 2.8. </p>
-
-
 </DD>
 
 <DT><b><a name="prepend_delivered_header">prepend_delivered_header</a>
index 89411a5933896bbcec79c65f380631a53e0abefd..6775e8f4e5313bdd9b4ac6898a422846ec2b3df3 100644 (file)
@@ -130,30 +130,22 @@ POSTSCREEN(8)                                                    POSTSCREEN(8)
               server will not send in  the  EHLO  response  to  a
               remote SMTP client.
 
-<b>TRIAGE PARAMETERS</b>
-       <b><a href="postconf.5.html#postscreen_bare_newline_action">postscreen_bare_newline_action</a> (ignore)</b>
-              The  action  that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
-              client sends a bare newline character, that  is,  a
-              newline not preceded by carriage return.
-
-       <b><a href="postconf.5.html#postscreen_bare_newline_enable">postscreen_bare_newline_enable</a> (no)</b>
-              Enable  "bare  newline"  SMTP protocol tests in the
-              <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
+<b>BEFORE-GREETING TRIAGE</b>
+       <b><a href="postconf.5.html#postscreen_access_list">postscreen_access_list</a> (<a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>)</b>
+              Permanent white/blacklist for remote SMTP client IP
+              addresses; <a href="postscreen.8.html"><b>postscreen</b>(8)</a> searches this list immedi-
+              ately after a remote SMTP client connects.
 
        <b><a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> (ignore)</b>
-              The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes  when  an  SMTP
-              client   is   permanently   blacklisted   with  the
+              The  action  that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
+              client  is   permanently   blacklisted   with   the
               <a href="postconf.5.html#postscreen_blacklist_networks">postscreen_blacklist_networks</a> parameter.
 
        <b><a href="postconf.5.html#postscreen_blacklist_networks">postscreen_blacklist_networks</a> (empty)</b>
               Network addresses that are permanently blacklisted;
-              see  the  <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> parameter for
+              see the <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a>  parameter  for
               possible actions.
 
-       <b><a href="postconf.5.html#postscreen_disable_vrfy_command">postscreen_disable_vrfy_command</a> ($<a href="postconf.5.html#disable_vrfy_command">disable_vrfy_command</a>)</b>
-              Disable the SMTP VRFY command in the  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
-              daemon.
-
        <b><a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a> (ignore)</b>
               The  action  that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
               client's  combined  DNSBL  score  is  equal  to  or
@@ -176,12 +168,8 @@ POSTSCREEN(8)                                                    POSTSCREEN(8)
               client,  based  on  its  combined  DNSBL  score  as
               defined  with the <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> parameter.
 
-       <b><a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a> ($<a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a>)</b>
-              List of commands that the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server con-
-              siders in violation of the SMTP protocol.
-
        <b><a href="postconf.5.html#postscreen_greet_action">postscreen_greet_action</a> (ignore)</b>
-              The  action  that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
+              The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes  when  an  SMTP
               client speaks before its turn within the time spec-
               ified with the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> parameter.
 
@@ -189,16 +177,34 @@ POSTSCREEN(8)                                                    POSTSCREEN(8)
               The  <i>text</i>  in  the  optional  "220-<i>text</i>..."  server
               response that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> sends ahead of the real
               Postfix SMTP server's "220 text..." response, in an
-              attempt to confuse bad SMTP clients  so  that  they
+              attempt  to  confuse  bad SMTP clients so that they
               speak before their turn (pre-greet).
 
        <b><a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> (${stress?2}${stress:6}s)</b>
               The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will wait for
-              an SMTP client to send a command before  its  turn,
-              and  for  DNS  blocklist  lookup  results to arrive
-              (default: up to 2 seconds under  stress,  up  to  6
+              an  SMTP  client to send a command before its turn,
+              and for DNS  blocklist  lookup  results  to  arrive
+              (default:  up  to  2  seconds under stress, up to 6
               seconds otherwise).
 
+<b>AFTER-GREETING TRIAGE</b>
+       <b><a href="postconf.5.html#postscreen_bare_newline_action">postscreen_bare_newline_action</a> (ignore)</b>
+              The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes  when  an  SMTP
+              client  sends  a bare newline character, that is, a
+              newline not preceded by carriage return.
+
+       <b><a href="postconf.5.html#postscreen_bare_newline_enable">postscreen_bare_newline_enable</a> (no)</b>
+              Enable "bare newline" SMTP protocol  tests  in  the
+              <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
+
+       <b><a href="postconf.5.html#postscreen_disable_vrfy_command">postscreen_disable_vrfy_command</a> ($<a href="postconf.5.html#disable_vrfy_command">disable_vrfy_command</a>)</b>
+              Disable  the SMTP VRFY command in the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
+              daemon.
+
+       <b><a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a> ($<a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a>)</b>
+              List of commands that the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server con-
+              siders in violation of the SMTP protocol.
+
        <b><a href="postconf.5.html#postscreen_helo_required">postscreen_helo_required</a> ($<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a>)</b>
               Require  that  a  remote  SMTP client sends HELO or
               EHLO before commencing a MAIL transaction.
@@ -221,11 +227,7 @@ POSTSCREEN(8)                                                    POSTSCREEN(8)
               Enable "pipelining"  SMTP  protocol  tests  in  the
               <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
 
-       <b><a href="postconf.5.html#postscreen_whitelist_networks">postscreen_whitelist_networks</a> ($<a href="postconf.5.html#mynetworks">mynetworks</a>)</b>
-              Network addresses that are permanently whitelisted,
-              and that will not  be  subjected  to  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
-              checks.
-
+<b>AFTER-TRIAGE CONTROLS</b>
        <b><a href="postconf.5.html#smtpd_service_name">smtpd_service_name</a> (smtpd)</b>
               The  internal  service  that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> forwards
               allowed connections to.
index 9fcc06c530c3e5f201cb417197de2874869a7d4b..d82229a3c3b39c3fa358f5b62dc73f6ec41c6c2d 100644 (file)
@@ -3723,6 +3723,66 @@ as "stop" commands. For these commands, disabled instances are skipped,
 and enabled instances are processed in reverse order.
 .PP
 This feature is available in Postfix 2.6 and later.
+.SH postscreen_access_list (default: permit_mynetworks)
+Permanent white/blacklist for remote SMTP client IP addresses;
+\fBpostscreen\fR(8) searches this list immediately after a remote SMTP
+client connects.  Specify a comma- or whitespace-separated list of
+commands (in upper or lower case) or lookup tables. The search stops
+upon the first command that fires for the client IP address.
+.IP "\fB permit_mynetworks \fR"
+Whitelist the client and
+terminate the search if the client IP address matches $mynetworks.
+Do not subject the client to any before/after 220 greeting tests.
+Pass the connection immediately to a Postfix SMTP server process.
+.IP "\fB type:table \fR"
+Query the specified lookup
+table. Each table lookup result is an access list, except that
+access lists inside a table cannot specify type:table entries.
+.br
+To discourage the use of hash, btree, etc. tables, there is no
+support for substring matching like \fBsmtpd\fR(8). Use CIDR tables
+instead.
+.IP "\fB permit \fR"
+Whitelist the client and terminate
+the search. Do not subject the client to any before/after 220
+greeting tests. Pass the connection immediately to a Postfix SMTP
+server process.
+.IP "\fB reject \fR"
+Blacklist the client and terminate
+the search. Subject the client to the action configured with the
+postscreen_blacklist_action configuration parameter.
+.IP "\fB dunno \fR"
+When used inside a lookup table,
+return from the lookup table and evaluate the next command.
+.br
+When used outside a lookup table, terminate the search, and subject
+the client to the configured before/after 220 greeting tests.
+.PP
+Example:
+.PP
+.nf
+.na
+.ft C
+/etc/postfix/main.cf:
+    postscreen_access_list = permit_mynetworks,
+               cidr:/etc/postfix/postscreen_access.cidr
+.fi
+.ad
+.ft R
+.PP
+.nf
+.na
+.ft C
+/etc/postfix/postscreen_access.cidr:
+    # Rules are evaluated in the order as specified.
+    # Blacklist 192.168.* except 192.168.0.1.
+    192.168.0.1         dunno
+    192.168.0.0/16      reject
+.fi
+.ad
+.ft R
+.PP
+This feature is available in Postfix 2.8.
 .SH postscreen_bare_newline_action (default: ignore)
 The action that \fBpostscreen\fR(8) takes when an SMTP client sends
 a bare newline character, that is, a newline not preceded by carriage
@@ -3778,14 +3838,6 @@ Drop the connection immediately with a 521 SMTP reply. Repeat
 this test the next time the client connects.
 .PP
 This feature is available in Postfix 2.8.
-.SH postscreen_blacklist_networks (default: empty)
-Network addresses that are permanently blacklisted; see the
-postscreen_blacklist_action parameter for possible actions.  This
-parameter uses the same address syntax as the mynetworks parameter.
-The blacklist has higher precedence than whitelists. This feature
-never uses the remote SMTP client hostname.
-.PP
-This feature is available in Postfix 2.8.
 .SH postscreen_cache_cleanup_interval (default: 12h)
 The amount of time between \fBpostscreen\fR(8) cache cleanup runs.
 Cache cleanup increases the load on the cache database and should
@@ -4192,13 +4244,6 @@ one-letter suffix that specifies the time unit).  Time units: s
 (seconds), m (minutes), h (hours), d (days), w (weeks).
 .PP
 This feature is available in Postfix 2.8.
-.SH postscreen_whitelist_networks (default: $mynetworks)
-Network addresses that are permanently whitelisted, and that
-will not be subjected to \fBpostscreen\fR(8) checks. This parameter uses
-the same address syntax as the mynetworks parameter. This feature
-never uses the remote SMTP client hostname.
-.PP
-This feature is available in Postfix 2.8.
 .SH prepend_delivered_header (default: command, file, forward)
 The message delivery contexts where the Postfix \fBlocal\fR(8) delivery
 agent prepends a Delivered-To:  message header with the address
index fbb0b7f8eaffc10f2c5514f9e428a25667892ee2..8888237b60b3add02c0427739bf214bcdd5af3ee 100644 (file)
@@ -135,18 +135,15 @@ to a remote SMTP client.
 A case insensitive list of EHLO keywords (pipelining, starttls,
 auth, etc.) that the \fBpostscreen\fR(8) server will not send in the EHLO
 response to a remote SMTP client.
-.SH "TRIAGE PARAMETERS"
+.SH "BEFORE-GREETING TRIAGE"
 .na
 .nf
 .ad
 .fi
-.IP "\fBpostscreen_bare_newline_action (ignore)\fR"
-The action that \fBpostscreen\fR(8) takes when an SMTP client sends
-a bare newline character, that is, a newline not preceded by carriage
-return.
-.IP "\fBpostscreen_bare_newline_enable (no)\fR"
-Enable "bare newline" SMTP protocol tests in the \fBpostscreen\fR(8)
-server.
+.IP "\fBpostscreen_access_list (permit_mynetworks)\fR"
+Permanent white/blacklist for remote SMTP client IP addresses;
+\fBpostscreen\fR(8) searches this list immediately after a remote SMTP
+client connects.
 .IP "\fBpostscreen_blacklist_action (ignore)\fR"
 The action that \fBpostscreen\fR(8) takes when an SMTP client is
 permanently blacklisted with the postscreen_blacklist_networks
@@ -154,8 +151,6 @@ parameter.
 .IP "\fBpostscreen_blacklist_networks (empty)\fR"
 Network addresses that are permanently blacklisted; see the
 postscreen_blacklist_action parameter for possible actions.
-.IP "\fBpostscreen_disable_vrfy_command ($disable_vrfy_command)\fR"
-Disable the SMTP VRFY command in the \fBpostscreen\fR(8) daemon.
 .IP "\fBpostscreen_dnsbl_action (ignore)\fR"
 The action that \fBpostscreen\fR(8) takes when an SMTP client's combined
 DNSBL score is equal to or greater than a threshold (as defined
@@ -172,9 +167,6 @@ factors.
 The inclusive lower bound for blocking an SMTP client, based on
 its combined DNSBL score as defined with the postscreen_dnsbl_sites
 parameter.
-.IP "\fBpostscreen_forbidden_commands ($smtpd_forbidden_commands)\fR"
-List of commands that the \fBpostscreen\fR(8) server considers in
-violation of the SMTP protocol.
 .IP "\fBpostscreen_greet_action (ignore)\fR"
 The action that \fBpostscreen\fR(8) takes when an SMTP client speaks
 before its turn within the time specified with the postscreen_greet_wait
@@ -190,6 +182,23 @@ The amount of time that \fBpostscreen\fR(8) will wait for an SMTP
 client to send a command before its turn, and for DNS blocklist
 lookup results to arrive (default: up to 2 seconds under stress,
 up to 6 seconds otherwise).
+.SH "AFTER-GREETING TRIAGE"
+.na
+.nf
+.ad
+.fi
+.IP "\fBpostscreen_bare_newline_action (ignore)\fR"
+The action that \fBpostscreen\fR(8) takes when an SMTP client sends
+a bare newline character, that is, a newline not preceded by carriage
+return.
+.IP "\fBpostscreen_bare_newline_enable (no)\fR"
+Enable "bare newline" SMTP protocol tests in the \fBpostscreen\fR(8)
+server.
+.IP "\fBpostscreen_disable_vrfy_command ($disable_vrfy_command)\fR"
+Disable the SMTP VRFY command in the \fBpostscreen\fR(8) daemon.
+.IP "\fBpostscreen_forbidden_commands ($smtpd_forbidden_commands)\fR"
+List of commands that the \fBpostscreen\fR(8) server considers in
+violation of the SMTP protocol.
 .IP "\fBpostscreen_helo_required ($smtpd_helo_required)\fR"
 Require that a remote SMTP client sends HELO or EHLO before
 commencing a MAIL transaction.
@@ -206,9 +215,11 @@ the server to respond.
 .IP "\fBpostscreen_pipelining_enable (no)\fR"
 Enable "pipelining" SMTP protocol tests in the \fBpostscreen\fR(8)
 server.
-.IP "\fBpostscreen_whitelist_networks ($mynetworks)\fR"
-Network addresses that are permanently whitelisted, and that
-will not be subjected to \fBpostscreen\fR(8) checks.
+.SH "AFTER-TRIAGE CONTROLS"
+.na
+.nf
+.ad
+.fi
 .IP "\fBsmtpd_service_name (smtpd)\fR"
 The internal service that \fBpostscreen\fR(8) forwards allowed
 connections to.
index 96269579a765ec0e7724245644312fbaabdebf5c..10f2376b93cfe64f1eb6b89f3ae2aa43148e8e96 100755 (executable)
@@ -945,6 +945,7 @@ while (<>) {
     s;\bpostscreen_pipelining_action\b;<a href="postconf.5.html#postscreen_pipelining_action">$&</a>;g;
     s;\bpostscreen_pipelining_ttl\b;<a href="postconf.5.html#postscreen_pipelining_ttl">$&</a>;g;
     s;\bpostscreen_watchdog_timeout\b;<a href="postconf.5.html#postscreen_watchdog_timeout">$&</a>;g;
+    s;\bpostscreen_access_list\b;<a href="postconf.5.html#postscreen_access_list">$&</a>;g;
     s;\bpostscreen_whitelist_networks\b;<a href="postconf.5.html#postscreen_whitelist_networks">$&</a>;g;
     s;\bpostscreen_black[-</bB>]*\n*[ <bB>]*list_networks\b;<a href="postconf.5.html#postscreen_blacklist_networks">$&</a>;g;
     s;\bpostscreen_black[-</bB>]*\n*[ <bB>]*list_action\b;<a href="postconf.5.html#postscreen_blacklist_action">$&</a>;g;
index 503aec71afdc06c034d5929c4e4238a690f2013f..9231bef79b05b153a44c8be69a771c52d5672e8e 100644 (file)
@@ -146,35 +146,50 @@ handling of known clients. </p>
 
 <ul>
 
-<li> <a href="#perm_white"> Permanent whitelist test </a>
-
-<li> <a href="#perm_black"> Permanent blacklist test </a>
+<li> <a href="#perm_white_black"> Permanent white/blacklist test </a>
 
 <li> <a href="#temp_white"> Temporary whitelist test </a>
 
 </ul>
 
-<h3> <a name="perm_white"> Permanent whitelist test </a> </h3>
+<h3> <a name="perm_white_black"> Permanent white/blacklist test </a> </h3>
+
+<p> The postscreen_access_list parameter (default: permit_mynetworks)
+specifies a permanent access list for SMTP client IP addresses. Typically
+one would specify something that whitelists local networks, followed
+by a CIDR table for selective white- and blacklisting. </p>
 
-<p> The postscreen_whitelist_networks parameter (default: $mynetworks)
-specifies a permanent whitelist for SMTP client IP addresses.  When
-the SMTP client address matches the permanent whitelist, postscreen(8)
-logs this with the client address and port number as: </p>
+<p> Example: </p>
+
+<pre>
+/etc/postfix/main.cf:
+    postscreen_access_list = permit_mynetworks,
+        /etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.cidr:
+   # Rules are evaluated in the order as specified.
+   # Blacklist 192.168.* except 192.168.0.1.
+   192.168.0.1          permit
+   192.168.0.0/16       reject
+</pre>
+
+<p> See the postscreen_access_list manpage documentation for more
+details.  </p>
+
+<p> When the SMTP client address matches a "permit" action,
+postscreen(8) logs this with the client address and port number as:
+</p>
 
 <pre>
     <b>WHITELISTED</b> <i>[address]:port</i>
 </pre>
 
-<p> The action is not configurable: immediately hand off the
+<p> The whitelist action is not configurable: immediately hand off the
 connection to a Postfix SMTP server process. </p>
 
-<h3> <a name="perm_black"> Permanent blacklist test </a>  </h3>
-
-<p> The postscreen_blacklist_networks parameter (default: empty)
-specifies a permanent blacklist for SMTP client IP addresses.  The
-address syntax is as with mynetworks.  When the SMTP client address
-matches the permanent blacklist, postscreen(8) logs this with the
-client address and port number as: </p>
+<p> When the SMTP client address matches a "reject" action,
+postscreen(8) logs this with the client address and port number as:
+</p>
 
 <pre>
     <b>BLACKLISTED</b> <i>[address]:port</i>
@@ -224,7 +239,7 @@ for the short postscreen_greet_wait delay).  </p>
 
 <li> <a href="#pregreet"> Pregreet test </a>
 
-<li> <a href="#dnsbl"> DNS Blocklist test </a>
+<li> <a href="#dnsbl"> DNS White/blacklist test </a>
 
 <li> <a href="#fail_before_220">When tests fail before the 220 SMTP server greeting</a>
 
@@ -247,13 +262,18 @@ SMTP clients that correctly implement the protocol.  </p>
 
 <p> To avoid problems with poorly-implemented SMTP engines in network
 appliances or network testing tools, either exclude them from all
-tests with the postscreen_whitelist_networks feature or else specify
+tests with the postscreen_access_list feature or else specify
 an empty teaser banner: </p>
 
 <pre>
 /etc/postfix/main.cf:
-    # Exclude broken clients by whitelisting. $mynetworks is default.
-    postscreen_whitelist_networks = $mynetworks, 192.168.254.0/24
+    # Exclude broken clients by whitelisting. Clients in mynetworks
+    # should always be whitelisted.
+    postscreen_access_list = permit_mynetworks, 
+        cidr:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.cidr:
+    192.168.254.0/24 permit
 </pre>
 
 <pre>
@@ -281,12 +301,13 @@ and \n for newline). </p>
 is taken next.  See "<a href="#fail_before_220">When tests fail
 before the 220 SMTP server greeting</a>" below. </p>
 
-<h3> <a name="dnsbl"> DNS Blocklist test </a> </h3>
+<h3> <a name="dnsbl"> DNS White/blacklist test </a> </h3>
 
 <p> The postscreen_dnsbl_sites parameter (default: empty) specifies
 a list of DNS blocklist servers with optional filters and weight
-factors.  These servers will be queried in parallel with the reverse
-client IP address. This test is disabled by default. </p>
+factors (positive weights for blacklisting, negative for whitelisting).
+These servers will be queried in parallel with the reverse client
+IP address.  This test is disabled by default. </p>
 
 <blockquote>
 <p>
@@ -799,9 +820,9 @@ reply; these clients were not so good after all.  Wietse enables
 "<a href="#after_220">deep protocol tests</a>" on his own internet-facing
 mail server.  </p>
 
-<li> <p> There is also support for permanent blacklists and whitelists;
-see the description of the postscreen_whitelist_networks and
-postscreen_blacklist_networks parameters for details. </p>
+<li> <p> There is also support for permanent blacklisting and
+whitelisting; see the description of the postscreen_access_list
+parameter for details. </p>
 
 </ul>
 
index 2885e9807675d5442d52ad022874214c93634efb..c48412f07141df6538e631c541f3d3f55c406e93 100644 (file)
@@ -12810,23 +12810,80 @@ IP address. </p>
 
 <p> This feature is available in Postfix 2.8. </p>
 
-%PARAM postscreen_whitelist_networks $mynetworks
+#%PARAM postscreen_whitelist_networks $mynetworks
+#
+#<p> Network addresses that are permanently whitelisted, and that
+#will not be subjected to postscreen(8) checks. This parameter uses
+#the same address syntax as the mynetworks parameter. This feature
+#never uses the remote SMTP client hostname.  </p>
+#
+#<p> This feature is available in Postfix 2.8. </p>
+#
+#%PARAM postscreen_blacklist_networks 
+#
+#<p> Network addresses that are permanently blacklisted; see the
+#postscreen_blacklist_action parameter for possible actions.  This
+#parameter uses the same address syntax as the mynetworks parameter.
+#The blacklist has higher precedence than whitelists. This feature
+#never uses the remote SMTP client hostname.  </p>
+#
+#<p> This feature is available in Postfix 2.8. </p>
 
-<p> Network addresses that are permanently whitelisted, and that
-will not be subjected to postscreen(8) checks. This parameter uses
-the same address syntax as the mynetworks parameter. This feature
-never uses the remote SMTP client hostname.  </p>
+%PARAM postscreen_access_list permit_mynetworks
 
-<p> This feature is available in Postfix 2.8. </p>
+<p> Permanent white/blacklist for remote SMTP client IP addresses;
+postscreen(8) searches this list immediately after a remote SMTP
+client connects.  Specify a comma- or whitespace-separated list of
+commands (in upper or lower case) or lookup tables. The search stops
+upon the first command that fires for the client IP address. </p>
+
+<dl>
+
+<dt> <b> permit_mynetworks </b> </dt> <dd> Whitelist the client and
+terminate the search if the client IP address matches $mynetworks.
+Do not subject the client to any before/after 220 greeting tests.
+Pass the connection immediately to a Postfix SMTP server process.
+</dd>
+
+<dt> <b> type:table </b> </dt> <dd> Query the specified lookup
+table. Each table lookup result is an access list, except that
+access lists inside a table cannot specify type:table entries.  <br>
+To discourage the use of hash, btree, etc. tables, there is no
+support for substring matching like smtpd(8). Use CIDR tables
+instead.  </dd>
+
+<dt> <b> permit </b> </dt> <dd> Whitelist the client and terminate
+the search. Do not subject the client to any before/after 220
+greeting tests. Pass the connection immediately to a Postfix SMTP
+server process. </dd>
 
-%PARAM postscreen_blacklist_networks 
+<dt> <b> reject </b> </dt> <dd> Blacklist the client and terminate
+the search. Subject the client to the action configured with the
+postscreen_blacklist_action configuration parameter. </dd>
 
-<p> Network addresses that are permanently blacklisted; see the
-postscreen_blacklist_action parameter for possible actions.  This
-parameter uses the same address syntax as the mynetworks parameter.
-The blacklist has higher precedence than whitelists. This feature
-never uses the remote SMTP client hostname.  </p>
+<dt> <b> dunno </b> </dt> <dd> When used inside a lookup table,
+return from the lookup table and evaluate the next command.  <br>
+When used outside a lookup table, terminate the search, and subject
+the client to the configured before/after 220 greeting tests. </dd>
 
+</dl>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/main.cf:
+    postscreen_access_list = permit_mynetworks, 
+               cidr:/etc/postfix/postscreen_access.cidr
+</pre>
+
+<pre>
+/etc/postfix/postscreen_access.cidr:
+    # Rules are evaluated in the order as specified.
+    # Blacklist 192.168.* except 192.168.0.1.
+    192.168.0.1         dunno
+    192.168.0.0/16      reject
+</pre>
+    
 <p> This feature is available in Postfix 2.8. </p>
 
 %PARAM postscreen_greet_banner $smtpd_banner
index b430a09168e512499e64e108d20be1500578a32d..1a35114125896dd8646e7d0ac9c3dbb0c5e13e42 100644 (file)
@@ -283,6 +283,9 @@ header_body_checks: header_body_checks.c $(LIB) $(LIBS)
 data_redirect: data_redirect.c $(LIB) $(LIBS)
        $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
 
+addr_match_list: addr_match_list.c $(LIB) $(LIBS)
+       $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+
 tests: tok822_test mime_tests strip_addr_test tok822_limit_test \
        xtext_test scache_multi_test ehlo_mask_test \
        namadr_list_test mail_conf_time_test header_body_checks_tests
index a066c10724e42b3246e74ddbb3cec5bd375df84f..7ba1166bbdc76d12e6d4b6e1b99414cfee051df6 100644 (file)
@@ -78,7 +78,9 @@
 #include <msg.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <string.h>
 #include <vstream.h>
+#include <vstring_vstream.h>
 #include <msg_vstream.h>
 
 static void usage(char *progname)
@@ -89,7 +91,6 @@ static void usage(char *progname)
 int     main(int argc, char **argv)
 {
     ADDR_MATCH_LIST *list;
-    char   *host;
     char   *addr;
     int     ch;
 
@@ -108,9 +109,19 @@ int     main(int argc, char **argv)
        usage(argv[0]);
     list = addr_match_list_init(MATCH_FLAG_PARENT, argv[optind]);
     addr = argv[optind + 1];
-    vstream_printf("%s: %s\n", addr,
-                  addr_match_list_match(list, addr) ?
-                  "YES" : "NO");
+    if (strcmp(addr, "-") == 0) {
+       VSTRING *buf = vstring_alloc(100);
+
+       while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF)
+           vstream_printf("%s: %s\n", vstring_str(buf),
+                          addr_match_list_match(list, vstring_str(buf)) ?
+                          "YES" : "NO");
+       vstring_free(buf);
+    } else {
+       vstream_printf("%s: %s\n", addr,
+                      addr_match_list_match(list, addr) ?
+                      "YES" : "NO");
+    }
     vstream_fflush(VSTREAM_OUT);
     addr_match_list_free(list);
     return (0);
index fa01c529340e802cc4ee8ff9b896ce69b5bca06a..d7dda00487424bfc70f7ffa42726acbb83982d9c 100644 (file)
@@ -3435,6 +3435,16 @@ extern char *var_psc_exp_filter;
 #define DEF_PSC_CMD_FILTER     ""
 extern char *var_psc_cmd_filter;
 
+#define PSC_ACL_NAME_WL_MYNETWORKS "permit_mynetworks"
+#define PSC_ACL_NAME_WHITELIST "permit"
+#define PSC_ACL_NAME_BLACKLIST "reject"
+#define PSC_ACL_NAME_DUNNO     "dunno"
+#define PSC_ACL_NAME_ERROR     "error"
+
+#define VAR_PSC_ACL            "postscreen_access_list"
+#define DEF_PSC_ACL            PSC_ACL_NAME_WL_MYNETWORKS
+extern char *var_psc_acl;
+
 #define VAR_DNSBLOG_DELAY      "dnsblog_reply_delay"
 #define DEF_DNSBLOG_DELAY      "0s"
 extern int var_dnsblog_delay;
index 989e78697e427b4c4c72ff9237c5c509f443758d..ac90cf17f87b1fc5d66c6c01fff26146eaaac30f 100644 (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      "20110109"
+#define MAIL_RELEASE_DATE      "20110112"
 #define MAIL_VERSION_NUMBER    "2.8"
 
 #ifdef SNAPSHOT
index 013f0f7b49dfb8fc5d375fc813a80bd75f8f4b4d..2afc1da0c4b0b3d1a4e651533956d1833bd2bb59 100644 (file)
@@ -2,16 +2,16 @@ SHELL = /bin/sh
 SRCS   = postscreen.c postscreen_dict.c postscreen_dnsbl.c \
        postscreen_early.c postscreen_smtpd.c postscreen_misc.c \
        postscreen_state.c postscreen_tests.c postscreen_send.c \
-       postscreen_starttls.c postscreen_expand.c
+       postscreen_starttls.c postscreen_expand.c postscreen_access.c
 OBJS   = postscreen.o postscreen_dict.o postscreen_dnsbl.o \
        postscreen_early.o postscreen_smtpd.o postscreen_misc.o \
        postscreen_state.o postscreen_tests.o postscreen_send.o \
-       postscreen_starttls.o postscreen_expand.o
+       postscreen_starttls.o postscreen_expand.o postscreen_access.o
 HDRS   = 
 TESTSRC        =
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
-TESTPROG= 
+TESTPROG= postscreen_access
 PROG   = postscreen
 INC_DIR = ../../include
 LIBS   = ../../lib/libmaster.a ../../lib/libtls.a ../../lib/libglobal.a \
@@ -38,6 +38,11 @@ update: ../../libexec/$(PROG)
 ../../libexec/$(PROG): $(PROG)
        cp $(PROG) ../../libexec
 
+postscreen_access: $(PROG) $(LIBS)
+       mv $@.o junk
+       $(CC) -DTEST $(CFLAGS) -o $@ $@.c $(LIBS) $(SYSLIBS)
+       mv junk $@.o
+
 printfck: $(OBJS) $(PROG)
        rm -rf printfck
        mkdir printfck
@@ -93,6 +98,27 @@ postscreen.o: ../../include/vstream.h
 postscreen.o: ../../include/vstring.h
 postscreen.o: postscreen.c
 postscreen.o: postscreen.h
+postscreen_access.o: ../../include/addr_match_list.h
+postscreen_access.o: ../../include/argv.h
+postscreen_access.o: ../../include/dict.h
+postscreen_access.o: ../../include/dict_cache.h
+postscreen_access.o: ../../include/events.h
+postscreen_access.o: ../../include/htable.h
+postscreen_access.o: ../../include/mail_params.h
+postscreen_access.o: ../../include/maps.h
+postscreen_access.o: ../../include/match_list.h
+postscreen_access.o: ../../include/match_ops.h
+postscreen_access.o: ../../include/match_parent_style.h
+postscreen_access.o: ../../include/msg.h
+postscreen_access.o: ../../include/mymalloc.h
+postscreen_access.o: ../../include/string_list.h
+postscreen_access.o: ../../include/stringops.h
+postscreen_access.o: ../../include/sys_defs.h
+postscreen_access.o: ../../include/vbuf.h
+postscreen_access.o: ../../include/vstream.h
+postscreen_access.o: ../../include/vstring.h
+postscreen_access.o: postscreen.h
+postscreen_access.o: postscreen_access.c
 postscreen_dict.o: ../../include/addr_match_list.h
 postscreen_dict.o: ../../include/argv.h
 postscreen_dict.o: ../../include/dict.h
index 2ba285c0e4b55759ba2705ec5f7a11d46a4631d9..3d4f30f48165f9f932d8c4043d8c7db067343ecc 100644 (file)
 /*     A case insensitive list of EHLO keywords (pipelining, starttls,
 /*     auth, etc.) that the \fBpostscreen\fR(8) server will not send in the EHLO
 /*     response to a remote SMTP client.
-/* TRIAGE PARAMETERS
+/* BEFORE-GREETING TRIAGE
 /* .ad
 /* .fi
-/* .IP "\fBpostscreen_bare_newline_action (ignore)\fR"
-/*     The action that \fBpostscreen\fR(8) takes when an SMTP client sends
-/*     a bare newline character, that is, a newline not preceded by carriage
-/*     return.
-/* .IP "\fBpostscreen_bare_newline_enable (no)\fR"
-/*     Enable "bare newline" SMTP protocol tests in the \fBpostscreen\fR(8)
-/*     server.
+/* .IP "\fBpostscreen_access_list (permit_mynetworks)\fR"
+/*     Permanent white/blacklist for remote SMTP client IP addresses;
+/*     \fBpostscreen\fR(8) searches this list immediately after a remote SMTP
+/*     client connects.
 /* .IP "\fBpostscreen_blacklist_action (ignore)\fR"
 /*     The action that \fBpostscreen\fR(8) takes when an SMTP client is
 /*     permanently blacklisted with the postscreen_blacklist_networks
 /* .IP "\fBpostscreen_blacklist_networks (empty)\fR"
 /*     Network addresses that are permanently blacklisted; see the
 /*     postscreen_blacklist_action parameter for possible actions.
-/* .IP "\fBpostscreen_disable_vrfy_command ($disable_vrfy_command)\fR"
-/*     Disable the SMTP VRFY command in the \fBpostscreen\fR(8) daemon.
 /* .IP "\fBpostscreen_dnsbl_action (ignore)\fR"
 /*     The action that \fBpostscreen\fR(8) takes when an SMTP client's combined
 /*     DNSBL score is equal to or greater than a threshold (as defined
 /*     The inclusive lower bound for blocking an SMTP client, based on
 /*     its combined DNSBL score as defined with the postscreen_dnsbl_sites
 /*     parameter.
-/* .IP "\fBpostscreen_forbidden_commands ($smtpd_forbidden_commands)\fR"
-/*     List of commands that the \fBpostscreen\fR(8) server considers in
-/*     violation of the SMTP protocol.
 /* .IP "\fBpostscreen_greet_action (ignore)\fR"
 /*     The action that \fBpostscreen\fR(8) takes when an SMTP client speaks
 /*     before its turn within the time specified with the postscreen_greet_wait
 /*     client to send a command before its turn, and for DNS blocklist
 /*     lookup results to arrive (default: up to 2 seconds under stress,
 /*     up to 6 seconds otherwise).
+/* AFTER-GREETING TRIAGE
+/* .ad
+/* .fi
+/* .IP "\fBpostscreen_bare_newline_action (ignore)\fR"
+/*     The action that \fBpostscreen\fR(8) takes when an SMTP client sends
+/*     a bare newline character, that is, a newline not preceded by carriage
+/*     return.
+/* .IP "\fBpostscreen_bare_newline_enable (no)\fR"
+/*     Enable "bare newline" SMTP protocol tests in the \fBpostscreen\fR(8)
+/*     server.
+/* .IP "\fBpostscreen_disable_vrfy_command ($disable_vrfy_command)\fR"
+/*     Disable the SMTP VRFY command in the \fBpostscreen\fR(8) daemon.
+/* .IP "\fBpostscreen_forbidden_commands ($smtpd_forbidden_commands)\fR"
+/*     List of commands that the \fBpostscreen\fR(8) server considers in
+/*     violation of the SMTP protocol.
 /* .IP "\fBpostscreen_helo_required ($smtpd_helo_required)\fR"
 /*     Require that a remote SMTP client sends HELO or EHLO before
 /*     commencing a MAIL transaction.
 /* .IP "\fBpostscreen_pipelining_enable (no)\fR"
 /*     Enable "pipelining" SMTP protocol tests in the \fBpostscreen\fR(8)
 /*     server.
-/* .IP "\fBpostscreen_whitelist_networks ($mynetworks)\fR"
-/*     Network addresses that are permanently whitelisted, and that
-/*     will not be subjected to \fBpostscreen\fR(8) checks.
+/* AFTER-TRIAGE CONTROLS
+/* .ad
+/* .fi
 /* .IP "\fBsmtpd_service_name (smtpd)\fR"
 /*     The internal service that \fBpostscreen\fR(8) forwards allowed
 /*     connections to.
@@ -394,8 +401,14 @@ int     var_psc_post_queue_limit;
 int     var_psc_pre_queue_limit;
 int     var_psc_watchdog;
 
+#define MIGRATION_WARNING
+
+#ifdef MIGRATION_WARNING
 char   *var_psc_wlist_nets;
 char   *var_psc_blist_nets;
+
+#endif
+char   *var_psc_acl;
 char   *var_psc_blist_action;
 
 char   *var_psc_greet_ttl;
@@ -464,8 +477,12 @@ HTABLE *psc_client_concurrency;            /* per-client concurrency */
  /*
   * Local variables.
   */
+#ifdef MIGRATION_WARNING
 static ADDR_MATCH_LIST *psc_wlist_nets;        /* permanently whitelisted networks */
 static ADDR_MATCH_LIST *psc_blist_nets;        /* permanently blacklisted networks */
+
+#endif
+static ARGV *psc_acl;                  /* permanent white/backlist */
 static int psc_blist_action;           /* PSC_ACT_DROP/ENFORCE/etc */
 
 /* psc_dump - dump some statistics before exit */
@@ -539,7 +556,6 @@ static void psc_service(VSTREAM *smtp_client_stream,
     MAI_SERVPORT_STR smtp_client_port;
     int     aierr;
     const char *stamp_str;
-    int     window_size;
     int     saved_flags;
 
     /*
@@ -631,6 +647,58 @@ static void psc_service(VSTREAM *smtp_client_stream,
        return;
     }
 
+    /*
+     * The permanent white/blacklist has highest precedence.
+     */
+    if (psc_acl != 0) {
+       switch (psc_acl_eval(state, psc_acl, VAR_PSC_ACL)) {
+
+           /*
+            * Permanently blacklisted.
+            */
+       case PSC_ACL_ACT_BLACKLIST:
+           msg_info("BLACKLISTED [%s]:%s", PSC_CLIENT_ADDR_PORT(state));
+           PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_BLIST_FAIL);
+           switch (psc_blist_action) {
+           case PSC_ACT_DROP:
+               PSC_DROP_SESSION_STATE(state,
+                            "521 5.3.2 Service currently unavailable\r\n");
+               return;
+           case PSC_ACT_ENFORCE:
+               PSC_ENFORCE_SESSION_STATE(state,
+                            "550 5.3.2 Service currently unavailable\r\n");
+               break;
+           case PSC_ACT_IGNORE:
+               PSC_UNFAIL_SESSION_STATE(state, PSC_STATE_FLAG_BLIST_FAIL);
+
+               /*
+                * Not: PSC_PASS_SESSION_STATE. Repeat this test the next
+                * time.
+                */
+               break;
+           default:
+               msg_panic("%s: unknown blacklist action value %d",
+                         myname, psc_blist_action);
+           }
+           break;
+
+           /*
+            * Permanently whitelisted.
+            */
+       case PSC_ACL_ACT_WHITELIST:
+           msg_info("WHITELISTED [%s]:%s", PSC_CLIENT_ADDR_PORT(state));
+           psc_conclude(state);
+           return;
+
+           /*
+            * Other: dunno (don't know) or error.
+            */
+       default:
+           break;
+       }
+    }
+#ifdef MIGRATION_WARNING
+
     /*
      * The permanent whitelist has highest precedence (never block mail from
      * whitelisted sites, and never run tests against those sites).
@@ -669,6 +737,7 @@ static void psc_service(VSTREAM *smtp_client_stream,
                      myname, psc_blist_action);
        }
     }
+#endif
 
     /*
      * The temporary whitelist (i.e. the postscreen cache) has the lowest
@@ -712,18 +781,6 @@ static void psc_service(VSTREAM *smtp_client_stream,
        return;
     }
 
-    /*
-     * Before commencing the tests we could set the TCP window to the
-     * smallest possible value to save some network bandwidth, at least with
-     * spamware that waits until the server starts speaking.
-     */
-#if 0
-    window_size = 1;
-    if (setsockopt(vstream_fileno(smtp_client_stream), SOL_SOCKET, SO_RCVBUF,
-                  (char *) &window_size, sizeof(window_size)) < 0)
-       msg_warn("setsockopt SO_RCVBUF %d: %m", window_size);
-#endif
-
     /*
      * If the client has no up-to-date results for some tests, do those tests
      * first. Otherwise, skip the tests and hand off the connection.
@@ -766,6 +823,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
      * Open read-only maps before dropping privilege, for consistency with
      * other Postfix daemons.
      */
+#ifdef MIGRATION_WARNING
     if (*var_psc_wlist_nets)
        psc_wlist_nets =
            addr_match_list_init(MATCH_FLAG_NONE, var_psc_wlist_nets);
@@ -773,6 +831,16 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
     if (*var_psc_blist_nets)
        psc_blist_nets = addr_match_list_init(MATCH_FLAG_NONE,
                                              var_psc_blist_nets);
+    if (psc_blist_nets || psc_wlist_nets) {
+       msg_warn("The %s and %s features will be removed soon. Use %s instead",
+                VAR_PSC_WLIST_NETS, VAR_PSC_BLIST_NETS, VAR_PSC_ACL);
+       msg_warn("To stop this warning, specify empty values for %s and %s",
+                VAR_PSC_WLIST_NETS, VAR_PSC_BLIST_NETS);
+    }
+#endif
+    psc_acl_pre_jail_init();
+    if (*var_psc_acl)
+       psc_acl = psc_acl_parse(var_psc_acl, VAR_PSC_ACL);
     if (*var_psc_forbid_cmds)
        psc_forbid_cmds = string_list_init(MATCH_FLAG_NONE,
                                           var_psc_forbid_cmds);
@@ -1002,8 +1070,11 @@ int     main(int argc, char **argv)
        VAR_PSC_PIPEL_ACTION, DEF_PSC_PIPEL_ACTION, &var_psc_pipel_action, 1, 0,
        VAR_PSC_NSMTP_ACTION, DEF_PSC_NSMTP_ACTION, &var_psc_nsmtp_action, 1, 0,
        VAR_PSC_BARLF_ACTION, DEF_PSC_BARLF_ACTION, &var_psc_barlf_action, 1, 0,
+#ifdef MIGRATION_WARNING
        VAR_PSC_WLIST_NETS, DEF_PSC_WLIST_NETS, &var_psc_wlist_nets, 0, 0,
        VAR_PSC_BLIST_NETS, DEF_PSC_BLIST_NETS, &var_psc_blist_nets, 0, 0,
+#endif
+       VAR_PSC_ACL, DEF_PSC_ACL, &var_psc_acl, 0, 0,
        VAR_PSC_BLIST_ACTION, DEF_PSC_BLIST_ACTION, &var_psc_blist_action, 1, 0,
        VAR_PSC_FORBID_CMDS, DEF_PSC_FORBID_CMDS, &var_psc_forbid_cmds, 0, 0,
        VAR_PSC_EHLO_DIS_WORDS, DEF_PSC_EHLO_DIS_WORDS, &var_psc_ehlo_dis_words, 0, 0,
index 74f35a30d0f859b5868135ec289ba7fc9146107a..f141a0d367bd2c84b9d88617323007c65463db70 100644 (file)
@@ -459,6 +459,18 @@ extern VSTRING *psc_expand_filter;
 extern void psc_expand_init(void);
 extern const char *psc_expand_lookup(const char *, int, char *);
 
+ /*
+  * postscreen_access.c
+  */
+#define PSC_ACL_ACT_WHITELIST  1
+#define PSC_ACL_ACT_DUNNO      0
+#define PSC_ACL_ACT_BLACKLIST  (-1)
+#define PSC_ACL_ACT_ERROR      (-2)
+
+extern void psc_acl_pre_jail_init(void);
+extern ARGV *psc_acl_parse(const char *, const char *);
+extern int psc_acl_eval(PSC_STATE *,ARGV *, const char *);
+
 /* LICENSE
 /* .ad
 /* .fi
diff --git a/postfix/src/postscreen/postscreen_access.c b/postfix/src/postscreen/postscreen_access.c
new file mode 100644 (file)
index 0000000..52a3208
--- /dev/null
@@ -0,0 +1,252 @@
+/*++
+/* NAME
+/*     postscreen_access 3
+/* SUMMARY
+/*     postscreen access list support
+/* SYNOPSIS
+/*     #include <postscreen.h>
+/*
+/*     void    psc_acl_pre_jail_init()
+/*
+/*     ARGV    *psc_acl_parse(raw_acl, origin)
+/*     const char *raw_acl;
+/*     const char *origin;
+/*
+/*     int     psc_acl_eval(state, cooked_acl, origin)
+/*     PSC_STATE *state;
+/*     ARGV    *cooked_acl;
+/*     const char *origin;
+/* DESCRIPTION
+/*     This module implements the permanent black/whitelist that
+/*     is evaluated immediately after a client connects to postscreen.
+/*
+/*     psc_acl_pre_jail_init() does before-chroot initialization.
+/*
+/*     psc_acl_parse() converts an access list from raw string
+/*     form to binary form.
+/*
+/*     psc_acl_eval() evaluates an access list for the specified
+/*     SMTP session.
+/*
+/*     Arguments:
+/* .IP raw_acl
+/*     String with space/comma separated commands.
+/* .IP cooked_acl
+/*     The parsed access list.
+/* .IP origin
+/*     This should be "postscreen_access_list" for an access list
+/*     from main.cf, and the type:name of a lookup table otherwise.
+/*     The information is used for error reporting (nested table,
+/*     unknown keyword).
+/* .IP state
+/*     Connection state.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <string.h>
+
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <stringops.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+#include <addr_match_list.h>
+#include <match_parent_style.h>
+
+/* Application-specific. */
+
+#include <postscreen.h>
+
+#define PSC_ACL_SEPARATORS     " \t\r"
+
+static ADDR_MATCH_LIST *psc_mynetworks;
+
+/* psc_acl_pre_jail_init - initialize */
+
+void    psc_acl_pre_jail_init(void)
+{
+    if (psc_mynetworks)
+       addr_match_list_free(psc_mynetworks);
+    psc_mynetworks = addr_match_list_init(match_parent_style(VAR_MYNETWORKS),
+                                         var_mynetworks);
+}
+
+/* psc_acl_parse - parse access list */
+
+ARGV   *psc_acl_parse(const char *acl, const char *origin)
+{
+    char   *saved_checks = mystrdup(acl);
+    ARGV   *argv = argv_alloc(1);
+    char   *bp = saved_checks;
+    char   *name;
+
+#define STREQ(x,y) ((*x) == (*y) && strcasecmp((x), (y)) == 0)
+#define STRNE(x,y) ((*x) != (*y) || strcasecmp((x), (y)) != 0)
+
+    /*
+     * Nested tables are not allowed. Tables are opened before entering the
+     * chroot jail, while access lists are evaluated after entering the
+     * chroot jail.
+     */
+    while ((name = mystrtok(&bp, PSC_ACL_SEPARATORS)) != 0) {
+       if (strchr(name, ':') != 0) {
+           if (STRNE(origin, VAR_PSC_ACL)) {
+               msg_warn("table %s: lookup result \"%s\" is not allowed"
+                        " -- ignoring remainder of access list",
+                        origin, name);
+               argv_add(argv, PSC_ACL_NAME_DUNNO, (char *) 0);
+               break;
+           } else {
+               if (dict_handle(name) == 0)
+                   dict_register(name, dict_open(name, O_RDONLY, DICT_FLAG_LOCK
+                                                 | DICT_FLAG_FOLD_FIX));
+           }
+       }
+       argv_add(argv, name, (char *) 0);
+    }
+    argv_terminate(argv);
+
+    /*
+     * Cleanup.
+     */
+    myfree(saved_checks);
+    return (argv);
+}
+
+/* psc_acl_eval - evaluate access list */
+
+int     psc_acl_eval(PSC_STATE *state, ARGV *acl, const char *origin)
+{
+    const char *myname = "psc_acl_eval";
+    char  **cpp;
+    DICT   *dict;
+    ARGV   *argv;
+    const char *name;
+    const char *dict_val;
+    int     ret;
+
+    for (cpp = acl->argv; (name = *cpp) != 0; cpp++) {
+       if (msg_verbose)
+           msg_info("source=%s address=%s acl=%s",
+                    origin, state->smtp_client_addr, name);
+       if (STREQ(name, PSC_ACL_NAME_BLACKLIST)) {
+           return (PSC_ACL_ACT_BLACKLIST);
+       } else if (STREQ(name, PSC_ACL_NAME_WHITELIST)) {
+           return (PSC_ACL_ACT_WHITELIST);
+       } else if (STREQ(name, PSC_ACL_NAME_WL_MYNETWORKS)) {
+           if (addr_match_list_match(psc_mynetworks, state->smtp_client_addr))
+               return (PSC_ACL_ACT_WHITELIST);
+       } else if (strchr(name, ':') != 0) {
+           if ((dict = dict_handle(name)) == 0)
+               msg_panic("%s: unexpected dictionary: %s", myname, name);
+           if ((dict_val = dict_get(dict, state->smtp_client_addr)) != 0) {
+               argv = psc_acl_parse(dict_val, name);
+               ret = psc_acl_eval(state, argv, name);
+               argv_free(argv);
+               if (ret != PSC_ACL_ACT_DUNNO)
+                   return (ret);
+           } else if (dict_errno != 0) {
+               msg_warn("%s: table lookup error -- ignoring the remainder "
+                        "of this access list", name);
+               return (PSC_ACL_ACT_ERROR);
+           }
+       } else {
+           msg_warn("%s: unknown command: %s -- ignoring the remainder "
+                    "of this access list", origin, name);
+           return (PSC_ACL_ACT_ERROR);
+       }
+    }
+    if (msg_verbose)
+       msg_info("source=%s address=%s - no match",
+                origin, state->smtp_client_addr);
+    return (PSC_ACL_ACT_DUNNO);
+}
+
+ /*
+  * Access lists need testing. Not only with good inputs; error cases must
+  * also be handled appropriately.
+  */
+#ifdef TEST
+#include <unistd.h>
+#include <stdlib.h>
+#include <vstring_vstream.h>
+#include <name_code.h>
+#include <split_at.h>
+
+char   *var_par_dom_match = DEF_PAR_DOM_MATCH;
+char   *var_mynetworks = "";
+char   *var_psc_acl = "";
+
+#define UPDATE_VAR(s,v) do { if (*(s)) myfree(s); (s) = mystrdup(v); } while (0)
+
+int     main(void)
+{
+    VSTRING *buf = vstring_alloc(100);
+    PSC_STATE state;
+    ARGV   *argv;
+    int     ret;
+    int     have_tty = isatty(0);
+    char   *bufp;
+    char   *cmd;
+    char   *value;
+    const NAME_CODE acl_map[] = {
+       PSC_ACL_NAME_ERROR, PSC_ACL_ACT_ERROR,
+       PSC_ACL_NAME_WHITELIST, PSC_ACL_ACT_WHITELIST,
+       PSC_ACL_NAME_BLACKLIST, PSC_ACL_ACT_BLACKLIST,
+       PSC_ACL_NAME_DUNNO, PSC_ACL_ACT_DUNNO,
+       0,
+    };
+
+    while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
+       bufp = STR(buf);
+       if (have_tty == 0) {
+           vstream_printf("> %s\n", bufp);
+           vstream_fflush(VSTREAM_OUT);
+       }
+       if (*bufp == '#')
+           continue;
+       if ((cmd = mystrtok(&bufp, " =")) == 0 || STREQ(cmd, "?")) {
+           vstream_printf("usage: %s=value|%s=value|address=value\n",
+                          VAR_MYNETWORKS, VAR_PSC_ACL);
+       } else if ((value = mystrtok(&bufp, " =")) == 0) {
+           vstream_printf("missing value\n");
+       } else if (STREQ(cmd, VAR_MYNETWORKS)) {
+           UPDATE_VAR(var_mynetworks, value);
+       } else if (STREQ(cmd, VAR_PSC_ACL)) {
+           UPDATE_VAR(var_psc_acl, value);
+       } else if (STREQ(cmd, "address")) {
+           psc_acl_pre_jail_init();
+           argv = psc_acl_parse(var_psc_acl, VAR_PSC_ACL);
+           state.smtp_client_addr = value;
+           ret = psc_acl_eval(&state, argv, VAR_PSC_ACL);
+           argv_free(argv);
+           vstream_printf("%s: %s\n", value, str_name_code(acl_map, ret));
+       } else {
+           vstream_printf("unknown command: \"%s\"\n", cmd);
+       }
+       vstream_fflush(VSTREAM_OUT);
+    }
+    vstring_free(buf);
+    exit(0);
+}
+
+#endif
index 3555427076c1af3147c8da0f8559d11af37e8fd5..9a99997fef997242da3757d8885539c093df991d 100644 (file)
@@ -90,8 +90,8 @@ int     psc_send_reply(PSC_STATE *state, const char *text)
     vstring_strcat(state->send_buf, text);
     if (*var_psc_rej_footer && (*text == '4' || *text == '5'))
        smtp_reply_footer(state->send_buf, start, var_psc_rej_footer,
-                          STR(psc_expand_filter), psc_expand_lookup,
-                          (char *) state);
+                         STR(psc_expand_filter), psc_expand_lookup,
+                         (char *) state);
 
     /*
      * XXX For soft_bounce support, it is not sufficient to fix replies here.
@@ -156,7 +156,6 @@ void    psc_send_socket(PSC_STATE *state)
 {
     const char *myname = "psc_send_socket";
     int     server_fd;
-    int     window_size;
 
     if (msg_verbose > 1)
        msg_info("%s: sq=%d cq=%d send socket %d from [%s]:%s",
@@ -164,17 +163,6 @@ void    psc_send_socket(PSC_STATE *state)
                 vstream_fileno(state->smtp_client_stream),
                 state->smtp_client_addr, state->smtp_client_port);
 
-    /*
-     * This is where we would adjust the window size to a value that is
-     * appropriate for this client class.
-     */
-#if 0
-    window_size = 65535;
-    if (setsockopt(vstream_fileno(state->smtp_client_stream), SOL_SOCKET, SO_RCVBUF,
-                  (char *) &window_size, sizeof(window_size)) < 0)
-       msg_warn("setsockopt SO_RCVBUF %d: %m", window_size);
-#endif
-
     /*
      * Connect to the real SMTP service over a local IPC channel, send the
      * file descriptor, and close the file descriptor to save resources.
@@ -192,8 +180,8 @@ void    psc_send_socket(PSC_STATE *state)
      * Postfix-specific.
      */
     if ((server_fd =
-       PASS_CONNECT(psc_smtpd_service_name, NON_BLOCKING,
-                    PSC_SEND_SOCK_CONNECT_TIMEOUT)) < 0) {
+        PASS_CONNECT(psc_smtpd_service_name, NON_BLOCKING,
+                     PSC_SEND_SOCK_CONNECT_TIMEOUT)) < 0) {
        msg_warn("cannot connect to service %s: %m", psc_smtpd_service_name);
        PSC_SEND_REPLY(state, "421 4.3.2 All server ports are busy\r\n");
        psc_free_session_state(state);
index 377347eb8307e037f8b21f8cbe422d2ff5d70c33..e3cc9271210b209c90dfdf534b61d56fb34ebfc0 100644 (file)
 #define PSC_SMTPD_NEXT_CHAR(state) \
        VSTREAM_GETC((state)->smtp_client_stream)
 
+#define PSC_SMTPD_BUFFER_EMPTY(state) \
+       (!PSC_SMTPD_HAVE_PUSH_BACK(state) \
+       && vstream_peek(state->smtp_client_stream) <= 0)
+
  /*
   * Dynamic reply strings. To minimize overhead we format these once.
   */
@@ -357,6 +361,7 @@ static void psc_starttls_resume(int unused_event, char *context)
      * Reset SMTP server state if STARTTLS was successful.
      */
     if (state->flags & PSC_STATE_FLAG_USING_TLS) {
+       /* Purge the push-back buffer, when implemented. */
        PSC_STRING_RESET(state->helo_name);
        PSC_STRING_RESET(state->sender);
 #ifdef TODO_SASL_AUTH
@@ -365,9 +370,12 @@ static void psc_starttls_resume(int unused_event, char *context)
     }
 
     /*
-     * Wait for the client to respond.
+     * Resume read/timeout events. If we still have unread input, resume the
+     * command processor immediately.
      */
     PSC_RESUME_SMTP_CMD_EVENTS(state);
+    if (!PSC_SMTPD_BUFFER_EMPTY(state))
+       psc_smtpd_read_event(EVENT_READ, (char *) state);
 }
 
 /* psc_starttls_cmd - activate the tlsproxy server */
@@ -620,11 +628,12 @@ typedef struct {
 #define PSC_SMTPD_CMD_FLAG_ENABLE      (1<<0)  /* command is enabled */
 #define PSC_SMTPD_CMD_FLAG_DESTROY     (1<<1)  /* dangling pointer alert */
 #define PSC_SMTPD_CMD_FLAG_PRE_TLS     (1<<2)  /* allowed with mandatory TLS */
+#define PSC_SMTPD_CMD_FLAG_SUSPEND     (1<<3)  /* suspend command engine */
 
 static const PSC_SMTPD_COMMAND command_table[] = {
     "HELO", psc_helo_cmd, PSC_SMTPD_CMD_FLAG_ENABLE | PSC_SMTPD_CMD_FLAG_PRE_TLS,
     "EHLO", psc_ehlo_cmd, PSC_SMTPD_CMD_FLAG_ENABLE | PSC_SMTPD_CMD_FLAG_PRE_TLS,
-    "STARTTLS", psc_starttls_cmd, PSC_SMTPD_CMD_FLAG_ENABLE | PSC_SMTPD_CMD_FLAG_PRE_TLS,
+    "STARTTLS", psc_starttls_cmd, PSC_SMTPD_CMD_FLAG_ENABLE | PSC_SMTPD_CMD_FLAG_PRE_TLS | PSC_SMTPD_CMD_FLAG_SUSPEND,
     "XCLIENT", psc_noop_cmd, PSC_SMTPD_CMD_FLAG_NONE,
     "XFORWARD", psc_noop_cmd, PSC_SMTPD_CMD_FLAG_NONE,
     "AUTH", psc_noop_cmd, PSC_SMTPD_CMD_FLAG_NONE,
@@ -688,9 +697,6 @@ static void psc_smtpd_read_event(int event, char *context)
      * was called. Also, yielding the pseudo thread will improve fairness for
      * other pseudo threads.
      */
-#define PSC_SMTPD_BUFFER_EMPTY(state) \
-       (!PSC_SMTPD_HAVE_PUSH_BACK(state) \
-       && vstream_peek(state->smtp_client_stream) <= 0)
 
     /*
      * Note: on entry into this function the VSTREAM buffer is still empty,
@@ -983,6 +989,14 @@ static void psc_smtpd_read_event(int event, char *context)
            return;
        }
 
+       /*
+        * We're suspended, waiting for some external event to happen.
+        * Hopefully, someone will call us back to process the remainder of
+        * the pending input, otherwise we could hang.
+        */
+       if (cmdp->flags & PSC_SMTPD_CMD_FLAG_SUSPEND)
+           return;
+
        /*
         * Reset the command read timeout before reading the next command.
         */
index f72ddaec24203a0926e3302177e60f672a0012ae..4455fbf20fd29ba6e853b4312d12f4ad3cc731b8 100644 (file)
@@ -1309,6 +1309,7 @@ mask_addr.o: msg.h
 mask_addr.o: sys_defs.h
 match_list.o: argv.h
 match_list.o: dict.h
+match_list.o: htable.h
 match_list.o: match_list.c
 match_list.o: match_list.h
 match_list.o: match_ops.h
@@ -1323,6 +1324,8 @@ match_list.o: vstring_vstream.h
 match_ops.o: argv.h
 match_ops.o: cidr_match.h
 match_ops.o: dict.h
+match_ops.o: htable.h
+match_ops.o: match_list.h
 match_ops.o: match_ops.c
 match_ops.o: match_ops.h
 match_ops.o: msg.h
index 5c0a9c8e35e076f483fe41432523760304f35d78..61230092486c5e1830788b7f697269038f6bb2fa 100644 (file)
@@ -118,6 +118,8 @@ int     unix_pass_trigger(const char *service, const char *buf, ssize_t len, int
      */
     if (pipe(pair) < 0)
        msg_fatal("%s: pipe: %m", myname);
+    close_on_exec(pair[0], CLOSE_ON_EXEC);
+    close_on_exec(pair[1], CLOSE_ON_EXEC);
     if (unix_send_fd(fd, pair[0]) < 0)
        msg_fatal("%s: send file descriptor: %m", myname);