2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-22 18:07:41 +00:00

postfix-2.8-20101130

This commit is contained in:
Wietse Venema 2010-11-30 00:00:00 -05:00 committed by Viktor Dukhovni
parent 6ff328f8fb
commit a2244a0dd0
32 changed files with 483 additions and 854 deletions

View File

@ -16176,3 +16176,21 @@ Apologies for any names omitted.
Cleanup: don't log "blocked using example.com=127.0.0.1", Cleanup: don't log "blocked using example.com=127.0.0.1",
just log the domain name. File: smtpd/smtpd_check.c. just log the domain name. File: smtpd/smtpd_check.c.
20101129
Cleanup: postscreen_client_connection_count_limit (default:
$smtpd_client_connection_count_limit) to limit the number
of connections from the same IP address to the postscreen(8)
daemon. Files: postscreen/postscreen.c, postscreen/postscreen.h,
postscreen/postscreen_state.c.
20101130
Cleanup: all postscreen(8) logging now reports the client
as [address]:port. This requires an update of tools that
process postscreen logging. Files: postscreen/*.c,
proto/POSTSCREEN_README.html.
Cleanup: polishing recent documentation and code. Files:
postscreen/postscreen_dnsbl.c, util/ip_match.c.

View File

@ -93,9 +93,10 @@ PPeerrmmaanneenntt wwhhiitteelliisstt tteesstt
The postscreen_whitelist_networks parameter (default: $mynetworks) specifies a The postscreen_whitelist_networks parameter (default: $mynetworks) specifies a
permanent whitelist for SMTP client IP addresses. When the SMTP client address permanent whitelist for SMTP client IP addresses. When the SMTP client address
matches the permanent whitelist, this is logged as: matches the permanent whitelist, postscreen(8) logs this with the client
address and port number as:
WWHHIITTEELLIISSTTEEDD address WWHHIITTEELLIISSTTEEDD [address]:port
The action is not configurable: immediately hand off the connection to a The action is not configurable: immediately hand off the connection to a
Postfix SMTP server process. Postfix SMTP server process.
@ -105,9 +106,9 @@ PPeerrmmaanneenntt bbllaacckklliisstt tteesstt
The postscreen_blacklist_networks parameter (default: empty) specifies a The postscreen_blacklist_networks parameter (default: empty) specifies a
permanent blacklist for SMTP client IP addresses. The address syntax is as with permanent blacklist for SMTP client IP addresses. The address syntax is as with
mynetworks. When the SMTP client address matches the permanent blacklist, mynetworks. When the SMTP client address matches the permanent blacklist,
postscreen(8) logs this as: postscreen(8) logs this with the client address and port number as:
BBLLAACCKKLLIISSTTEEDD address BBLLAACCKKLLIISSTTEEDD [address]:port
The postscreen_blacklist_action parameter specifies the action that is taken The postscreen_blacklist_action parameter specifies the action that is taken
next. See "When tests fail before the 220 SMTP server greeting" below. next. See "When tests fail before the 220 SMTP server greeting" below.
@ -121,9 +122,9 @@ whitelist. The temporary whitelist is not used for SMTP client addresses that
appear on the permanent blacklist or whitelist. appear on the permanent blacklist or whitelist.
When the SMTP client address appears on the temporary whitelist, postscreen(8) When the SMTP client address appears on the temporary whitelist, postscreen(8)
logs this as: logs this with the client address and port number as:
PPAASSSS OOLLDD address PPAASSSS OOLLDD [address]:port
The action is not configurable: immediately hand off the connection to a The action is not configurable: immediately hand off the connection to a
Postfix SMTP server process. The client is excluded from further tests until Postfix SMTP server process. The client is excluded from further tests until
@ -174,12 +175,12 @@ postscreen_whitelist_networks feature or else specify an empty teaser banner:
When an SMTP client sends a command before the postscreen_greet_wait time has When an SMTP client sends a command before the postscreen_greet_wait time has
elapsed, postscreen(8) logs this as: elapsed, postscreen(8) logs this as:
PPRREEGGRREEEETT count aafftteerr time ffrroomm address text... PPRREEGGRREEEETT count aafftteerr time ffrroomm [address]:port text...
Translation: the client at address sent count bytes before its turn to speak. Translation: the client at [address]:port sent count bytes before its turn to
This happened time seconds after the postscreen_greet_wait timer was started. speak. This happened time seconds after the postscreen_greet_wait timer was
The text is what the client sent (truncated to 100 bytes, and with non- started. The text is what the client sent (truncated to 100 bytes, and with
printable characters replaced with "?"). non-printable characters replaced with "?").
The postscreen_greet_action parameter specifies the action that is taken next. The postscreen_greet_action parameter specifies the action that is taken next.
See "When tests fail before the 220 SMTP server greeting" below. See "When tests fail before the 220 SMTP server greeting" below.
@ -199,9 +200,10 @@ When the postscreen_greet_wait time has elapsed, and the combined DNSBL score
is equal to or greater than the postscreen_dnsbl_threshold parameter value, is equal to or greater than the postscreen_dnsbl_threshold parameter value,
postscreen(8) logs this as: postscreen(8) logs this as:
DDNNSSBBLL rraannkk count ffoorr address DDNNSSBBLL rraannkk count ffoorr [address]:port
Translation: the SMTP client at address has a combined DNSBL score of count. Translation: the SMTP client at [address]:port has a combined DNSBL score of
count.
The postscreen_dnsbl_action parameter specifies the action that is taken when The postscreen_dnsbl_action parameter specifies the action that is taken when
the combined DNSBL score is equal to or greater than the threshold. See "When the combined DNSBL score is equal to or greater than the threshold. See "When
@ -278,11 +280,11 @@ in SMTP engine anyway. This is to make postscreen(8) logging more informative.
When a client sends multiple commands, postscreen(8) logs this as: When a client sends multiple commands, postscreen(8) logs this as:
CCOOMMMMAANNDD PPIIPPEELLIINNIINNGG aafftteerr time ffrroomm address CCOOMMMMAANNDD PPIIPPEELLIINNIINNGG aafftteerr time ffrroomm [address]:port
Translation: the SMTP client at address sent multiple SMTP commands, instead of Translation: the SMTP client at [address]:port sent multiple SMTP commands,
sending one command and then waiting for the server to reply. This happened instead of sending one command and then waiting for the server to reply. This
time seconds after the "220 " server greeting was sent. happened time seconds after the "220 " server greeting was sent.
The postscreen_pipelining_action parameter specifies the action that is taken The postscreen_pipelining_action parameter specifies the action that is taken
next. See "When tests fail after the 220 SMTP server greeting" below. next. See "When tests fail after the 220 SMTP server greeting" below.
@ -306,9 +308,9 @@ in SMTP engine anyway. This is to make postscreen(8) logging more informative.
When a client sends non-SMTP commands, postscreen(8) logs this as: When a client sends non-SMTP commands, postscreen(8) logs this as:
NNOONN--SSMMTTPP CCOOMMMMAANNDD ffrroomm address command NNOONN--SSMMTTPP CCOOMMMMAANNDD ffrroomm [address]:port command
Translation: the SMTP client at address sent a command that matches the Translation: the SMTP client at [address]:port sent a command that matches the
postscreen_forbidden_commands parameter, or that has the syntax of a message postscreen_forbidden_commands parameter, or that has the syntax of a message
header label. header label.
@ -330,10 +332,10 @@ in SMTP engine anyway. This is to make postscreen(8) logging more informative.
When a client sends bare newline characters, postscreen(8) logs this as: When a client sends bare newline characters, postscreen(8) logs this as:
BBAARREE NNEEWWLLIINNEE ffrroomm address BBAARREE NNEEWWLLIINNEE ffrroomm [address]:port
Translation: the SMTP client at address sent a bare newline character, that is Translation: the SMTP client at [address]:port sent a bare newline character,
newline not preceded by carriage return. that is newline not preceded by carriage return.
The postscreen_bare_newline_action parameter specifies the action that is taken The postscreen_bare_newline_action parameter specifies the action that is taken
next. See "When tests fail after the 220 SMTP server greeting" below. next. See "When tests fail after the 220 SMTP server greeting" below.
@ -364,44 +366,54 @@ OOtthheerr eerrrroorrss
When an SMTP client hangs up unexpectedly during any tests, postscreen(8) logs When an SMTP client hangs up unexpectedly during any tests, postscreen(8) logs
this as: this as:
HHAANNGGUUPP aafftteerr time ffrroomm address iinn test name HHAANNGGUUPP aafftteerr time ffrroomm [address]:port iinn test name
Translation: the SMTP client at address disconnected unexpectedly, time seconds Translation: the SMTP client at [address]:port disconnected unexpectedly, time
after the start of the test named test name. seconds after the start of the test named test name.
The following errors are reported by the built-in SMTP engine. This engine The following errors are reported by the built-in SMTP engine. This engine
never accepts mail, therefore it has per-session limits on the number of never accepts mail, therefore it has per-session limits on the number of
commands and on the session length. commands and on the session length.
CCOOMMMMAANNDD TTIIMMEE LLIIMMIITT ffrroomm address CCOOMMMMAANNDD TTIIMMEE LLIIMMIITT ffrroomm [address]:port
Translation: the SMTP client at address reached the per-command time limit as Translation: the SMTP client at [address]:port reached the per-command time
specified with the postscreen_command_time_limit parameter. The session is limit as specified with the postscreen_command_time_limit parameter. The
terminated immediately.
CCOOMMMMAANNDD CCOOUUNNTT LLIIMMIITT ffrroomm address
Translation: the SMTP client at address reached the per-session command count
limit as specified with the postscreen_command_count_limit parameter. The
session is terminated immediately. session is terminated immediately.
CCOOMMMMAANNDD LLEENNGGTTHH LLIIMMIITT ffrroomm address CCOOMMMMAANNDD CCOOUUNNTT LLIIMMIITT ffrroomm [address]:port
Translation: the SMTP client at address reached the per-command length limit, Translation: the SMTP client at [address]:port reached the per-session command
as specified with the line_length_limit parameter. The session is terminated count limit as specified with the postscreen_command_count_limit parameter. The
immediately. session is terminated immediately.
CCOOMMMMAANNDD LLEENNGGTTHH LLIIMMIITT ffrroomm [address]:port
Translation: the SMTP client at [address]:port reached the per-command length
limit, as specified with the line_length_limit parameter. The session is
terminated immediately.
When an SMTP client makes too many connections at the same time, or when all
postscreen(8) ports are busy, postscreen(8) rejects the connection with a 421
status code and logs:
NNOOQQUUEEUUEE:: rreejjeecctt:: CCOONNNNEECCTT ffrroomm [address]:port:: ttoooo mmaannyy ccoonnnneeccttiioonnss
NNOOQQUUEEUUEE:: rreejjeecctt:: CCOONNNNEECCTT ffrroomm [address]:port:: aallll sseerrvveerr ppoorrttss bbuussyy
The postscreen_client_connection_count_limit and postscreen_pre_queue_limit
parameters control these limits.
WWhheenn aallll tteessttss ssuucccceeeedd WWhheenn aallll tteessttss ssuucccceeeedd
When a new SMTP client passes all tests (i.e. it is not whitelisted via some When a new SMTP client passes all tests (i.e. it is not whitelisted via some
mechanism), postscreen(8) logs this as: mechanism), postscreen(8) logs this as:
PPAASSSS NNEEWW address PPAASSSS NNEEWW [address]:port
Where address is the client IP address. Then, postscreen(8) creates a temporary Where [address]:port are the client IP address and port. Then, postscreen(8)
whitelist entry that excludes the client IP address from further tests until creates a temporary whitelist entry that excludes the client IP address from
the temporary whitelist entry expires, as controlled with the postscreen_*_ttl further tests until the temporary whitelist entry expires, as controlled with
parameters. the postscreen_*_ttl parameters.
When no "deep protocol tests" are configured, postscreen(8) hands off the When no "deep protocol tests" are configured, postscreen(8) hands off the
"live" connection to a Postfix SMTP server process. The client can then "live" connection to a Postfix SMTP server process. The client can then

View File

@ -33,6 +33,14 @@ This is supported only when the default value is stress-dependent
postscreen parameters always evaluate as if the stress value is postscreen parameters always evaluate as if the stress value is
equal to the empty string. equal to the empty string.
Incompatibility with snapshot 20101130
======================================
The postscreen(8) daemon now logs the client as [address]:port.
The port helps to distinguish between simultaneous sessions from
the same address, and the [] allow the same tool to be used with
old and new format logfiles, without producing errors for IPv6.
Major changes with snapshot 20101126 Major changes with snapshot 20101126
==================================== ====================================

View File

@ -4,13 +4,8 @@ Wish list:
anvil rate limit for sasl_username. anvil rate limit for sasl_username.
postscreen per-client connection count limit.
smtpd xclient option for sasl_username. smtpd xclient option for sasl_username.
Documentation: add a note that smtpd_helo_required=yes is
needed to really enforce HELO restrictions.
Use different ipc_timeout settings for email message Use different ipc_timeout settings for email message
transactions (smtpd, pickup)->cleanup and for quick query/reply transactions (smtpd, pickup)->cleanup and for quick query/reply
transactions such as address rewriting/resolution. transactions such as address rewriting/resolution.

View File

@ -131,11 +131,11 @@ handling of known clients. </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>) <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 specifies a permanent whitelist for SMTP client IP addresses. When
the SMTP client address matches the permanent whitelist, this is the SMTP client address matches the permanent whitelist, <a href="postscreen.8.html">postscreen(8)</a>
logged as: </p> logs this with the client address and port number as: </p>
<pre> <pre>
<b>WHITELISTED</b> <i>address</i> <b>WHITELISTED</b> <i>[address]:port</i>
</pre> </pre>
<p> The action is not configurable: immediately hand off the <p> The action is not configurable: immediately hand off the
@ -146,10 +146,11 @@ connection to a Postfix SMTP server process. </p>
<p> The <a href="postconf.5.html#postscreen_blacklist_networks">postscreen_blacklist_networks</a> parameter (default: empty) <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 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 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 as: </p> matches the permanent blacklist, <a href="postscreen.8.html">postscreen(8)</a> logs this with the
client address and port number as: </p>
<pre> <pre>
<b>BLACKLISTED</b> <i>address</i> <b>BLACKLISTED</b> <i>[address]:port</i>
</pre> </pre>
<p> The <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> parameter specifies the action <p> The <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> parameter specifies the action
@ -166,10 +167,11 @@ temporary whitelist is not used for SMTP client addresses
that appear on the <i>permanent</i> blacklist or whitelist. </p> that appear on the <i>permanent</i> blacklist or whitelist. </p>
<p> When the SMTP client address appears on the temporary <p> When the SMTP client address appears on the temporary
whitelist, <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p> whitelist, <a href="postscreen.8.html">postscreen(8)</a> logs this with the client address and port
number as: </p>
<pre> <pre>
<b>PASS OLD</b> <i>address</i> <b>PASS OLD</b> <i>[address]:port</i>
</pre> </pre>
<p> The action is not configurable: immediately hand off the <p> The action is not configurable: immediately hand off the
@ -238,10 +240,10 @@ an empty teaser banner: </p>
</p> </p>
<pre> <pre>
<b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>address text...</i> <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>[address]:port text...</i>
</pre> </pre>
<p> Translation: the client at <i>address</i> sent <i>count</i> <p> Translation: the client at <i>[address]:port</i> sent <i>count</i>
bytes before its turn to speak. This happened <i>time</i> seconds bytes before its turn to speak. This happened <i>time</i> seconds
after the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> timer was started. The <i>text</i> after the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> timer was started. The <i>text</i>
is what the client sent (truncated to 100 bytes, and with non-printable is what the client sent (truncated to 100 bytes, and with non-printable
@ -271,10 +273,10 @@ DNSBL score is equal to or greater than the <a href="postconf.5.html#postscreen_
parameter value, <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p> parameter value, <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>
<pre> <pre>
<b>DNSBL rank</b> <i>count</i> <b>for</b> <i>address</i> <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> has a combined <p> Translation: the SMTP client at <i>[address]:port</i> has a combined
DNSBL score of <i>count</i>. </p> DNSBL score of <i>count</i>. </p>
<p> The <a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a> parameter specifies the action that <p> The <a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a> parameter specifies the action that
@ -380,10 +382,10 @@ logging more informative. </p>
as: </p> as: </p>
<pre> <pre>
<b>COMMAND PIPELINING after</b> <i>time</i> <b>from</b> <i>address</i> <b>COMMAND PIPELINING after</b> <i>time</i> <b>from</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> sent multiple <p> Translation: the SMTP client at <i>[address]:port</i> sent multiple
SMTP commands, instead of sending one command and then waiting for SMTP commands, instead of sending one command and then waiting for
the server to reply. This happened <i>time</i> seconds after the the server to reply. This happened <i>time</i> seconds after the
"220 " server greeting was sent. </p> "220 " server greeting was sent. </p>
@ -416,10 +418,10 @@ logging more informative. </p>
as: </p> as: </p>
<pre> <pre>
<b>NON-SMTP COMMAND from</b> <i>address command</i> <b>NON-SMTP COMMAND from</b> <i>[address]:port command</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> sent a <p> Translation: the SMTP client at <i>[address]:port</i> sent a
<i>command</i> that matches the <a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a> <i>command</i> that matches the <a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a>
parameter, or that has the syntax of a message header label. </p> parameter, or that has the syntax of a message header label. </p>
@ -448,10 +450,10 @@ this as:
</p> </p>
<pre> <pre>
<b>BARE NEWLINE from</b> <i>address</i> <b>BARE NEWLINE from</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> sent a bare <p> Translation: the SMTP client at <i>[address]:port</i> sent a bare
newline character, that is newline not preceded by carriage newline character, that is newline not preceded by carriage
return. </p> return. </p>
@ -499,10 +501,10 @@ feature. </dd>
<a href="postscreen.8.html">postscreen(8)</a> logs this as: </p> <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>
<pre> <pre>
<b>HANGUP after</b> <i>time</i> <b>from</b> <i>address</i> <b>in</b> <i>test name</i> <b>HANGUP after</b> <i>time</i> <b>from</b> <i>[address]:port</i> <b>in</b> <i>test name</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> disconnected <p> Translation: the SMTP client at <i>[address]:port</i> disconnected
unexpectedly, <i>time</i> seconds after the start of the unexpectedly, <i>time</i> seconds after the start of the
test named <i>test name</i>. </p> test named <i>test name</i>. </p>
@ -513,7 +515,7 @@ allowed to pass any tests, and <a href="postscreen.8.html">postscreen(8)</a> lo
with the remaining amount of penalty time as: </p> with the remaining amount of penalty time as: </p>
<pre> <pre>
<b>PENALTY</b> <i>time</i> <b>for</b> <i>address</i> <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i>
</pre> </pre>
<p> During this time, all attempts by the client to deliver mail <p> During this time, all attempts by the client to deliver mail
@ -526,40 +528,53 @@ This engine never accepts mail, therefore it has per-session limits
on the number of commands and on the session length. </p> on the number of commands and on the session length. </p>
<pre> <pre>
<b>COMMAND TIME LIMIT</b> <b>from</b> <i>address</i> <b>COMMAND TIME LIMIT</b> <b>from</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> reached the <p> Translation: the SMTP client at <i>[address]:port</i> reached the
per-command time limit as specified with the <a href="postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit</a> per-command time limit as specified with the <a href="postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit</a>
parameter. The session is terminated immediately. </p> parameter. The session is terminated immediately. </p>
<pre> <pre>
<b>COMMAND COUNT LIMIT from</b> <i>address</i> <b>COMMAND COUNT LIMIT from</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> reached the <p> Translation: the SMTP client at <i>[address]:port</i> reached the
per-session command count limit as specified with the per-session command count limit as specified with the
<a href="postconf.5.html#postscreen_command_count_limit">postscreen_command_count_limit</a> parameter. The session is terminated <a href="postconf.5.html#postscreen_command_count_limit">postscreen_command_count_limit</a> parameter. The session is terminated
immediately. </p> immediately. </p>
<pre> <pre>
<b>COMMAND LENGTH LIMIT from</b> <i>address</i> <b>COMMAND LENGTH LIMIT from</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> reached the <p> Translation: the SMTP client at <i>[address]:port</i> reached the
per-command length limit, as specified with the <a href="postconf.5.html#line_length_limit">line_length_limit</a> per-command length limit, as specified with the <a href="postconf.5.html#line_length_limit">line_length_limit</a>
parameter. The session is terminated immediately. </p> parameter. The session is terminated immediately. </p>
<p> When an SMTP client makes too many connections at the same time,
or when all <a href="postscreen.8.html">postscreen(8)</a> ports are busy, <a href="postscreen.8.html">postscreen(8)</a> rejects the
connection with a 421 status code and logs: </p>
<pre>
<b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: too many connections</b>
<b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all server ports busy</b>
</pre>
<p> The <a href="postconf.5.html#postscreen_client_connection_count_limit">postscreen_client_connection_count_limit</a> and
<a href="postconf.5.html#postscreen_pre_queue_limit">postscreen_pre_queue_limit</a> parameters control these limits. </p>
<h2> <a name="victory">When all tests succeed</a> </h2> <h2> <a name="victory">When all tests succeed</a> </h2>
<p> When a new SMTP client passes all tests (i.e. it is not whitelisted <p> When a new SMTP client passes all tests (i.e. it is not whitelisted
via some mechanism), <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p> via some mechanism), <a href="postscreen.8.html">postscreen(8)</a> logs this as: </p>
<pre> <pre>
<b>PASS NEW</b> <i>address</i> <b>PASS NEW</b> <i>[address]:port</i>
</pre> </pre>
<p> Where <i>address</i> is the client IP address. Then, <a href="postscreen.8.html">postscreen(8)</a> <p> Where <i>[address]:port</i> are the client IP address and port.
Then, <a href="postscreen.8.html">postscreen(8)</a>
creates a temporary whitelist entry that excludes the client IP creates a temporary whitelist entry that excludes the client IP
address from further tests until the temporary whitelist entry address from further tests until the temporary whitelist entry
expires, as controlled with the postscreen_*_ttl parameters. </p> expires, as controlled with the postscreen_*_ttl parameters. </p>

View File

@ -6782,6 +6782,21 @@ that passed some deep protocol test once and never came back. </p>
<p> This feature is available in Postfix 2.8. </p> <p> This feature is available in Postfix 2.8. </p>
</DD>
<DT><b><a name="postscreen_client_connection_count_limit">postscreen_client_connection_count_limit</a>
(default: $<a href="postconf.5.html#smtpd_client_connection_count_limit">smtpd_client_connection_count_limit</a>)</b></DT><DD>
<p> How many simultaneous connections any client is allowed to have
with the <a href="postscreen.8.html">postscreen(8)</a> daemon. By default, this limit is the same
as with the Postfix SMTP server. Note that the triage process can
take several seconds, with the time spent in <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a>
delay, and with the time spent talking to the <a href="postscreen.8.html">postscreen(8)</a> built-in
dummy SMTP protocol engine. </p>
<p> This feature is available in Postfix 2.8. </p>
</DD> </DD>
<DT><b><a name="postscreen_command_count_limit">postscreen_command_count_limit</a> <DT><b><a name="postscreen_command_count_limit">postscreen_command_count_limit</a>
@ -11680,8 +11695,8 @@ Postfix version 2.5). This feature is available with Postfix version
<dd>Reject the request when the reversed client network address is <dd>Reject the request when the reversed client network address is
listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
(Postfix version 2.1 and later only). Each "<i>d</i>" can be a (Postfix version 2.1 and later only). Each "<i>d</i>" is a number,
pattern inside "[]" that contains one or more comma-separated decimal or a pattern inside "[]" that contains one or more comma-separated
numbers or number..number ranges (Postfix version 2.8 and later). numbers or number..number ranges (Postfix version 2.8 and later).
If no "<i>=d.d.d.d</i>" is specified, reject the request when the If no "<i>=d.d.d.d</i>" is specified, reject the request when the
reversed client network address is listed with any A record under reversed client network address is listed with any A record under
@ -11696,8 +11711,8 @@ This feature is available in Postfix 2.0 and later. </dd>
<dd>Accept the request when the reversed client network address is <dd>Accept the request when the reversed client network address is
listed with the A record "<i>d.d.d.d</i>" under <i>dnswl_domain</i>. listed with the A record "<i>d.d.d.d</i>" under <i>dnswl_domain</i>.
Each "<i>d</i>" can be a pattern inside "[]" that contains one or Each "<i>d</i>" is a number, or a pattern inside "[]" that contains
more comma-separated decimal numbers or number..number ranges. one or more comma-separated numbers or number..number ranges.
If no "<i>=d.d.d.d</i>" is specified, accept the request when the If no "<i>=d.d.d.d</i>" is specified, accept the request when the
reversed client network address is listed with any A record under reversed client network address is listed with any A record under
<i>dnswl_domain</i>. <br> For safety, <a href="postconf.5.html#permit_dnswl_client">permit_dnswl_client</a> is silently <i>dnswl_domain</i>. <br> For safety, <a href="postconf.5.html#permit_dnswl_client">permit_dnswl_client</a> is silently
@ -11709,8 +11724,8 @@ is available in Postfix 2.8 and later. </dd>
<dd>Reject the request when the client hostname is listed with the <dd>Reject the request when the client hostname is listed with the
A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version
2.1 and later only). Each "<i>d</i>" can be a pattern inside "[]" 2.1 and later only). Each "<i>d</i>" is a number, or a pattern
that contains one or more comma-separated decimal numbers or inside "[]" that contains one or more comma-separated numbers or
number..number ranges (Postfix version 2.8 and later). If no number..number ranges (Postfix version 2.8 and later). If no
"<i>=d.d.d.d</i>" is specified, reject the request when the client "<i>=d.d.d.d</i>" is specified, reject the request when the client
hostname is listed with hostname is listed with
@ -11724,8 +11739,8 @@ produce better results. </dd>
<dd>Accept the request when the client hostname is listed with the <dd>Accept the request when the client hostname is listed with the
A record "<i>d.d.d.d</i>" under <i>rhswl_domain</i>. Each "<i>d</i>" A record "<i>d.d.d.d</i>" under <i>rhswl_domain</i>. Each "<i>d</i>"
can be a pattern inside "[]" that contains one or more comma-separated is a number, or a pattern inside "[]" that contains one or more
decimal numbers or number..number ranges. If no comma-separated numbers or number..number ranges. If no
"<i>=d.d.d.d</i>" is specified, accept the request when the client "<i>=d.d.d.d</i>" is specified, accept the request when the client
hostname is listed with any A record under <i>rhswl_domain</i>. hostname is listed with any A record under <i>rhswl_domain</i>.
<br> Caution: client name whitelisting is fragile, since the client <br> Caution: client name whitelisting is fragile, since the client
@ -11741,8 +11756,8 @@ when whitelist lookup fails. This feature is available in Postfix
<dd>Reject the request when the unverified reverse client hostname <dd>Reject the request when the unverified reverse client hostname
is listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>. is listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>.
Each "<i>d</i>" can be a pattern inside "[]" that contains one or Each "<i>d</i>" is a number, or a pattern inside "[]" that contains
more comma-separated decimal numbers or number..number ranges. one or more comma-separated numbers or number..number ranges.
If no "<i>=d.d.d.d</i>" is specified, reject the request when the If no "<i>=d.d.d.d</i>" is specified, reject the request when the
unverified reverse client hostname is listed with any A record under unverified reverse client hostname is listed with any A record under
<i>rbl_domain</i>. See the <a href="postconf.5.html#reject_rbl_client">reject_rbl_client</a> description above for <i>rbl_domain</i>. See the <a href="postconf.5.html#reject_rbl_client">reject_rbl_client</a> description above for
@ -12346,50 +12361,58 @@ received with the HELO or EHLO command.
<dd>Search the specified <a href="access.5.html">access(5)</a> database for the HELO or EHLO <dd>Search the specified <a href="access.5.html">access(5)</a> database for the HELO or EHLO
hostname or parent domains, and execute the corresponding action. hostname or parent domains, and execute the corresponding action.
</dd> Note: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully enforce this
restriction. </dd>
<dt><b><a name="check_helo_mx_access">check_helo_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> <dt><b><a name="check_helo_mx_access">check_helo_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
<dd>Search the specified <a href="access.5.html">access(5)</a> database for the MX hosts for <dd>Search the specified <a href="access.5.html">access(5)</a> database for the MX hosts for
the HELO or EHLO hostname, and execute the corresponding action. the HELO or EHLO hostname, and execute the corresponding action.
Note: a result of "OK" is not allowed for safety reasons. Instead, Note 1: a result of "OK" is not allowed for safety reasons. Instead,
use DUNNO in order to exclude specific hosts from blacklists. This use DUNNO in order to exclude specific hosts from blacklists. Note
feature is available in Postfix 2.1 and later. </dd> 2: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully enforce this
restriction. This feature is available in Postfix 2.1 and later.
</dd>
<dt><b><a name="check_helo_ns_access">check_helo_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> <dt><b><a name="check_helo_ns_access">check_helo_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
<dd>Search the specified <a href="access.5.html">access(5)</a> database for the DNS servers <dd>Search the specified <a href="access.5.html">access(5)</a> database for the DNS servers
for the HELO or EHLO hostname, and execute the corresponding action. for the HELO or EHLO hostname, and execute the corresponding action.
Note: a result of "OK" is not allowed for safety reasons. Instead, Note 1: a result of "OK" is not allowed for safety reasons. Instead,
use DUNNO in order to exclude specific hosts from blacklists. This use DUNNO in order to exclude specific hosts from blacklists. Note
feature is available in Postfix 2.1 and later. </dd> 2: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully enforce this
restriction. This feature is available in Postfix 2.1 and later.
</dd>
<dt><b><a name="reject_invalid_helo_hostname">reject_invalid_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_invalid_hostname)</dt> <dt><b><a name="reject_invalid_helo_hostname">reject_invalid_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_invalid_hostname)</dt>
<dd>Reject the request when the HELO or EHLO hostname syntax is <dd>Reject the request when the HELO or EHLO hostname syntax is
invalid. <br> The <a href="postconf.5.html#invalid_hostname_reject_code">invalid_hostname_reject_code</a> specifies the response invalid. Note: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully enforce
code for rejected requests (default: 501).</dd> this restriction. <br> The <a href="postconf.5.html#invalid_hostname_reject_code">invalid_hostname_reject_code</a> specifies
the response code for rejected requests (default: 501).</dd>
<dt><b><a name="reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_non_fqdn_hostname)</dt> <dt><b><a name="reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_non_fqdn_hostname)</dt>
<dd>Reject the request when the HELO or EHLO hostname is not in <dd>Reject the request when the HELO or EHLO hostname is not in
fully-qualified domain form, as required by the RFC. <br> The fully-qualified domain form, as required by the RFC. Note: specify
<a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> parameter specifies the response code for "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully enforce this restriction. <br>
The <a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> parameter specifies the response code for
rejected requests (default: 504).</dd> rejected requests (default: 504).</dd>
<dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt> <dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt>
<dd>Reject the request when the HELO or EHLO hostname hostname is <dd>Reject the request when the HELO or EHLO hostname hostname is
listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
(Postfix version 2.1 and later only). Each "<i>d</i>" can be a (Postfix version 2.1 and later only). Each "<i>d</i>" is a number,
pattern inside "[]" that contains one or more comma-separated decimal or a pattern inside "[]" that contains one or more comma-separated
numbers or number..number ranges (Postfix version 2.8 and later). numbers or number..number ranges (Postfix version 2.8 and later).
If no "<i>=d.d.d.d</i>" is If no "<i>=d.d.d.d</i>" is
specified, reject the request when the HELO or EHLO hostname is specified, reject the request when the HELO or EHLO hostname is
listed with any A record under <i>rbl_domain</i>. See the listed with any A record under <i>rbl_domain</i>. See the
<a href="postconf.5.html#reject_rbl_client">reject_rbl_client</a> description for additional RBL related configuration <a href="postconf.5.html#reject_rbl_client">reject_rbl_client</a> description for additional RBL related configuration
parameters. This feature is available in Postfix 2.0 and later. parameters. Note: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully
</dd> enforce this restriction. This feature is available in Postfix 2.0
and later. </dd>
<dt><b><a name="reject_unknown_helo_hostname">reject_unknown_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_unknown_hostname)</dt> <dt><b><a name="reject_unknown_helo_hostname">reject_unknown_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_unknown_hostname)</dt>
@ -12398,7 +12421,8 @@ or MX record. <br> The <a href="postconf.5.html#unknown_hostname_reject_code">un
specifies the numerical response code for rejected requests (default: specifies the numerical response code for rejected requests (default:
450). <br> The <a href="postconf.5.html#unknown_helo_hostname_tempfail_action">unknown_helo_hostname_tempfail_action</a> parameter 450). <br> The <a href="postconf.5.html#unknown_helo_hostname_tempfail_action">unknown_helo_hostname_tempfail_action</a> parameter
specifies the action after a temporary DNS error (default: specifies the action after a temporary DNS error (default:
<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). </dd> <a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). Note: specify "<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> = yes" to fully
enforce this restriction. </dd>
</dl> </dl>
@ -12800,8 +12824,8 @@ rejected requests (default: 504). </dd>
<dd>Reject the request when the RCPT TO domain is listed with the <dd>Reject the request when the RCPT TO domain is listed with the
A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version
2.1 and later only). Each "<i>d</i>" can be a pattern inside "[]" 2.1 and later only). Each "<i>d</i>" is a number, or a pattern
that contains one or more comma-separated decimal numbers or inside "[]" that contains one or more comma-separated numbers or
number..number ranges (Postfix version 2.8 and later). If no number..number ranges (Postfix version 2.8 and later). If no
"<i>=d.d.d.d</i>" is specified, reject "<i>=d.d.d.d</i>" is specified, reject
the request when the RCPT TO domain is listed with the request when the RCPT TO domain is listed with
@ -13347,8 +13371,8 @@ rejected requests (default: 504). </dd>
<dd>Reject the request when the MAIL FROM domain is listed with <dd>Reject the request when the MAIL FROM domain is listed with
the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix
version 2.1 and later only). Each "<i>d</i>" can be a pattern version 2.1 and later only). Each "<i>d</i>" is a number, or a
inside "[]" that contains one or more comma-separated decimal numbers pattern inside "[]" that contains one or more comma-separated numbers
or number..number ranges (Postfix version 2.8 and later). If no or number..number ranges (Postfix version 2.8 and later). If no
"<i>=d.d.d.d</i>" is specified, "<i>=d.d.d.d</i>" is specified,
reject the request when the MAIL FROM domain is reject the request when the MAIL FROM domain is

View File

@ -233,6 +233,11 @@ POSTSCREEN(8) POSTSCREEN(8)
of at most this length; upon delivery, long lines of at most this length; upon delivery, long lines
are reconstructed. are reconstructed.
<b><a href="postconf.5.html#postscreen_client_connection_count_limit">postscreen_client_connection_count_limit</a></b>
<b>($<a href="postconf.5.html#smtpd_client_connection_count_limit">smtpd_client_connection_count_limit</a>)</b>
How many simultaneous connections any client is
allowed to have with the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> daemon.
<b><a href="postconf.5.html#postscreen_command_count_limit">postscreen_command_count_limit</a> (20)</b> <b><a href="postconf.5.html#postscreen_command_count_limit">postscreen_command_count_limit</a> (20)</b>
The limit on the total number of commands per SMTP The limit on the total number of commands per SMTP
session for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol session for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s built-in SMTP protocol

View File

@ -3818,6 +3818,15 @@ Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks). (weeks).
.PP .PP
This feature is available in Postfix 2.8. This feature is available in Postfix 2.8.
.SH postscreen_client_connection_count_limit (default: $smtpd_client_connection_count_limit)
How many simultaneous connections any client is allowed to have
with the \fBpostscreen\fR(8) daemon. By default, this limit is the same
as with the Postfix SMTP server. Note that the triage process can
take several seconds, with the time spent in postscreen_greet_wait
delay, and with the time spent talking to the \fBpostscreen\fR(8) built-in
dummy SMTP protocol engine.
.PP
This feature is available in Postfix 2.8.
.SH postscreen_command_count_limit (default: 20) .SH postscreen_command_count_limit (default: 20)
The limit on the total number of commands per SMTP session for The limit on the total number of commands per SMTP session for
\fBpostscreen\fR(8)'s built-in SMTP protocol engine. This SMTP engine \fBpostscreen\fR(8)'s built-in SMTP protocol engine. This SMTP engine
@ -7166,8 +7175,8 @@ Postfix version 2.5). This feature is available with Postfix version
.IP "\fBreject_rbl_client \fIrbl_domain=d.d.d.d\fR\fR" .IP "\fBreject_rbl_client \fIrbl_domain=d.d.d.d\fR\fR"
Reject the request when the reversed client network address is Reject the request when the reversed client network address is
listed with the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR listed with the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR
(Postfix version 2.1 and later only). Each "\fId\fR" can be a (Postfix version 2.1 and later only). Each "\fId\fR" is a number,
pattern inside "[]" that contains one or more comma-separated decimal or a pattern inside "[]" that contains one or more comma-separated
numbers or number..number ranges (Postfix version 2.8 and later). numbers or number..number ranges (Postfix version 2.8 and later).
If no "\fI=d.d.d.d\fR" is specified, reject the request when the If no "\fI=d.d.d.d\fR" is specified, reject the request when the
reversed client network address is listed with any A record under reversed client network address is listed with any A record under
@ -7181,8 +7190,8 @@ This feature is available in Postfix 2.0 and later.
.IP "\fBpermit_dnswl_client \fIdnswl_domain=d.d.d.d\fR\fR" .IP "\fBpermit_dnswl_client \fIdnswl_domain=d.d.d.d\fR\fR"
Accept the request when the reversed client network address is Accept the request when the reversed client network address is
listed with the A record "\fId.d.d.d\fR" under \fIdnswl_domain\fR. listed with the A record "\fId.d.d.d\fR" under \fIdnswl_domain\fR.
Each "\fId\fR" can be a pattern inside "[]" that contains one or Each "\fId\fR" is a number, or a pattern inside "[]" that contains
more comma-separated decimal numbers or number..number ranges. one or more comma-separated numbers or number..number ranges.
If no "\fI=d.d.d.d\fR" is specified, accept the request when the If no "\fI=d.d.d.d\fR" is specified, accept the request when the
reversed client network address is listed with any A record under reversed client network address is listed with any A record under
\fIdnswl_domain\fR. \fIdnswl_domain\fR.
@ -7194,8 +7203,8 @@ is available in Postfix 2.8 and later.
.IP "\fBreject_rhsbl_client \fIrbl_domain=d.d.d.d\fR\fR" .IP "\fBreject_rhsbl_client \fIrbl_domain=d.d.d.d\fR\fR"
Reject the request when the client hostname is listed with the Reject the request when the client hostname is listed with the
A record "\fId.d.d.d\fR" under \fIrbl_domain\fR (Postfix version A record "\fId.d.d.d\fR" under \fIrbl_domain\fR (Postfix version
2.1 and later only). Each "\fId\fR" can be a pattern inside "[]" 2.1 and later only). Each "\fId\fR" is a number, or a pattern
that contains one or more comma-separated decimal numbers or inside "[]" that contains one or more comma-separated numbers or
number..number ranges (Postfix version 2.8 and later). If no number..number ranges (Postfix version 2.8 and later). If no
"\fI=d.d.d.d\fR" is specified, reject the request when the client "\fI=d.d.d.d\fR" is specified, reject the request when the client
hostname is listed with hostname is listed with
@ -7207,8 +7216,8 @@ produce better results.
.IP "\fBpermit_rhswl_client \fIrhswl_domain=d.d.d.d\fR\fR" .IP "\fBpermit_rhswl_client \fIrhswl_domain=d.d.d.d\fR\fR"
Accept the request when the client hostname is listed with the Accept the request when the client hostname is listed with the
A record "\fId.d.d.d\fR" under \fIrhswl_domain\fR. Each "\fId\fR" A record "\fId.d.d.d\fR" under \fIrhswl_domain\fR. Each "\fId\fR"
can be a pattern inside "[]" that contains one or more comma-separated is a number, or a pattern inside "[]" that contains one or more
decimal numbers or number..number ranges. If no comma-separated numbers or number..number ranges. If no
"\fI=d.d.d.d\fR" is specified, accept the request when the client "\fI=d.d.d.d\fR" is specified, accept the request when the client
hostname is listed with any A record under \fIrhswl_domain\fR. hostname is listed with any A record under \fIrhswl_domain\fR.
.br .br
@ -7224,8 +7233,8 @@ when whitelist lookup fails. This feature is available in Postfix
.IP "\fBreject_rhsbl_reverse_client \fIrbl_domain=d.d.d.d\fR\fR" .IP "\fBreject_rhsbl_reverse_client \fIrbl_domain=d.d.d.d\fR\fR"
Reject the request when the unverified reverse client hostname Reject the request when the unverified reverse client hostname
is listed with the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR. is listed with the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR.
Each "\fId\fR" can be a pattern inside "[]" that contains one or Each "\fId\fR" is a number, or a pattern inside "[]" that contains
more comma-separated decimal numbers or number..number ranges. one or more comma-separated numbers or number..number ranges.
If no "\fI=d.d.d.d\fR" is specified, reject the request when the If no "\fI=d.d.d.d\fR" is specified, reject the request when the
unverified reverse client hostname is listed with any A record under unverified reverse client hostname is listed with any A record under
\fIrbl_domain\fR. See the reject_rbl_client description above for \fIrbl_domain\fR. See the reject_rbl_client description above for
@ -7666,42 +7675,49 @@ received with the HELO or EHLO command.
.IP "\fBcheck_helo_access \fItype:table\fR\fR" .IP "\fBcheck_helo_access \fItype:table\fR\fR"
Search the specified \fBaccess\fR(5) database for the HELO or EHLO Search the specified \fBaccess\fR(5) database for the HELO or EHLO
hostname or parent domains, and execute the corresponding action. hostname or parent domains, and execute the corresponding action.
Note: specify "smtpd_helo_required = yes" to fully enforce this
restriction.
.IP "\fBcheck_helo_mx_access \fItype:table\fR\fR" .IP "\fBcheck_helo_mx_access \fItype:table\fR\fR"
Search the specified \fBaccess\fR(5) database for the MX hosts for Search the specified \fBaccess\fR(5) database for the MX hosts for
the HELO or EHLO hostname, and execute the corresponding action. the HELO or EHLO hostname, and execute the corresponding action.
Note: a result of "OK" is not allowed for safety reasons. Instead, Note 1: a result of "OK" is not allowed for safety reasons. Instead,
use DUNNO in order to exclude specific hosts from blacklists. This use DUNNO in order to exclude specific hosts from blacklists. Note
feature is available in Postfix 2.1 and later. 2: specify "smtpd_helo_required = yes" to fully enforce this
restriction. This feature is available in Postfix 2.1 and later.
.IP "\fBcheck_helo_ns_access \fItype:table\fR\fR" .IP "\fBcheck_helo_ns_access \fItype:table\fR\fR"
Search the specified \fBaccess\fR(5) database for the DNS servers Search the specified \fBaccess\fR(5) database for the DNS servers
for the HELO or EHLO hostname, and execute the corresponding action. for the HELO or EHLO hostname, and execute the corresponding action.
Note: a result of "OK" is not allowed for safety reasons. Instead, Note 1: a result of "OK" is not allowed for safety reasons. Instead,
use DUNNO in order to exclude specific hosts from blacklists. This use DUNNO in order to exclude specific hosts from blacklists. Note
feature is available in Postfix 2.1 and later. 2: specify "smtpd_helo_required = yes" to fully enforce this
restriction. This feature is available in Postfix 2.1 and later.
.IP "\fBreject_invalid_helo_hostname\fR (with Postfix < 2.3: reject_invalid_hostname)" .IP "\fBreject_invalid_helo_hostname\fR (with Postfix < 2.3: reject_invalid_hostname)"
Reject the request when the HELO or EHLO hostname syntax is Reject the request when the HELO or EHLO hostname syntax is
invalid. invalid. Note: specify "smtpd_helo_required = yes" to fully enforce
this restriction.
.br .br
The invalid_hostname_reject_code specifies the response The invalid_hostname_reject_code specifies
code for rejected requests (default: 501). the response code for rejected requests (default: 501).
.IP "\fBreject_non_fqdn_helo_hostname\fR (with Postfix < 2.3: reject_non_fqdn_hostname)" .IP "\fBreject_non_fqdn_helo_hostname\fR (with Postfix < 2.3: reject_non_fqdn_hostname)"
Reject the request when the HELO or EHLO hostname is not in Reject the request when the HELO or EHLO hostname is not in
fully-qualified domain form, as required by the RFC. fully-qualified domain form, as required by the RFC. Note: specify
"smtpd_helo_required = yes" to fully enforce this restriction.
.br .br
The The non_fqdn_reject_code parameter specifies the response code for
non_fqdn_reject_code parameter specifies the response code for
rejected requests (default: 504). rejected requests (default: 504).
.IP "\fBreject_rhsbl_helo \fIrbl_domain=d.d.d.d\fR\fR" .IP "\fBreject_rhsbl_helo \fIrbl_domain=d.d.d.d\fR\fR"
Reject the request when the HELO or EHLO hostname hostname is Reject the request when the HELO or EHLO hostname hostname is
listed with the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR listed with the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR
(Postfix version 2.1 and later only). Each "\fId\fR" can be a (Postfix version 2.1 and later only). Each "\fId\fR" is a number,
pattern inside "[]" that contains one or more comma-separated decimal or a pattern inside "[]" that contains one or more comma-separated
numbers or number..number ranges (Postfix version 2.8 and later). numbers or number..number ranges (Postfix version 2.8 and later).
If no "\fI=d.d.d.d\fR" is If no "\fI=d.d.d.d\fR" is
specified, reject the request when the HELO or EHLO hostname is specified, reject the request when the HELO or EHLO hostname is
listed with any A record under \fIrbl_domain\fR. See the listed with any A record under \fIrbl_domain\fR. See the
reject_rbl_client description for additional RBL related configuration reject_rbl_client description for additional RBL related configuration
parameters. This feature is available in Postfix 2.0 and later. parameters. Note: specify "smtpd_helo_required = yes" to fully
enforce this restriction. This feature is available in Postfix 2.0
and later.
.IP "\fBreject_unknown_helo_hostname\fR (with Postfix < 2.3: reject_unknown_hostname)" .IP "\fBreject_unknown_helo_hostname\fR (with Postfix < 2.3: reject_unknown_hostname)"
Reject the request when the HELO or EHLO hostname has no DNS A Reject the request when the HELO or EHLO hostname has no DNS A
or MX record. or MX record.
@ -7712,7 +7728,8 @@ specifies the numerical response code for rejected requests (default:
.br .br
The unknown_helo_hostname_tempfail_action parameter The unknown_helo_hostname_tempfail_action parameter
specifies the action after a temporary DNS error (default: specifies the action after a temporary DNS error (default:
defer_if_permit). defer_if_permit). Note: specify "smtpd_helo_required = yes" to fully
enforce this restriction.
.PP .PP
Other restrictions that are valid in this context: Other restrictions that are valid in this context:
.IP \(bu .IP \(bu
@ -7939,8 +7956,8 @@ rejected requests (default: 504).
.IP "\fBreject_rhsbl_recipient \fIrbl_domain=d.d.d.d\fR\fR" .IP "\fBreject_rhsbl_recipient \fIrbl_domain=d.d.d.d\fR\fR"
Reject the request when the RCPT TO domain is listed with the Reject the request when the RCPT TO domain is listed with the
A record "\fId.d.d.d\fR" under \fIrbl_domain\fR (Postfix version A record "\fId.d.d.d\fR" under \fIrbl_domain\fR (Postfix version
2.1 and later only). Each "\fId\fR" can be a pattern inside "[]" 2.1 and later only). Each "\fId\fR" is a number, or a pattern
that contains one or more comma-separated decimal numbers or inside "[]" that contains one or more comma-separated numbers or
number..number ranges (Postfix version 2.8 and later). If no number..number ranges (Postfix version 2.8 and later). If no
"\fI=d.d.d.d\fR" is specified, reject "\fI=d.d.d.d\fR" is specified, reject
the request when the RCPT TO domain is listed with the request when the RCPT TO domain is listed with
@ -8312,8 +8329,8 @@ rejected requests (default: 504).
.IP "\fBreject_rhsbl_sender \fIrbl_domain=d.d.d.d\fR\fR" .IP "\fBreject_rhsbl_sender \fIrbl_domain=d.d.d.d\fR\fR"
Reject the request when the MAIL FROM domain is listed with Reject the request when the MAIL FROM domain is listed with
the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR (Postfix the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR (Postfix
version 2.1 and later only). Each "\fId\fR" can be a pattern version 2.1 and later only). Each "\fId\fR" is a number, or a
inside "[]" that contains one or more comma-separated decimal numbers pattern inside "[]" that contains one or more comma-separated numbers
or number..number ranges (Postfix version 2.8 and later). If no or number..number ranges (Postfix version 2.8 and later). If no
"\fI=d.d.d.d\fR" is specified, "\fI=d.d.d.d\fR" is specified,
reject the request when the MAIL FROM domain is reject the request when the MAIL FROM domain is

View File

@ -210,6 +210,9 @@ a successful "pipelining" SMTP protocol test.
.IP "\fBline_length_limit (2048)\fR" .IP "\fBline_length_limit (2048)\fR"
Upon input, long lines are chopped up into pieces of at most Upon input, long lines are chopped up into pieces of at most
this length; upon delivery, long lines are reconstructed. this length; upon delivery, long lines are reconstructed.
.IP "\fBpostscreen_client_connection_count_limit ($smtpd_client_connection_count_limit)\fR"
How many simultaneous connections any client is allowed to have
with the \fBpostscreen\fR(8) daemon.
.IP "\fBpostscreen_command_count_limit (20)\fR" .IP "\fBpostscreen_command_count_limit (20)\fR"
The limit on the total number of commands per SMTP session for The limit on the total number of commands per SMTP session for
\fBpostscreen\fR(8)'s built-in SMTP protocol engine. \fBpostscreen\fR(8)'s built-in SMTP protocol engine.

View File

@ -944,6 +944,7 @@ while (<>) {
s;\bpostscreen_whitelist_networks\b;<a href="postconf.5.html#postscreen_whitelist_networks">$&</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_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; s;\bpostscreen_black[-</bB>]*\n*[ <bB>]*list_action\b;<a href="postconf.5.html#postscreen_blacklist_action">$&</a>;g;
s;\bpostscreen_client_connection_count_limit\b;<a href="postconf.5.html#postscreen_client_connection_count_limit">$&</a>;g;
# Hyperlink URLs and RFC documents # Hyperlink URLs and RFC documents

View File

@ -131,11 +131,11 @@ handling of known clients. </p>
<p> The postscreen_whitelist_networks parameter (default: $mynetworks) <p> The postscreen_whitelist_networks parameter (default: $mynetworks)
specifies a permanent whitelist for SMTP client IP addresses. When specifies a permanent whitelist for SMTP client IP addresses. When
the SMTP client address matches the permanent whitelist, this is the SMTP client address matches the permanent whitelist, postscreen(8)
logged as: </p> logs this with the client address and port number as: </p>
<pre> <pre>
<b>WHITELISTED</b> <i>address</i> <b>WHITELISTED</b> <i>[address]:port</i>
</pre> </pre>
<p> The action is not configurable: immediately hand off the <p> The action is not configurable: immediately hand off the
@ -146,10 +146,11 @@ connection to a Postfix SMTP server process. </p>
<p> The postscreen_blacklist_networks parameter (default: empty) <p> The postscreen_blacklist_networks parameter (default: empty)
specifies a permanent blacklist for SMTP client IP addresses. The specifies a permanent blacklist for SMTP client IP addresses. The
address syntax is as with mynetworks. When the SMTP client address address syntax is as with mynetworks. When the SMTP client address
matches the permanent blacklist, postscreen(8) logs this as: </p> matches the permanent blacklist, postscreen(8) logs this with the
client address and port number as: </p>
<pre> <pre>
<b>BLACKLISTED</b> <i>address</i> <b>BLACKLISTED</b> <i>[address]:port</i>
</pre> </pre>
<p> The postscreen_blacklist_action parameter specifies the action <p> The postscreen_blacklist_action parameter specifies the action
@ -166,10 +167,11 @@ temporary whitelist is not used for SMTP client addresses
that appear on the <i>permanent</i> blacklist or whitelist. </p> that appear on the <i>permanent</i> blacklist or whitelist. </p>
<p> When the SMTP client address appears on the temporary <p> When the SMTP client address appears on the temporary
whitelist, postscreen(8) logs this as: </p> whitelist, postscreen(8) logs this with the client address and port
number as: </p>
<pre> <pre>
<b>PASS OLD</b> <i>address</i> <b>PASS OLD</b> <i>[address]:port</i>
</pre> </pre>
<p> The action is not configurable: immediately hand off the <p> The action is not configurable: immediately hand off the
@ -238,10 +240,10 @@ postscreen_greet_wait time has elapsed, postscreen(8) logs this as:
</p> </p>
<pre> <pre>
<b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>address text...</i> <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>[address]:port text...</i>
</pre> </pre>
<p> Translation: the client at <i>address</i> sent <i>count</i> <p> Translation: the client at <i>[address]:port</i> sent <i>count</i>
bytes before its turn to speak. This happened <i>time</i> seconds bytes before its turn to speak. This happened <i>time</i> seconds
after the postscreen_greet_wait timer was started. The <i>text</i> after the postscreen_greet_wait timer was started. The <i>text</i>
is what the client sent (truncated to 100 bytes, and with non-printable is what the client sent (truncated to 100 bytes, and with non-printable
@ -271,10 +273,10 @@ DNSBL score is equal to or greater than the postscreen_dnsbl_threshold
parameter value, postscreen(8) logs this as: </p> parameter value, postscreen(8) logs this as: </p>
<pre> <pre>
<b>DNSBL rank</b> <i>count</i> <b>for</b> <i>address</i> <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> has a combined <p> Translation: the SMTP client at <i>[address]:port</i> has a combined
DNSBL score of <i>count</i>. </p> DNSBL score of <i>count</i>. </p>
<p> The postscreen_dnsbl_action parameter specifies the action that <p> The postscreen_dnsbl_action parameter specifies the action that
@ -380,10 +382,10 @@ logging more informative. </p>
as: </p> as: </p>
<pre> <pre>
<b>COMMAND PIPELINING after</b> <i>time</i> <b>from</b> <i>address</i> <b>COMMAND PIPELINING after</b> <i>time</i> <b>from</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> sent multiple <p> Translation: the SMTP client at <i>[address]:port</i> sent multiple
SMTP commands, instead of sending one command and then waiting for SMTP commands, instead of sending one command and then waiting for
the server to reply. This happened <i>time</i> seconds after the the server to reply. This happened <i>time</i> seconds after the
"220 " server greeting was sent. </p> "220 " server greeting was sent. </p>
@ -416,10 +418,10 @@ logging more informative. </p>
as: </p> as: </p>
<pre> <pre>
<b>NON-SMTP COMMAND from</b> <i>address command</i> <b>NON-SMTP COMMAND from</b> <i>[address]:port command</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> sent a <p> Translation: the SMTP client at <i>[address]:port</i> sent a
<i>command</i> that matches the postscreen_forbidden_commands <i>command</i> that matches the postscreen_forbidden_commands
parameter, or that has the syntax of a message header label. </p> parameter, or that has the syntax of a message header label. </p>
@ -448,10 +450,10 @@ this as:
</p> </p>
<pre> <pre>
<b>BARE NEWLINE from</b> <i>address</i> <b>BARE NEWLINE from</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> sent a bare <p> Translation: the SMTP client at <i>[address]:port</i> sent a bare
newline character, that is newline not preceded by carriage newline character, that is newline not preceded by carriage
return. </p> return. </p>
@ -499,10 +501,10 @@ feature. </dd>
postscreen(8) logs this as: </p> postscreen(8) logs this as: </p>
<pre> <pre>
<b>HANGUP after</b> <i>time</i> <b>from</b> <i>address</i> <b>in</b> <i>test name</i> <b>HANGUP after</b> <i>time</i> <b>from</b> <i>[address]:port</i> <b>in</b> <i>test name</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> disconnected <p> Translation: the SMTP client at <i>[address]:port</i> disconnected
unexpectedly, <i>time</i> seconds after the start of the unexpectedly, <i>time</i> seconds after the start of the
test named <i>test name</i>. </p> test named <i>test name</i>. </p>
@ -513,7 +515,7 @@ allowed to pass any tests, and postscreen(8) logs each connection
with the remaining amount of penalty time as: </p> with the remaining amount of penalty time as: </p>
<pre> <pre>
<b>PENALTY</b> <i>time</i> <b>for</b> <i>address</i> <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i>
</pre> </pre>
<p> During this time, all attempts by the client to deliver mail <p> During this time, all attempts by the client to deliver mail
@ -526,40 +528,53 @@ This engine never accepts mail, therefore it has per-session limits
on the number of commands and on the session length. </p> on the number of commands and on the session length. </p>
<pre> <pre>
<b>COMMAND TIME LIMIT</b> <b>from</b> <i>address</i> <b>COMMAND TIME LIMIT</b> <b>from</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> reached the <p> Translation: the SMTP client at <i>[address]:port</i> reached the
per-command time limit as specified with the postscreen_command_time_limit per-command time limit as specified with the postscreen_command_time_limit
parameter. The session is terminated immediately. </p> parameter. The session is terminated immediately. </p>
<pre> <pre>
<b>COMMAND COUNT LIMIT from</b> <i>address</i> <b>COMMAND COUNT LIMIT from</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> reached the <p> Translation: the SMTP client at <i>[address]:port</i> reached the
per-session command count limit as specified with the per-session command count limit as specified with the
postscreen_command_count_limit parameter. The session is terminated postscreen_command_count_limit parameter. The session is terminated
immediately. </p> immediately. </p>
<pre> <pre>
<b>COMMAND LENGTH LIMIT from</b> <i>address</i> <b>COMMAND LENGTH LIMIT from</b> <i>[address]:port</i>
</pre> </pre>
<p> Translation: the SMTP client at <i>address</i> reached the <p> Translation: the SMTP client at <i>[address]:port</i> reached the
per-command length limit, as specified with the line_length_limit per-command length limit, as specified with the line_length_limit
parameter. The session is terminated immediately. </p> parameter. The session is terminated immediately. </p>
<p> When an SMTP client makes too many connections at the same time,
or when all postscreen(8) ports are busy, postscreen(8) rejects the
connection with a 421 status code and logs: </p>
<pre>
<b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: too many connections</b>
<b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all server ports busy</b>
</pre>
<p> The postscreen_client_connection_count_limit and
postscreen_pre_queue_limit parameters control these limits. </p>
<h2> <a name="victory">When all tests succeed</a> </h2> <h2> <a name="victory">When all tests succeed</a> </h2>
<p> When a new SMTP client passes all tests (i.e. it is not whitelisted <p> When a new SMTP client passes all tests (i.e. it is not whitelisted
via some mechanism), postscreen(8) logs this as: </p> via some mechanism), postscreen(8) logs this as: </p>
<pre> <pre>
<b>PASS NEW</b> <i>address</i> <b>PASS NEW</b> <i>[address]:port</i>
</pre> </pre>
<p> Where <i>address</i> is the client IP address. Then, postscreen(8) <p> Where <i>[address]:port</i> are the client IP address and port.
Then, postscreen(8)
creates a temporary whitelist entry that excludes the client IP creates a temporary whitelist entry that excludes the client IP
address from further tests until the temporary whitelist entry address from further tests until the temporary whitelist entry
expires, as controlled with the postscreen_*_ttl parameters. </p> expires, as controlled with the postscreen_*_ttl parameters. </p>

View File

@ -4879,8 +4879,8 @@ Postfix version 2.5). This feature is available with Postfix version
<dd>Reject the request when the reversed client network address is <dd>Reject the request when the reversed client network address is
listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
(Postfix version 2.1 and later only). Each "<i>d</i>" can be a (Postfix version 2.1 and later only). Each "<i>d</i>" is a number,
pattern inside "[]" that contains one or more comma-separated decimal or a pattern inside "[]" that contains one or more comma-separated
numbers or number..number ranges (Postfix version 2.8 and later). numbers or number..number ranges (Postfix version 2.8 and later).
If no "<i>=d.d.d.d</i>" is specified, reject the request when the If no "<i>=d.d.d.d</i>" is specified, reject the request when the
reversed client network address is listed with any A record under reversed client network address is listed with any A record under
@ -4895,8 +4895,8 @@ This feature is available in Postfix 2.0 and later. </dd>
<dd>Accept the request when the reversed client network address is <dd>Accept the request when the reversed client network address is
listed with the A record "<i>d.d.d.d</i>" under <i>dnswl_domain</i>. listed with the A record "<i>d.d.d.d</i>" under <i>dnswl_domain</i>.
Each "<i>d</i>" can be a pattern inside "[]" that contains one or Each "<i>d</i>" is a number, or a pattern inside "[]" that contains
more comma-separated decimal numbers or number..number ranges. one or more comma-separated numbers or number..number ranges.
If no "<i>=d.d.d.d</i>" is specified, accept the request when the If no "<i>=d.d.d.d</i>" is specified, accept the request when the
reversed client network address is listed with any A record under reversed client network address is listed with any A record under
<i>dnswl_domain</i>. <br> For safety, permit_dnswl_client is silently <i>dnswl_domain</i>. <br> For safety, permit_dnswl_client is silently
@ -4908,8 +4908,8 @@ is available in Postfix 2.8 and later. </dd>
<dd>Reject the request when the client hostname is listed with the <dd>Reject the request when the client hostname is listed with the
A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version
2.1 and later only). Each "<i>d</i>" can be a pattern inside "[]" 2.1 and later only). Each "<i>d</i>" is a number, or a pattern
that contains one or more comma-separated decimal numbers or inside "[]" that contains one or more comma-separated numbers or
number..number ranges (Postfix version 2.8 and later). If no number..number ranges (Postfix version 2.8 and later). If no
"<i>=d.d.d.d</i>" is specified, reject the request when the client "<i>=d.d.d.d</i>" is specified, reject the request when the client
hostname is listed with hostname is listed with
@ -4923,8 +4923,8 @@ produce better results. </dd>
<dd>Accept the request when the client hostname is listed with the <dd>Accept the request when the client hostname is listed with the
A record "<i>d.d.d.d</i>" under <i>rhswl_domain</i>. Each "<i>d</i>" A record "<i>d.d.d.d</i>" under <i>rhswl_domain</i>. Each "<i>d</i>"
can be a pattern inside "[]" that contains one or more comma-separated is a number, or a pattern inside "[]" that contains one or more
decimal numbers or number..number ranges. If no comma-separated numbers or number..number ranges. If no
"<i>=d.d.d.d</i>" is specified, accept the request when the client "<i>=d.d.d.d</i>" is specified, accept the request when the client
hostname is listed with any A record under <i>rhswl_domain</i>. hostname is listed with any A record under <i>rhswl_domain</i>.
<br> Caution: client name whitelisting is fragile, since the client <br> Caution: client name whitelisting is fragile, since the client
@ -4940,8 +4940,8 @@ when whitelist lookup fails. This feature is available in Postfix
<dd>Reject the request when the unverified reverse client hostname <dd>Reject the request when the unverified reverse client hostname
is listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>. is listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>.
Each "<i>d</i>" can be a pattern inside "[]" that contains one or Each "<i>d</i>" is a number, or a pattern inside "[]" that contains
more comma-separated decimal numbers or number..number ranges. one or more comma-separated numbers or number..number ranges.
If no "<i>=d.d.d.d</i>" is specified, reject the request when the If no "<i>=d.d.d.d</i>" is specified, reject the request when the
unverified reverse client hostname is listed with any A record under unverified reverse client hostname is listed with any A record under
<i>rbl_domain</i>. See the reject_rbl_client description above for <i>rbl_domain</i>. See the reject_rbl_client description above for
@ -5346,50 +5346,58 @@ received with the HELO or EHLO command.
<dd>Search the specified access(5) database for the HELO or EHLO <dd>Search the specified access(5) database for the HELO or EHLO
hostname or parent domains, and execute the corresponding action. hostname or parent domains, and execute the corresponding action.
</dd> Note: specify "smtpd_helo_required = yes" to fully enforce this
restriction. </dd>
<dt><b><a name="check_helo_mx_access">check_helo_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> <dt><b><a name="check_helo_mx_access">check_helo_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
<dd>Search the specified access(5) database for the MX hosts for <dd>Search the specified access(5) database for the MX hosts for
the HELO or EHLO hostname, and execute the corresponding action. the HELO or EHLO hostname, and execute the corresponding action.
Note: a result of "OK" is not allowed for safety reasons. Instead, Note 1: a result of "OK" is not allowed for safety reasons. Instead,
use DUNNO in order to exclude specific hosts from blacklists. This use DUNNO in order to exclude specific hosts from blacklists. Note
feature is available in Postfix 2.1 and later. </dd> 2: specify "smtpd_helo_required = yes" to fully enforce this
restriction. This feature is available in Postfix 2.1 and later.
</dd>
<dt><b><a name="check_helo_ns_access">check_helo_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt> <dt><b><a name="check_helo_ns_access">check_helo_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
<dd>Search the specified access(5) database for the DNS servers <dd>Search the specified access(5) database for the DNS servers
for the HELO or EHLO hostname, and execute the corresponding action. for the HELO or EHLO hostname, and execute the corresponding action.
Note: a result of "OK" is not allowed for safety reasons. Instead, Note 1: a result of "OK" is not allowed for safety reasons. Instead,
use DUNNO in order to exclude specific hosts from blacklists. This use DUNNO in order to exclude specific hosts from blacklists. Note
feature is available in Postfix 2.1 and later. </dd> 2: specify "smtpd_helo_required = yes" to fully enforce this
restriction. This feature is available in Postfix 2.1 and later.
</dd>
<dt><b><a name="reject_invalid_helo_hostname">reject_invalid_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_invalid_hostname)</dt> <dt><b><a name="reject_invalid_helo_hostname">reject_invalid_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_invalid_hostname)</dt>
<dd>Reject the request when the HELO or EHLO hostname syntax is <dd>Reject the request when the HELO or EHLO hostname syntax is
invalid. <br> The invalid_hostname_reject_code specifies the response invalid. Note: specify "smtpd_helo_required = yes" to fully enforce
code for rejected requests (default: 501).</dd> this restriction. <br> The invalid_hostname_reject_code specifies
the response code for rejected requests (default: 501).</dd>
<dt><b><a name="reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_non_fqdn_hostname)</dt> <dt><b><a name="reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_non_fqdn_hostname)</dt>
<dd>Reject the request when the HELO or EHLO hostname is not in <dd>Reject the request when the HELO or EHLO hostname is not in
fully-qualified domain form, as required by the RFC. <br> The fully-qualified domain form, as required by the RFC. Note: specify
non_fqdn_reject_code parameter specifies the response code for "smtpd_helo_required = yes" to fully enforce this restriction. <br>
The non_fqdn_reject_code parameter specifies the response code for
rejected requests (default: 504).</dd> rejected requests (default: 504).</dd>
<dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt> <dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt>
<dd>Reject the request when the HELO or EHLO hostname hostname is <dd>Reject the request when the HELO or EHLO hostname hostname is
listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
(Postfix version 2.1 and later only). Each "<i>d</i>" can be a (Postfix version 2.1 and later only). Each "<i>d</i>" is a number,
pattern inside "[]" that contains one or more comma-separated decimal or a pattern inside "[]" that contains one or more comma-separated
numbers or number..number ranges (Postfix version 2.8 and later). numbers or number..number ranges (Postfix version 2.8 and later).
If no "<i>=d.d.d.d</i>" is If no "<i>=d.d.d.d</i>" is
specified, reject the request when the HELO or EHLO hostname is specified, reject the request when the HELO or EHLO hostname is
listed with any A record under <i>rbl_domain</i>. See the listed with any A record under <i>rbl_domain</i>. See the
reject_rbl_client description for additional RBL related configuration reject_rbl_client description for additional RBL related configuration
parameters. This feature is available in Postfix 2.0 and later. parameters. Note: specify "smtpd_helo_required = yes" to fully
</dd> enforce this restriction. This feature is available in Postfix 2.0
and later. </dd>
<dt><b><a name="reject_unknown_helo_hostname">reject_unknown_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_unknown_hostname)</dt> <dt><b><a name="reject_unknown_helo_hostname">reject_unknown_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_unknown_hostname)</dt>
@ -5398,7 +5406,8 @@ or MX record. <br> The unknown_hostname_reject_code parameter
specifies the numerical response code for rejected requests (default: specifies the numerical response code for rejected requests (default:
450). <br> The unknown_helo_hostname_tempfail_action parameter 450). <br> The unknown_helo_hostname_tempfail_action parameter
specifies the action after a temporary DNS error (default: specifies the action after a temporary DNS error (default:
defer_if_permit). </dd> defer_if_permit). Note: specify "smtpd_helo_required = yes" to fully
enforce this restriction. </dd>
</dl> </dl>
@ -5674,8 +5683,8 @@ rejected requests (default: 504). </dd>
<dd>Reject the request when the RCPT TO domain is listed with the <dd>Reject the request when the RCPT TO domain is listed with the
A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version
2.1 and later only). Each "<i>d</i>" can be a pattern inside "[]" 2.1 and later only). Each "<i>d</i>" is a number, or a pattern
that contains one or more comma-separated decimal numbers or inside "[]" that contains one or more comma-separated numbers or
number..number ranges (Postfix version 2.8 and later). If no number..number ranges (Postfix version 2.8 and later). If no
"<i>=d.d.d.d</i>" is specified, reject "<i>=d.d.d.d</i>" is specified, reject
the request when the RCPT TO domain is listed with the request when the RCPT TO domain is listed with
@ -6052,8 +6061,8 @@ rejected requests (default: 504). </dd>
<dd>Reject the request when the MAIL FROM domain is listed with <dd>Reject the request when the MAIL FROM domain is listed with
the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix
version 2.1 and later only). Each "<i>d</i>" can be a pattern version 2.1 and later only). Each "<i>d</i>" is a number, or a
inside "[]" that contains one or more comma-separated decimal numbers pattern inside "[]" that contains one or more comma-separated numbers
or number..number ranges (Postfix version 2.8 and later). If no or number..number ranges (Postfix version 2.8 and later). If no
"<i>=d.d.d.d</i>" is specified, "<i>=d.d.d.d</i>" is specified,
reject the request when the MAIL FROM domain is reject the request when the MAIL FROM domain is
@ -13331,6 +13340,17 @@ it passes the test, before it can talk to a real Postfix SMTP server.
<p> This feature is available in Postfix 2.8. </p> <p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_client_connection_count_limit $smtpd_client_connection_count_limit
<p> How many simultaneous connections any client is allowed to have
with the postscreen(8) daemon. By default, this limit is the same
as with the Postfix SMTP server. Note that the triage process can
take several seconds, with the time spent in postscreen_greet_wait
delay, and with the time spent talking to the postscreen(8) built-in
dummy SMTP protocol engine. </p>
<p> This feature is available in Postfix 2.8. </p>
%PARAM dnsblog_reply_delay 0s %PARAM dnsblog_reply_delay 0s
<p> A debugging aid to artifically delay DNS responses. </p> <p> A debugging aid to artifically delay DNS responses. </p>

View File

@ -3366,6 +3366,10 @@ extern bool var_ps_helo_required;
#define DEF_PS_DISABLE_VRFY "$" VAR_DISABLE_VRFY_CMD #define DEF_PS_DISABLE_VRFY "$" VAR_DISABLE_VRFY_CMD
extern bool var_ps_disable_vrfy; extern bool var_ps_disable_vrfy;
#define VAR_PS_CCONN_LIMIT "postscreen_client_connection_count_limit"
#define DEF_PS_CCONN_LIMIT "$" VAR_SMTPD_CCONN_LIMIT
extern int var_ps_cconn_limit;
#define VAR_DNSBLOG_DELAY "dnsblog_reply_delay" #define VAR_DNSBLOG_DELAY "dnsblog_reply_delay"
#define DEF_DNSBLOG_DELAY "0s" #define DEF_DNSBLOG_DELAY "0s"
extern int var_dnsblog_delay; extern int var_dnsblog_delay;

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no * Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only. * patchlevel; they change the release date only.
*/ */
#define MAIL_RELEASE_DATE "20101126" #define MAIL_RELEASE_DATE "20101130"
#define MAIL_VERSION_NUMBER "2.8" #define MAIL_VERSION_NUMBER "2.8"
#ifdef SNAPSHOT #ifdef SNAPSHOT

View File

@ -68,6 +68,7 @@ postscreen.o: ../../include/data_redirect.h
postscreen.o: ../../include/dict.h postscreen.o: ../../include/dict.h
postscreen.o: ../../include/dict_cache.h postscreen.o: ../../include/dict_cache.h
postscreen.o: ../../include/events.h postscreen.o: ../../include/events.h
postscreen.o: ../../include/htable.h
postscreen.o: ../../include/iostuff.h postscreen.o: ../../include/iostuff.h
postscreen.o: ../../include/mail_conf.h postscreen.o: ../../include/mail_conf.h
postscreen.o: ../../include/mail_params.h postscreen.o: ../../include/mail_params.h
@ -93,6 +94,7 @@ postscreen_dict.o: ../../include/argv.h
postscreen_dict.o: ../../include/dict.h postscreen_dict.o: ../../include/dict.h
postscreen_dict.o: ../../include/dict_cache.h postscreen_dict.o: ../../include/dict_cache.h
postscreen_dict.o: ../../include/events.h postscreen_dict.o: ../../include/events.h
postscreen_dict.o: ../../include/htable.h
postscreen_dict.o: ../../include/match_list.h postscreen_dict.o: ../../include/match_list.h
postscreen_dict.o: ../../include/match_ops.h postscreen_dict.o: ../../include/match_ops.h
postscreen_dict.o: ../../include/msg.h postscreen_dict.o: ../../include/msg.h
@ -118,6 +120,7 @@ postscreen_dnsbl.o: ../../include/mail_proto.h
postscreen_dnsbl.o: ../../include/match_list.h postscreen_dnsbl.o: ../../include/match_list.h
postscreen_dnsbl.o: ../../include/match_ops.h postscreen_dnsbl.o: ../../include/match_ops.h
postscreen_dnsbl.o: ../../include/msg.h postscreen_dnsbl.o: ../../include/msg.h
postscreen_dnsbl.o: ../../include/myaddrinfo.h
postscreen_dnsbl.o: ../../include/mymalloc.h postscreen_dnsbl.o: ../../include/mymalloc.h
postscreen_dnsbl.o: ../../include/split_at.h postscreen_dnsbl.o: ../../include/split_at.h
postscreen_dnsbl.o: ../../include/string_list.h postscreen_dnsbl.o: ../../include/string_list.h
@ -133,6 +136,7 @@ postscreen_early.o: ../../include/argv.h
postscreen_early.o: ../../include/dict.h postscreen_early.o: ../../include/dict.h
postscreen_early.o: ../../include/dict_cache.h postscreen_early.o: ../../include/dict_cache.h
postscreen_early.o: ../../include/events.h postscreen_early.o: ../../include/events.h
postscreen_early.o: ../../include/htable.h
postscreen_early.o: ../../include/mail_params.h postscreen_early.o: ../../include/mail_params.h
postscreen_early.o: ../../include/match_list.h postscreen_early.o: ../../include/match_list.h
postscreen_early.o: ../../include/match_ops.h postscreen_early.o: ../../include/match_ops.h
@ -152,6 +156,7 @@ postscreen_misc.o: ../../include/dict.h
postscreen_misc.o: ../../include/dict_cache.h postscreen_misc.o: ../../include/dict_cache.h
postscreen_misc.o: ../../include/events.h postscreen_misc.o: ../../include/events.h
postscreen_misc.o: ../../include/format_tv.h postscreen_misc.o: ../../include/format_tv.h
postscreen_misc.o: ../../include/htable.h
postscreen_misc.o: ../../include/iostuff.h postscreen_misc.o: ../../include/iostuff.h
postscreen_misc.o: ../../include/mail_params.h postscreen_misc.o: ../../include/mail_params.h
postscreen_misc.o: ../../include/match_list.h postscreen_misc.o: ../../include/match_list.h
@ -170,6 +175,7 @@ postscreen_send.o: ../../include/connect.h
postscreen_send.o: ../../include/dict.h postscreen_send.o: ../../include/dict.h
postscreen_send.o: ../../include/dict_cache.h postscreen_send.o: ../../include/dict_cache.h
postscreen_send.o: ../../include/events.h postscreen_send.o: ../../include/events.h
postscreen_send.o: ../../include/htable.h
postscreen_send.o: ../../include/iostuff.h postscreen_send.o: ../../include/iostuff.h
postscreen_send.o: ../../include/match_list.h postscreen_send.o: ../../include/match_list.h
postscreen_send.o: ../../include/match_ops.h postscreen_send.o: ../../include/match_ops.h
@ -187,6 +193,7 @@ postscreen_smtpd.o: ../../include/attr.h
postscreen_smtpd.o: ../../include/dict.h postscreen_smtpd.o: ../../include/dict.h
postscreen_smtpd.o: ../../include/dict_cache.h postscreen_smtpd.o: ../../include/dict_cache.h
postscreen_smtpd.o: ../../include/events.h postscreen_smtpd.o: ../../include/events.h
postscreen_smtpd.o: ../../include/htable.h
postscreen_smtpd.o: ../../include/iostuff.h postscreen_smtpd.o: ../../include/iostuff.h
postscreen_smtpd.o: ../../include/is_header.h postscreen_smtpd.o: ../../include/is_header.h
postscreen_smtpd.o: ../../include/mail_params.h postscreen_smtpd.o: ../../include/mail_params.h
@ -209,6 +216,7 @@ postscreen_state.o: ../../include/attr.h
postscreen_state.o: ../../include/dict.h postscreen_state.o: ../../include/dict.h
postscreen_state.o: ../../include/dict_cache.h postscreen_state.o: ../../include/dict_cache.h
postscreen_state.o: ../../include/events.h postscreen_state.o: ../../include/events.h
postscreen_state.o: ../../include/htable.h
postscreen_state.o: ../../include/iostuff.h postscreen_state.o: ../../include/iostuff.h
postscreen_state.o: ../../include/mail_proto.h postscreen_state.o: ../../include/mail_proto.h
postscreen_state.o: ../../include/mail_server.h postscreen_state.o: ../../include/mail_server.h
@ -229,6 +237,7 @@ postscreen_tests.o: ../../include/argv.h
postscreen_tests.o: ../../include/dict.h postscreen_tests.o: ../../include/dict.h
postscreen_tests.o: ../../include/dict_cache.h postscreen_tests.o: ../../include/dict_cache.h
postscreen_tests.o: ../../include/events.h postscreen_tests.o: ../../include/events.h
postscreen_tests.o: ../../include/htable.h
postscreen_tests.o: ../../include/mail_params.h postscreen_tests.o: ../../include/mail_params.h
postscreen_tests.o: ../../include/match_list.h postscreen_tests.o: ../../include/match_list.h
postscreen_tests.o: ../../include/match_ops.h postscreen_tests.o: ../../include/match_ops.h

View File

@ -188,6 +188,9 @@
/* .IP "\fBline_length_limit (2048)\fR" /* .IP "\fBline_length_limit (2048)\fR"
/* Upon input, long lines are chopped up into pieces of at most /* Upon input, long lines are chopped up into pieces of at most
/* this length; upon delivery, long lines are reconstructed. /* this length; upon delivery, long lines are reconstructed.
/* .IP "\fBpostscreen_client_connection_count_limit ($smtpd_client_connection_count_limit)\fR"
/* How many simultaneous connections any client is allowed to have
/* with the \fBpostscreen\fR(8) daemon.
/* .IP "\fBpostscreen_command_count_limit (20)\fR" /* .IP "\fBpostscreen_command_count_limit (20)\fR"
/* The limit on the total number of commands per SMTP session for /* The limit on the total number of commands per SMTP session for
/* \fBpostscreen\fR(8)'s built-in SMTP protocol engine. /* \fBpostscreen\fR(8)'s built-in SMTP protocol engine.
@ -348,6 +351,8 @@ int var_ps_barlf_ttl;
int var_ps_cmd_count; int var_ps_cmd_count;
char *var_ps_cmd_time; char *var_ps_cmd_time;
int var_ps_cconn_limit;
/* /*
* Global variables. * Global variables.
*/ */
@ -372,6 +377,7 @@ int ps_stress; /* stress level */
int ps_check_queue_length_lowat; /* stress low-water mark */ int ps_check_queue_length_lowat; /* stress low-water mark */
int ps_check_queue_length_hiwat; /* stress high-water mark */ int ps_check_queue_length_hiwat; /* stress high-water mark */
DICT *ps_dnsbl_reply; /* DNSBL name mapper */ DICT *ps_dnsbl_reply; /* DNSBL name mapper */
HTABLE *ps_client_concurrency; /* per-client concurrency */
/* /*
* Local variables. * Local variables.
@ -501,11 +507,11 @@ static void ps_service(VSTREAM *smtp_client_stream,
memmove(smtp_client_addr.buf, smtp_client_addr.buf + 7, memmove(smtp_client_addr.buf, smtp_client_addr.buf + 7,
sizeof(smtp_client_addr.buf) - 7); sizeof(smtp_client_addr.buf) - 7);
if (msg_verbose > 1) if (msg_verbose > 1)
msg_info("%s: sq=%d cq=%d connect from %s:%s", msg_info("%s: sq=%d cq=%d connect from [%s]:%s",
myname, ps_post_queue_length, ps_check_queue_length, myname, ps_post_queue_length, ps_check_queue_length,
smtp_client_addr.buf, smtp_client_port.buf); smtp_client_addr.buf, smtp_client_port.buf);
msg_info("CONNECT from %s", smtp_client_addr.buf); msg_info("CONNECT from [%s]:%s", smtp_client_addr.buf, smtp_client_port.buf);
/* /*
* Bundle up all the loose session pieces. This zeroes all flags and time * Bundle up all the loose session pieces. This zeroes all flags and time
@ -514,12 +520,24 @@ static void ps_service(VSTREAM *smtp_client_stream,
state = ps_new_session_state(smtp_client_stream, smtp_client_addr.buf, state = ps_new_session_state(smtp_client_stream, smtp_client_addr.buf,
smtp_client_port.buf); smtp_client_port.buf);
/*
* Reply with 421 when the client has too many open connections.
*/
if (var_ps_cconn_limit > 0
&& state->client_concurrency > var_ps_cconn_limit) {
msg_info("NOQUEUE: reject: CONNECT from [%s]:%s: too many connections",
state->smtp_client_addr, state->smtp_client_port);
PS_DROP_SESSION_STATE(state,
"421 4.7.0 Error: too many connections\r\n");
return;
}
/* /*
* Reply with 421 when we can't forward more connections. * Reply with 421 when we can't forward more connections.
*/ */
if (var_ps_post_queue_limit > 0 if (var_ps_post_queue_limit > 0
&& ps_post_queue_length >= var_ps_post_queue_limit) { && ps_post_queue_length >= var_ps_post_queue_limit) {
msg_info("reject: connect from %s:%s: all server ports busy", msg_info("NOQUEUE: reject: CONNECT from [%s]:%s: all server ports busy",
state->smtp_client_addr, state->smtp_client_port); state->smtp_client_addr, state->smtp_client_port);
PS_DROP_SESSION_STATE(state, PS_DROP_SESSION_STATE(state,
"421 4.3.2 All server ports are busy\r\n"); "421 4.3.2 All server ports are busy\r\n");
@ -532,7 +550,7 @@ static void ps_service(VSTREAM *smtp_client_stream,
*/ */
if (ps_wlist_nets != 0 if (ps_wlist_nets != 0
&& ps_addr_match_list_match(ps_wlist_nets, state->smtp_client_addr)) { && ps_addr_match_list_match(ps_wlist_nets, state->smtp_client_addr)) {
msg_info("WHITELISTED %s", state->smtp_client_addr); msg_info("WHITELISTED [%s]:%s", PS_CLIENT_ADDR_PORT(state));
ps_conclude(state); ps_conclude(state);
return; return;
} }
@ -544,7 +562,7 @@ static void ps_service(VSTREAM *smtp_client_stream,
*/ */
if (ps_blist_nets != 0 if (ps_blist_nets != 0
&& ps_addr_match_list_match(ps_blist_nets, state->smtp_client_addr)) { && ps_addr_match_list_match(ps_blist_nets, state->smtp_client_addr)) {
msg_info("BLACKLISTED %s", state->smtp_client_addr); msg_info("BLACKLISTED [%s]:%s", PS_CLIENT_ADDR_PORT(state));
PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_BLIST_FAIL); PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_BLIST_FAIL);
switch (ps_blist_action) { switch (ps_blist_action) {
case PS_ACT_DROP: case PS_ACT_DROP:
@ -581,7 +599,7 @@ static void ps_service(VSTREAM *smtp_client_stream,
msg_info("%s: cached + recent flags: %s", msg_info("%s: cached + recent flags: %s",
myname, ps_print_state_flags(state->flags, myname)); myname, ps_print_state_flags(state->flags, myname));
if ((state->flags & PS_STATE_MASK_ANY_TODO_FAIL) == 0) { if ((state->flags & PS_STATE_MASK_ANY_TODO_FAIL) == 0) {
msg_info("PASS OLD %s", state->smtp_client_addr); msg_info("PASS OLD [%s]:%s", PS_CLIENT_ADDR_PORT(state));
ps_conclude(state); ps_conclude(state);
return; return;
} }
@ -599,7 +617,7 @@ static void ps_service(VSTREAM *smtp_client_stream,
*/ */
if (var_ps_pre_queue_limit > 0 if (var_ps_pre_queue_limit > 0
&& ps_check_queue_length - ps_post_queue_length >= var_ps_pre_queue_limit) { && ps_check_queue_length - ps_post_queue_length >= var_ps_pre_queue_limit) {
msg_info("reject: connect from %s:%s: all screening ports busy", msg_info("reject: connect from [%s]:%s: all screening ports busy",
state->smtp_client_addr, state->smtp_client_port); state->smtp_client_addr, state->smtp_client_port);
PS_DROP_SESSION_STATE(state, PS_DROP_SESSION_STATE(state,
"421 4.3.2 All screening ports are busy\r\n"); "421 4.3.2 All screening ports are busy\r\n");
@ -807,6 +825,11 @@ static void post_jail_init(char *unused_name, char **unused_argv)
msg_info(VAR_PS_CMD_TIME ": stress=%d normal=%d lowat=%d hiwat=%d", msg_info(VAR_PS_CMD_TIME ": stress=%d normal=%d lowat=%d hiwat=%d",
ps_stress_cmd_time_limit, ps_normal_cmd_time_limit, ps_stress_cmd_time_limit, ps_normal_cmd_time_limit,
ps_check_queue_length_lowat, ps_check_queue_length_hiwat); ps_check_queue_length_lowat, ps_check_queue_length_hiwat);
/*
* Per-client concurrency.
*/
ps_client_concurrency = htable_create(var_ps_pre_queue_limit);
} }
MAIL_VERSION_STAMP_DECLARE; MAIL_VERSION_STAMP_DECLARE;
@ -848,6 +871,7 @@ int main(int argc, char **argv)
static const CONFIG_NINT_TABLE nint_table[] = { static const CONFIG_NINT_TABLE nint_table[] = {
VAR_PS_POST_QLIMIT, DEF_PS_POST_QLIMIT, &var_ps_post_queue_limit, 5, 0, VAR_PS_POST_QLIMIT, DEF_PS_POST_QLIMIT, &var_ps_post_queue_limit, 5, 0,
VAR_PS_PRE_QLIMIT, DEF_PS_PRE_QLIMIT, &var_ps_pre_queue_limit, 10, 0, VAR_PS_PRE_QLIMIT, DEF_PS_PRE_QLIMIT, &var_ps_pre_queue_limit, 10, 0,
VAR_PS_CCONN_LIMIT, DEF_PS_CCONN_LIMIT, &var_ps_cconn_limit, 0, 0,
0, 0,
}; };
static const CONFIG_TIME_TABLE time_table[] = { static const CONFIG_TIME_TABLE time_table[] = {

View File

@ -19,6 +19,7 @@
#include <vstream.h> #include <vstream.h>
#include <vstring.h> #include <vstring.h>
#include <events.h> #include <events.h>
#include <htable.h>
/* /*
* Global library. * Global library.
@ -41,6 +42,7 @@ typedef struct {
int smtp_server_fd; /* real SMTP server */ int smtp_server_fd; /* real SMTP server */
char *smtp_client_addr; /* client address */ char *smtp_client_addr; /* client address */
char *smtp_client_port; /* client port */ char *smtp_client_port; /* client port */
int client_concurrency; /* per-client */
const char *final_reply; /* cause for hanging up */ const char *final_reply; /* cause for hanging up */
/* Test context. */ /* Test context. */
struct timeval start_time; /* start of current test */ struct timeval start_time; /* start of current test */
@ -288,6 +290,7 @@ extern int ps_stress; /* stress level */
extern int ps_check_queue_length_lowat; /* stress low-water mark */ extern int ps_check_queue_length_lowat; /* stress low-water mark */
extern int ps_check_queue_length_hiwat; /* stress high-water mark */ extern int ps_check_queue_length_hiwat; /* stress high-water mark */
extern DICT *ps_dnsbl_reply; /* DNSBL name mapper */ extern DICT *ps_dnsbl_reply; /* DNSBL name mapper */
extern HTABLE *ps_client_concurrency; /* per-client concurrency */
#define PS_EFF_GREET_WAIT \ #define PS_EFF_GREET_WAIT \
(ps_stress ? ps_stress_greet_wait : ps_normal_greet_wait) (ps_stress ? ps_stress_greet_wait : ps_normal_greet_wait)
@ -323,40 +326,40 @@ extern DICT *ps_dnsbl_reply; /* DNSBL name mapper */
#define PS_PASS_SESSION_STATE(state, what, bits) do { \ #define PS_PASS_SESSION_STATE(state, what, bits) do { \
if (msg_verbose) \ if (msg_verbose) \
msg_info("PASS %s %s:%s", (what), PS_CLIENT_ADDR_PORT(state)); \ msg_info("PASS %s [%s]:%s", (what), PS_CLIENT_ADDR_PORT(state)); \
(state)->flags |= (bits); \ (state)->flags |= (bits); \
} while (0) } while (0)
#define PS_FAIL_SESSION_STATE(state, bits) do { \ #define PS_FAIL_SESSION_STATE(state, bits) do { \
if (msg_verbose) \ if (msg_verbose) \
msg_info("FAIL %s:%s", PS_CLIENT_ADDR_PORT(state)); \ msg_info("FAIL [%s]:%s", PS_CLIENT_ADDR_PORT(state)); \
(state)->flags |= (bits); \ (state)->flags |= (bits); \
} while (0) } while (0)
#define PS_SKIP_SESSION_STATE(state, what, bits) do { \ #define PS_SKIP_SESSION_STATE(state, what, bits) do { \
if (msg_verbose) \ if (msg_verbose) \
msg_info("SKIP %s %s:%s", (what), PS_CLIENT_ADDR_PORT(state)); \ msg_info("SKIP %s [%s]:%s", (what), PS_CLIENT_ADDR_PORT(state)); \
(state)->flags |= (bits); \ (state)->flags |= (bits); \
} while (0) } while (0)
#define PS_DROP_SESSION_STATE(state, reply) do { \ #define PS_DROP_SESSION_STATE(state, reply) do { \
if (msg_verbose) \ if (msg_verbose) \
msg_info("DROP %s:%s", PS_CLIENT_ADDR_PORT(state)); \ msg_info("DROP [%s]:%s", PS_CLIENT_ADDR_PORT(state)); \
(state)->flags |= PS_STATE_FLAG_NOFORWARD; \ (state)->flags |= PS_STATE_FLAG_NOFORWARD; \
(state)->final_reply = (reply); \ (state)->final_reply = (reply); \
ps_conclude(state); \ ps_conclude(state); \
} while (0) } while (0)
#define PS_ENFORCE_SESSION_STATE(state, reply) do { \ #define PS_ENFORCE_SESSION_STATE(state, reply) do { \
if (msg_verbose) \ if (msg_verbose) \
msg_info("ENFORCE %s:%s", PS_CLIENT_ADDR_PORT(state)); \ msg_info("ENFORCE [%s]:%s", PS_CLIENT_ADDR_PORT(state)); \
(state)->rcpt_reply = (reply); \ (state)->rcpt_reply = (reply); \
(state)->flags |= PS_STATE_FLAG_NOFORWARD; \ (state)->flags |= PS_STATE_FLAG_NOFORWARD; \
} while (0) } while (0)
#define PS_UNPASS_SESSION_STATE(state, bits) do { \ #define PS_UNPASS_SESSION_STATE(state, bits) do { \
if (msg_verbose) \ if (msg_verbose) \
msg_info("UNPASS %s:%s", PS_CLIENT_ADDR_PORT(state)); \ msg_info("UNPASS [%s]:%s", PS_CLIENT_ADDR_PORT(state)); \
(state)->flags &= ~(bits); \ (state)->flags &= ~(bits); \
} while (0) } while (0)
#define PS_UNFAIL_SESSION_STATE(state, bits) do { \ #define PS_UNFAIL_SESSION_STATE(state, bits) do { \
if (msg_verbose) \ if (msg_verbose) \
msg_info("UNFAIL %s:%s", PS_CLIENT_ADDR_PORT(state)); \ msg_info("UNFAIL [%s]:%s", PS_CLIENT_ADDR_PORT(state)); \
(state)->flags &= ~(bits); \ (state)->flags &= ~(bits); \
} while (0) } while (0)
#define PS_ADD_SERVER_STATE(state, fd) do { \ #define PS_ADD_SERVER_STATE(state, fd) do { \

View File

@ -107,7 +107,8 @@ typedef struct {
} PS_DNSBL_HEAD; } PS_DNSBL_HEAD;
typedef struct PS_DNSBL_SITE { typedef struct PS_DNSBL_SITE {
char *filter; /* reply filter (default: null) */ char *filter; /* printable filter (default: null) */
char *byte_codes; /* encoded filter (default: null) */
int weight; /* reply weight (default: 1) */ int weight; /* reply weight (default: 1) */
struct PS_DNSBL_SITE *next; /* linked list */ struct PS_DNSBL_SITE *next; /* linked list */
} PS_DNSBL_SITE; } PS_DNSBL_SITE;
@ -263,7 +264,8 @@ static void ps_dnsbl_add_site(const char *site)
* name. * name.
*/ */
new_site = (PS_DNSBL_SITE *) mymalloc(sizeof(*new_site)); new_site = (PS_DNSBL_SITE *) mymalloc(sizeof(*new_site));
new_site->filter = (pattern_text ? ip_match_save(byte_codes) : 0); new_site->filter = (pattern_text ? mystrdup(pattern_text) : 0);
new_site->byte_codes = (byte_codes ? ip_match_save(byte_codes) : 0);
new_site->weight = weight; new_site->weight = weight;
new_site->next = head->first; new_site->next = head->first;
head->first = new_site; head->first = new_site;
@ -382,8 +384,8 @@ static void ps_dnsbl_receive(int event, char *context)
htable_find(dnsbl_site_cache, STR(reply_dnsbl)); htable_find(dnsbl_site_cache, STR(reply_dnsbl));
site = (head ? head->first : (PS_DNSBL_SITE *) 0); site = (head ? head->first : (PS_DNSBL_SITE *) 0);
for (reply_argv = 0; site != 0; site = site->next) { for (reply_argv = 0; site != 0; site = site->next) {
if (site->filter == 0 if (site->byte_codes == 0
|| ps_dnsbl_match(site->filter, reply_argv ? reply_argv : || ps_dnsbl_match(site->byte_codes, reply_argv ? reply_argv :
(reply_argv = argv_split(STR(reply_addr), " ")))) { (reply_argv = argv_split(STR(reply_addr), " ")))) {
if (score->dnsbl == 0) if (score->dnsbl == 0)
score->dnsbl = head->safe_dnsbl; score->dnsbl = head->safe_dnsbl;

View File

@ -62,7 +62,7 @@ static void ps_early_event(int event, char *context)
const char *dnsbl_name; const char *dnsbl_name;
if (msg_verbose > 1) if (msg_verbose > 1)
msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from %s:%s flags=%s", msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from [%s]:%s flags=%s",
myname, ps_post_queue_length, ps_check_queue_length, myname, ps_post_queue_length, ps_check_queue_length,
event, vstream_fileno(state->smtp_client_stream), event, vstream_fileno(state->smtp_client_stream),
state->smtp_client_addr, state->smtp_client_port, state->smtp_client_addr, state->smtp_client_port,
@ -117,8 +117,8 @@ static void ps_early_event(int event, char *context)
PS_PASS_SESSION_STATE(state, "dnsbl test", PS_PASS_SESSION_STATE(state, "dnsbl test",
PS_STATE_FLAG_DNSBL_PASS); PS_STATE_FLAG_DNSBL_PASS);
} else { } else {
msg_info("DNSBL rank %d for %s", msg_info("DNSBL rank %d for [%s]:%s",
dnsbl_score, state->smtp_client_addr); dnsbl_score, PS_CLIENT_ADDR_PORT(state));
PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_DNSBL_FAIL); PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_DNSBL_FAIL);
switch (ps_dnsbl_action) { switch (ps_dnsbl_action) {
case PS_ACT_DROP: case PS_ACT_DROP:
@ -174,9 +174,9 @@ static void ps_early_event(int event, char *context)
return; return;
} }
read_buf[read_count] = 0; read_buf[read_count] = 0;
msg_info("PREGREET %d after %s from %s: %.100s", read_count, msg_info("PREGREET %d after %s from [%s]:%s: %.100s", read_count,
ps_format_delta_time(ps_temp, state->start_time, &elapsed), ps_format_delta_time(ps_temp, state->start_time, &elapsed),
state->smtp_client_addr, printable(read_buf, '?')); PS_CLIENT_ADDR_PORT(state), printable(read_buf, '?'));
PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_PREGR_FAIL); PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_PREGR_FAIL);
switch (ps_pregr_action) { switch (ps_pregr_action) {
case PS_ACT_DROP: case PS_ACT_DROP:
@ -228,7 +228,7 @@ static void ps_early_dnsbl_event(int unused_event, char *context)
PS_STATE *state = (PS_STATE *) context; PS_STATE *state = (PS_STATE *) context;
if (msg_verbose) if (msg_verbose)
msg_info("%s: notify %s:%s", myname, PS_CLIENT_ADDR_PORT(state)); msg_info("%s: notify [%s]:%s", myname, PS_CLIENT_ADDR_PORT(state));
/* /*
* Terminate the greet delay if we're just waiting for DNSBL lookup to * Terminate the greet delay if we're just waiting for DNSBL lookup to

View File

@ -104,8 +104,8 @@ void ps_conclude(PS_STATE *state)
if ((state->flags & PS_STATE_MASK_ANY_PASS) != 0 if ((state->flags & PS_STATE_MASK_ANY_PASS) != 0
&& (state->flags & PS_STATE_MASK_ANY_PASS) == && (state->flags & PS_STATE_MASK_ANY_PASS) ==
PS_STATE_FLAGS_TODO_TO_PASS(state->flags & PS_STATE_MASK_ANY_TODO)) PS_STATE_FLAGS_TODO_TO_PASS(state->flags & PS_STATE_MASK_ANY_TODO))
msg_info("PASS %s %s", (state->flags & PS_STATE_FLAG_NEW) == 0 ? msg_info("PASS %s [%s]:%s", (state->flags & PS_STATE_FLAG_NEW) == 0 ?
"OLD" : "NEW", state->smtp_client_addr); "OLD" : "NEW", PS_CLIENT_ADDR_PORT(state));
/* /*
* Update the postscreen cache. This still supports a scenario where a * Update the postscreen cache. This still supports a scenario where a
@ -128,7 +128,7 @@ void ps_conclude(PS_STATE *state)
(void) ps_send_reply(vstream_fileno(state->smtp_client_stream), (void) ps_send_reply(vstream_fileno(state->smtp_client_stream),
state->smtp_client_addr, state->smtp_client_port, state->smtp_client_addr, state->smtp_client_port,
state->final_reply); state->final_reply);
msg_info("DISCONNECT %s", state->smtp_client_addr); msg_info("DISCONNECT [%s]:%s", PS_CLIENT_ADDR_PORT(state));
ps_free_session_state(state); ps_free_session_state(state);
} }
} }
@ -148,9 +148,9 @@ void ps_hangup_event(PS_STATE *state)
* phase. * phase.
*/ */
state->flags |= PS_STATE_FLAG_HANGUP; state->flags |= PS_STATE_FLAG_HANGUP;
msg_info("HANGUP after %s from %s in %s", msg_info("HANGUP after %s from [%s]:%s in %s",
ps_format_delta_time(ps_temp, state->start_time, &elapsed), ps_format_delta_time(ps_temp, state->start_time, &elapsed),
state->smtp_client_addr, state->test_name); PS_CLIENT_ADDR_PORT(state), state->test_name);
state->flags |= PS_STATE_FLAG_NOFORWARD; state->flags |= PS_STATE_FLAG_NOFORWARD;
ps_conclude(state); ps_conclude(state);
} }

View File

@ -78,7 +78,7 @@ int ps_send_reply(int smtp_client_fd, const char *smtp_client_addr,
int ret; int ret;
if (msg_verbose) if (msg_verbose)
msg_info("> %s:%s: %.*s", smtp_client_addr, smtp_client_port, msg_info("> [%s]:%s: %.*s", smtp_client_addr, smtp_client_port,
(int) strlen(text) - 2, text); (int) strlen(text) - 2, text);
/* /*
@ -88,7 +88,7 @@ int ps_send_reply(int smtp_client_fd, const char *smtp_client_addr,
ret = (write_buf(smtp_client_fd, text, strlen(text), ret = (write_buf(smtp_client_fd, text, strlen(text),
PS_SEND_TEXT_TIMEOUT) < 0); PS_SEND_TEXT_TIMEOUT) < 0);
if (ret != 0 && errno != EPIPE) if (ret != 0 && errno != EPIPE)
msg_warn("write %s:%s: %m", smtp_client_addr, smtp_client_port); msg_warn("write [%s]:%s: %m", smtp_client_addr, smtp_client_port);
return (ret); return (ret);
} }
@ -100,7 +100,7 @@ static void ps_send_socket_close_event(int event, char *context)
PS_STATE *state = (PS_STATE *) context; PS_STATE *state = (PS_STATE *) context;
if (msg_verbose > 1) if (msg_verbose > 1)
msg_info("%s: sq=%d cq=%d event %d on send socket %d from %s:%s", msg_info("%s: sq=%d cq=%d event %d on send socket %d from [%s]:%s",
myname, ps_post_queue_length, ps_check_queue_length, myname, ps_post_queue_length, ps_check_queue_length,
event, state->smtp_server_fd, state->smtp_client_addr, event, state->smtp_server_fd, state->smtp_client_addr,
state->smtp_client_port); state->smtp_client_port);
@ -128,7 +128,7 @@ void ps_send_socket(PS_STATE *state)
int window_size; int window_size;
if (msg_verbose > 1) if (msg_verbose > 1)
msg_info("%s: sq=%d cq=%d send socket %d from %s:%s", msg_info("%s: sq=%d cq=%d send socket %d from [%s]:%s",
myname, ps_post_queue_length, ps_check_queue_length, myname, ps_post_queue_length, ps_check_queue_length,
vstream_fileno(state->smtp_client_stream), vstream_fileno(state->smtp_client_stream),
state->smtp_client_addr, state->smtp_client_port); state->smtp_client_addr, state->smtp_client_port);

View File

@ -321,9 +321,9 @@ static int ps_rcpt_cmd(PS_STATE *state, char *args)
if ((addr = ps_extract_addr(ps_temp, colon + 1)) == 0) if ((addr = ps_extract_addr(ps_temp, colon + 1)) == 0)
return (PS_SEND_REPLY(state, return (PS_SEND_REPLY(state,
"501 5.1.3 Bad recipient address syntax\r\n")); "501 5.1.3 Bad recipient address syntax\r\n"));
msg_info("NOQUEUE: reject: RCPT from [%s]: %.*s; " msg_info("NOQUEUE: reject: RCPT from [%s]:%s: %.*s; "
"from=<%s>, to=<%s>, proto=%s, helo=<%s>", "from=<%s>, to=<%s>, proto=%s, helo=<%s>",
state->smtp_client_addr, PS_CLIENT_ADDR_PORT(state),
(int) strlen(state->rcpt_reply) - 2, state->rcpt_reply, (int) strlen(state->rcpt_reply) - 2, state->rcpt_reply,
state->sender, addr, state->protocol, state->sender, addr, state->protocol,
state->helo_name ? state->helo_name : ""); state->helo_name ? state->helo_name : "");
@ -428,13 +428,13 @@ static void ps_smtpd_time_event(int event, char *context)
PS_STATE *state = (PS_STATE *) context; PS_STATE *state = (PS_STATE *) context;
if (msg_verbose > 1) if (msg_verbose > 1)
msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from %s:%s flags=%s", msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from [%s]:%s flags=%s",
myname, ps_post_queue_length, ps_check_queue_length, myname, ps_post_queue_length, ps_check_queue_length,
event, vstream_fileno(state->smtp_client_stream), event, vstream_fileno(state->smtp_client_stream),
state->smtp_client_addr, state->smtp_client_port, state->smtp_client_addr, state->smtp_client_port,
ps_print_state_flags(state->flags, myname)); ps_print_state_flags(state->flags, myname));
msg_info("COMMAND TIME LIMIT from %s", state->smtp_client_addr); msg_info("COMMAND TIME LIMIT from [%s]:%s", PS_CLIENT_ADDR_PORT(state));
PS_CLEAR_EVENT_DROP_SESSION_STATE(state, ps_smtpd_time_event, PS_CLEAR_EVENT_DROP_SESSION_STATE(state, ps_smtpd_time_event,
ps_smtpd_timeout_reply); ps_smtpd_timeout_reply);
} }
@ -499,7 +499,7 @@ static void ps_smtpd_read_event(int event, char *context)
int write_stat; int write_stat;
if (msg_verbose > 1) if (msg_verbose > 1)
msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from %s:%s flags=%s", msg_info("%s: sq=%d cq=%d event %d on smtp socket %d from [%s]:%s flags=%s",
myname, ps_post_queue_length, ps_check_queue_length, myname, ps_post_queue_length, ps_check_queue_length,
event, vstream_fileno(state->smtp_client_stream), event, vstream_fileno(state->smtp_client_stream),
state->smtp_client_addr, state->smtp_client_port, state->smtp_client_addr, state->smtp_client_port,
@ -543,8 +543,8 @@ static void ps_smtpd_read_event(int event, char *context)
*/ */
if (state->read_state == PS_SMTPD_CMD_ST_ANY if (state->read_state == PS_SMTPD_CMD_ST_ANY
&& VSTRING_LEN(state->cmd_buffer) >= var_line_limit) { && VSTRING_LEN(state->cmd_buffer) >= var_line_limit) {
msg_info("COMMAND LENGTH LIMIT from %s", msg_info("COMMAND LENGTH LIMIT from [%s]:%s",
state->smtp_client_addr); PS_CLIENT_ADDR_PORT(state));
PS_CLEAR_EVENT_DROP_SESSION_STATE(state, ps_smtpd_time_event, PS_CLEAR_EVENT_DROP_SESSION_STATE(state, ps_smtpd_time_event,
ps_smtpd_421_reply); ps_smtpd_421_reply);
return; return;
@ -580,7 +580,8 @@ static void ps_smtpd_read_event(int event, char *context)
if (ch == '\n') { if (ch == '\n') {
if ((state->flags & PS_STATE_MASK_BARLF_TODO_SKIP) if ((state->flags & PS_STATE_MASK_BARLF_TODO_SKIP)
== PS_STATE_FLAG_BARLF_TODO) { == PS_STATE_FLAG_BARLF_TODO) {
msg_info("BARE NEWLINE from %s", state->smtp_client_addr); msg_info("BARE NEWLINE from [%s]:%s",
PS_CLIENT_ADDR_PORT(state));
PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_BARLF_FAIL); PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_BARLF_FAIL);
PS_UNPASS_SESSION_STATE(state, PS_STATE_FLAG_BARLF_PASS); PS_UNPASS_SESSION_STATE(state, PS_STATE_FLAG_BARLF_PASS);
state->barlf_stamp = PS_TIME_STAMP_DISABLED; /* XXX */ state->barlf_stamp = PS_TIME_STAMP_DISABLED; /* XXX */
@ -644,7 +645,7 @@ static void ps_smtpd_read_event(int event, char *context)
*/ */
cmd_buffer_ptr = vstring_str(state->cmd_buffer); cmd_buffer_ptr = vstring_str(state->cmd_buffer);
if (msg_verbose) if (msg_verbose)
msg_info("< %s:%s: %s", state->smtp_client_addr, msg_info("< [%s]:%s: %s", state->smtp_client_addr,
state->smtp_client_port, cmd_buffer_ptr); state->smtp_client_port, cmd_buffer_ptr);
/* Parse the command name. */ /* Parse the command name. */
@ -668,8 +669,8 @@ static void ps_smtpd_read_event(int event, char *context)
|| (*var_ps_forbid_cmds || (*var_ps_forbid_cmds
&& string_list_match(ps_forbid_cmds, command)))) { && string_list_match(ps_forbid_cmds, command)))) {
printable(command, '?'); printable(command, '?');
msg_info("NON-SMTP COMMAND from %s %.100s", msg_info("NON-SMTP COMMAND from [%s]:%s %.100s",
state->smtp_client_addr, command); PS_CLIENT_ADDR_PORT(state), command);
PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_NSMTP_FAIL); PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_NSMTP_FAIL);
PS_UNPASS_SESSION_STATE(state, PS_STATE_FLAG_NSMTP_PASS); PS_UNPASS_SESSION_STATE(state, PS_STATE_FLAG_NSMTP_PASS);
state->nsmtp_stamp = PS_TIME_STAMP_DISABLED; /* XXX */ state->nsmtp_stamp = PS_TIME_STAMP_DISABLED; /* XXX */
@ -703,8 +704,8 @@ static void ps_smtpd_read_event(int event, char *context)
if ((state->flags & PS_STATE_MASK_PIPEL_TODO_SKIP) if ((state->flags & PS_STATE_MASK_PIPEL_TODO_SKIP)
== PS_STATE_FLAG_PIPEL_TODO && !PS_SMTPD_BUFFER_EMPTY(state)) { == PS_STATE_FLAG_PIPEL_TODO && !PS_SMTPD_BUFFER_EMPTY(state)) {
printable(command, '?'); printable(command, '?');
msg_info("COMMAND PIPELINING from %s after %.100s", msg_info("COMMAND PIPELINING from [%s]:%s after %.100s",
state->smtp_client_addr, command); PS_CLIENT_ADDR_PORT(state), command);
PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_PIPEL_FAIL); PS_FAIL_SESSION_STATE(state, PS_STATE_FLAG_PIPEL_FAIL);
PS_UNPASS_SESSION_STATE(state, PS_STATE_FLAG_PIPEL_PASS); PS_UNPASS_SESSION_STATE(state, PS_STATE_FLAG_PIPEL_PASS);
state->pipel_stamp = PS_TIME_STAMP_DISABLED; /* XXX */ state->pipel_stamp = PS_TIME_STAMP_DISABLED; /* XXX */
@ -766,7 +767,8 @@ static void ps_smtpd_read_event(int event, char *context)
/* Command COUNT limit test. */ /* Command COUNT limit test. */
if (++state->command_count > var_ps_cmd_count if (++state->command_count > var_ps_cmd_count
&& cmdp->action != ps_quit_cmd) { && cmdp->action != ps_quit_cmd) {
msg_info("COMMAND COUNT LIMIT from %s", state->smtp_client_addr); msg_info("COMMAND COUNT LIMIT from [%s]:%s",
PS_CLIENT_ADDR_PORT(state));
PS_CLEAR_EVENT_DROP_SESSION_STATE(state, ps_smtpd_time_event, PS_CLEAR_EVENT_DROP_SESSION_STATE(state, ps_smtpd_time_event,
ps_smtpd_421_reply); ps_smtpd_421_reply);
return; return;

View File

@ -123,6 +123,7 @@
#include <msg.h> #include <msg.h>
#include <mymalloc.h> #include <mymalloc.h>
#include <name_mask.h> #include <name_mask.h>
#include <htable.h>
/* Global library. */ /* Global library. */
@ -143,6 +144,7 @@ PS_STATE *ps_new_session_state(VSTREAM *stream,
const char *port) const char *port)
{ {
PS_STATE *state; PS_STATE *state;
HTABLE_INFO *ht;
state = (PS_STATE *) mymalloc(sizeof(*state)); state = (PS_STATE *) mymalloc(sizeof(*state));
PS_INIT_TESTS(state); PS_INIT_TESTS(state);
@ -171,6 +173,15 @@ PS_STATE *ps_new_session_state(VSTREAM *stream,
msg_info("entering STRESS mode with %d connections", msg_info("entering STRESS mode with %d connections",
ps_check_queue_length); ps_check_queue_length);
} }
/*
* Update the per-client session count.
*/
if ((ht = htable_locate(ps_client_concurrency, addr)) == 0)
ht = htable_enter(ps_client_concurrency, addr, (char *) 0);
ht->value += 1;
state->client_concurrency = (int) ht->value;
return (state); return (state);
} }
@ -178,6 +189,18 @@ PS_STATE *ps_new_session_state(VSTREAM *stream,
void ps_free_session_state(PS_STATE *state) void ps_free_session_state(PS_STATE *state)
{ {
const char *myname = "ps_free_session_state";
HTABLE_INFO *ht;
/*
* Update the per-client session count.
*/
if ((ht = htable_locate(ps_client_concurrency, state->smtp_client_addr)) == 0)
msg_panic("%s: unknown client address: %s",
myname, state->smtp_client_addr);
if (--(ht->value) == 0)
htable_delete(ps_client_concurrency, state->smtp_client_addr, (void (*) (char *)) 0);
if (state->smtp_client_stream != 0) { if (state->smtp_client_stream != 0) {
event_server_disconnect(state->smtp_client_stream); event_server_disconnect(state->smtp_client_stream);
ps_check_queue_length--; ps_check_queue_length--;

View File

@ -156,7 +156,6 @@ void ps_parse_tests(PS_STATE *state,
const char *stamp_str, const char *stamp_str,
time_t time_value) time_t time_value)
{ {
const char *myname = "ps_parse_tests";
unsigned long pregr_stamp; unsigned long pregr_stamp;
unsigned long dnsbl_stamp; unsigned long dnsbl_stamp;
unsigned long pipel_stamp; unsigned long pipel_stamp;

View File

@ -33,7 +33,7 @@ SRCS = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
allascii.c load_file.c killme_after.c vstream_tweak.c upass_connect.c \ allascii.c load_file.c killme_after.c vstream_tweak.c upass_connect.c \
upass_listen.c upass_trigger.c edit_file.c inet_windowsize.c \ upass_listen.c upass_trigger.c edit_file.c inet_windowsize.c \
unix_pass_fd_fix.c dict_cache.c valid_utf_8.c dict_thash.c \ unix_pass_fd_fix.c dict_cache.c valid_utf_8.c dict_thash.c \
ip_match.c ip_lmatch.c ip_match.c
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \ attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \ attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@ -68,7 +68,7 @@ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
allascii.o load_file.o killme_after.o vstream_tweak.o upass_connect.o \ allascii.o load_file.o killme_after.o vstream_tweak.o upass_connect.o \
upass_listen.o upass_trigger.o edit_file.o inet_windowsize.o \ upass_listen.o upass_trigger.o edit_file.o inet_windowsize.o \
unix_pass_fd_fix.o dict_cache.o valid_utf_8.o dict_thash.o \ unix_pass_fd_fix.o dict_cache.o valid_utf_8.o dict_thash.o \
ip_match.o ip_lmatch.o ip_match.o
HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \ chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \
dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \ dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \
@ -89,7 +89,7 @@ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
username.h valid_hostname.h vbuf.h vbuf_print.h vstream.h vstring.h \ username.h valid_hostname.h vbuf.h vbuf_print.h vstream.h vstring.h \
vstring_vstream.h watchdog.h format_tv.h load_file.h killme_after.h \ vstring_vstream.h watchdog.h format_tv.h load_file.h killme_after.h \
edit_file.h dict_cache.h dict_thash.h \ edit_file.h dict_cache.h dict_thash.h \
ip_match.h ip_lmatch.h ip_match.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \ TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c test_send_fd test_recv_fd stream_test.c dup2_pass_on_exec.c test_send_fd test_recv_fd
DEFS = -I. -D$(SYSTYPE) DEFS = -I. -D$(SYSTYPE)
@ -107,7 +107,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
attr_scan0 host_port attr_scan_plain attr_print_plain htable \ attr_scan0 host_port attr_scan_plain attr_print_plain htable \
unix_recv_fd unix_send_fd stream_recv_fd stream_send_fd hex_code \ unix_recv_fd unix_send_fd stream_recv_fd stream_send_fd hex_code \
myaddrinfo myaddrinfo4 inet_proto sane_basename format_tv \ myaddrinfo myaddrinfo4 inet_proto sane_basename format_tv \
test_send_fd test_recv_fd valid_utf_8 ip_match ip_lmatch test_send_fd test_recv_fd valid_utf_8 ip_match
LIB_DIR = ../../lib LIB_DIR = ../../lib
INC_DIR = ../../include INC_DIR = ../../include
@ -427,16 +427,11 @@ ip_match: $(LIB)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS) $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
mv junk $@.o mv junk $@.o
ip_lmatch: $(LIB)
mv $@.o junk
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
mv junk $@.o
tests: valid_hostname_test mac_expand_test dict_test unescape_test \ tests: valid_hostname_test mac_expand_test dict_test unescape_test \
hex_quote_test ctable_test inet_addr_list_test base64_code_test \ hex_quote_test ctable_test inet_addr_list_test base64_code_test \
attr_scan64_test attr_scan0_test dict_pcre_test host_port_test \ attr_scan64_test attr_scan0_test dict_pcre_test host_port_test \
dict_cidr_test attr_scan_plain_test htable_test hex_code_test \ dict_cidr_test attr_scan_plain_test htable_test hex_code_test \
myaddrinfo_test format_tv_test ip_match_test ip_lmatch_test myaddrinfo_test format_tv_test ip_match_test
root_tests: root_tests:
@ -563,11 +558,6 @@ ip_match_test: ip_match ip_match.in ip_match.ref
diff ip_match.ref ip_match.tmp diff ip_match.ref ip_match.tmp
rm -f ip_match.tmp rm -f ip_match.tmp
ip_lmatch_test: ip_lmatch ip_lmatch.in ip_lmatch.ref
./ip_lmatch <ip_lmatch.in >ip_lmatch.tmp
diff ip_lmatch.ref ip_lmatch.tmp
rm -f ip_lmatch.tmp
depend: $(MAKES) depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \ (sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \ set -e; for i in [a-z][a-z0-9]*.c; do \
@ -1214,13 +1204,6 @@ ip_match.o: mymalloc.h
ip_match.o: sys_defs.h ip_match.o: sys_defs.h
ip_match.o: vbuf.h ip_match.o: vbuf.h
ip_match.o: vstring.h ip_match.o: vstring.h
ip_lmatch.o: ip_lmatch.c
ip_lmatch.o: ip_lmatch.h
ip_lmatch.o: msg.h
ip_lmatch.o: mymalloc.h
ip_lmatch.o: sys_defs.h
ip_lmatch.o: vbuf.h
ip_lmatch.o: vstring.h
killme_after.o: killme_after.c killme_after.o: killme_after.c
killme_after.o: killme_after.h killme_after.o: killme_after.h
killme_after.o: sys_defs.h killme_after.o: sys_defs.h

View File

@ -1,450 +0,0 @@
/*++
/* NAME
/* ip_lmatch 3
/* SUMMARY
/* lazy IP address pattern matching
/* SYNOPSIS
/* #include <ip_lmatch.h>
/*
/* int ip_lmatch(pattern, addr, why)
/* char *pattern;
/* const char *addr;
/* VSTRING **why;
/* DESCRIPTION
/* This module supports IP address pattern matching. See below
/* for a description of the supported address pattern syntax.
/*
/* This version optimizes for implementation convenience. The
/* lazy parser stops as soon as the address does not match the
/* pattern. This results in a poor user interface: a pattern
/* syntax error at the end will be reported ONLY when an address
/* matches the entire pattern before the syntax error.
/*
/* Use the ip_match() module for an implementation that has
/* separate parsing and matching stages. That implementation
/* reports a syntax error immediately, and provides faster
/* matching at the cost of a more complex programming interface.
/*
/* ip_lmatch_parse() matches the address bytes while parsing
/* the pattern, and terminates as soon as a non-match or syntax
/* error is found. The result is -1 in case of syntax error,
/* 0 in case of no match, 1 in case of a match.
/*
/* Arguments
/* .IP addr
/* Network address in printable form.
/* .IP pattern
/* Address pattern. This argument may be modified.
/* .IP why
/* Pointer to storage for error reports (result value -1). If
/* the target is a null pointer, ip_lmatch() will allocate a
/* buffer that should be freed by the application.
/* IPV4 PATTERN SYNTAX
/* .ad
/* .fi
/* An IPv4 address pattern has four fields separated by ".".
/* Each field is either a decimal number, or a sequence inside
/* "[]" that contains one or more comma-separated decimal
/* numbers or number..number ranges.
/*
/* Examples of patterns are 1.2.3.4 (matches itself, as one
/* would expect) and 1.2.3.[2,4,6..8] (matches 1.2.3.2, 1.2.3.4,
/* 1.2.3.6, 1.2.3.7, 1.2.3.8).
/*
/* Thus, any pattern field can be a sequence inside "[]", but
/* a "[]" sequence cannot span multiple address fields, and
/* a pattern field cannot contain both a number and a "[]"
/* sequence at the same time.
/*
/* This means that the pattern 1.2.[3.4] is not valid (the
/* sequence [3.4] cannot span two address fields) and the
/* pattern 1.2.3.3[6..9] is also not valid (the last field
/* cannot be both number 3 and sequence [6..9] at the same
/* time).
/*
/* The syntax for IPv4 patterns is as follows:
/*
/* .in +5
/* v4pattern = v4field "." v4field "." v4field "." v4field
/* .br
/* v4field = v4octet | "[" v4sequence "]
/* .br
/* v4octet = any decimal number in the range 0 through 255
/* .br
/* v4sequence = v4seq_member | v4sequence "," v4seq_member
/* .br
/* v4seq_member = v4octet | v4octet ".." v4octet
/* .in
/* 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 <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <string.h>
/* Utility library. */
#include <msg.h>
#include <mymalloc.h>
#include <vstring.h>
#include <myaddrinfo.h>
#include <ip_lmatch.h>
/*
* Token values.
*/
#define IP_LMATCH_CODE_OPEN '[' /* start of set */
#define IP_LMATCH_CODE_CLOSE ']' /* end of set */
#define IP_LMATCH_CODE_OVAL 'N' /* octet value */
#define IP_LMATCH_CODE_EOF '\0' /* oops */
#define IP_LMATCH_CODE_ERR 256 /* oops */
/*
* Address length is protocol dependent. Find out how large our address byte
* strings should be.
*/
#ifdef HAS_IPV6
#define IP_LMATCH_ABYTES MAI_V6ADDR_BYTES
#else
#define IP_LMATCH_ABYTES MAI_V4ADDR_BYTES
#endif
/*
* SLMs.
*/
#define STR vstring_str
#define LEN VSTRING_LEN
/* ip_lmatch_next_token - carve out the next token from user input */
static int ip_lmatch_next_token(char **pstart, char **psaved_start, int *poval)
{
unsigned char *cp;
unsigned char *next;
int oval;
/*
* Return a value-less token (i.e. a literal, error, or EOF.
*/
#define IP_LMATCH_RETURN_TOK(next, type) \
do { *pstart = (char *) (next); return (type); } while (0)
/*
* Return a token that contains an IPv4 address octet value.
*/
#define IP_LMATCH_RETURN_TOK_OVAL(next, oval) do { \
*poval = (oval); IP_LMATCH_RETURN_TOK((next), IP_LMATCH_CODE_OVAL); \
} while (0)
/*
* Light-weight tokenizer. Each result is an IPv4 address octet value, a
* literal character value, error, or EOF.
*/
*psaved_start = *pstart;
cp = (unsigned char *) *pstart;
if (ISDIGIT(*cp)) {
oval = *cp - '0';
for (next = cp + 1; ISDIGIT(*next); next++) {
oval *= 10;
oval += *next - '0';
if (oval > 255)
IP_LMATCH_RETURN_TOK(next + 1, IP_LMATCH_CODE_ERR);
}
IP_LMATCH_RETURN_TOK_OVAL(next, oval);
} else {
IP_LMATCH_RETURN_TOK(*cp ? cp + 1 : cp, *cp);
}
}
/* ip_lmatch_print_parse_error - report parsing error in context */
static void PRINTFLIKE(5, 6) ip_lmatch_print_parse_error(VSTRING **why,
char *start,
char *here,
char *next,
const char *fmt,...)
{
va_list ap;
int start_width;
int here_width;
/*
* On-the-fly allocation.
*/
if (*why == 0)
*why = vstring_alloc(20);
/*
* Format the error type.
*/
va_start(ap, fmt);
vstring_vsprintf(*why, fmt, ap);
va_end(ap);
/*
* Format the error context. The syntax is complex enough that it is
* worth the effort to precisely indicate what input is in error.
*
* XXX Workaround for %.*s to avoid output when a zero width is specified.
*/
#define IP_LMATCH_NO_ERROR_CONTEXT (char *) 0, (char *) 0, (char *) 0
if (start != 0) {
start_width = here - start;
here_width = next - here;
vstring_sprintf_append(*why, " at \"%.*s>%.*s<%s\"",
start_width, start_width == 0 ? "" : start,
here_width, here_width == 0 ? "" : here, next);
}
}
/* ip_lmatch - match an address pattern */
int ip_lmatch(char *pattern, const char *addr, VSTRING **why)
{
const char *myname = "ip_lmatch";
char addr_bytes[IP_LMATCH_ABYTES];
const unsigned char *ap;
int octet_count;
char *saved_cp;
char *cp;
int token_type;
int look_ahead;
int oval;
int saved_oval;
int matched;
/*
* For now, IPv4 support only. Use different parser loops for IPv4 and
* IPv6.
*/
switch (inet_pton(AF_INET, addr, addr_bytes)) {
case -1:
msg_fatal("%s: address conversion error: %m", myname);
case 0:
msg_warn("%s: unexpected address form: %s", myname, addr);
return (0);
}
/*
* Simplify this if we change to {} for "octet set" notation.
*/
#define FIND_TERMINATOR(start, cp) do { \
int _level = 1; \
for (cp = (start) ; *cp; cp++) { \
if (*cp == '[') _level++; \
if (*cp != ']') continue; \
if (--_level == 0) break; \
} \
} while (0)
/*
* Strip [] around the entire pattern.
*/
if (*pattern == '[') {
FIND_TERMINATOR(pattern, cp);
if (cp[0] == 0) {
ip_lmatch_print_parse_error(why, IP_LMATCH_NO_ERROR_CONTEXT,
"missing \"]\" character");
return (-1);
}
if (cp[1] == 0) {
*cp = 0;
pattern += 1;
}
}
/*
* Sanity check. In this case we can't show any error context.
*/
if (*pattern == 0) {
ip_lmatch_print_parse_error(why, IP_LMATCH_NO_ERROR_CONTEXT,
"empty address pattern");
return (-1);
}
/*
* Simple on-the-fly pattern matching.
*/
octet_count = 0;
cp = pattern;
/*
* Require four address fields separated by ".", each field containing a
* numeric octet value or a sequence inside []. The loop head has no test
* and does not step the loop variable. The tokenizer advances the loop
* variable, and the loop termination logic is inside the loop.
*/
for (ap = (const unsigned char *) addr_bytes; /* void */ ; ap++) {
switch (token_type = ip_lmatch_next_token(&cp, &saved_cp, &oval)) {
/*
* Numeric address field.
*/
case IP_LMATCH_CODE_OVAL:
if (*ap == oval)
break;
return (0);
/*
* Wild-card address field.
*/
case IP_LMATCH_CODE_OPEN:
matched = 0;
/* Require comma-separated numbers or numeric ranges. */
for (;;) {
token_type = ip_lmatch_next_token(&cp, &saved_cp, &oval);
if (token_type == IP_LMATCH_CODE_OVAL) {
saved_oval = oval;
look_ahead = ip_lmatch_next_token(&cp, &saved_cp, &oval);
/* Numeric range. */
if (look_ahead == '.') {
/* Brute-force parsing. */
if (ip_lmatch_next_token(&cp, &saved_cp, &oval) == '.'
&& ip_lmatch_next_token(&cp, &saved_cp, &oval)
== IP_LMATCH_CODE_OVAL
&& saved_oval <= oval) {
if (!matched)
matched = (*ap >= saved_oval && *ap <= oval);
look_ahead =
ip_lmatch_next_token(&cp, &saved_cp, &oval);
} else {
ip_lmatch_print_parse_error(why, pattern,
saved_cp, cp,
"numeric range error");
return (-1);
}
}
/* Single number. */
else {
if (!matched)
matched = (*ap == oval);
}
/* Require "," or end-of-wildcard. */
token_type = look_ahead;
if (token_type == ',') {
continue;
} else if (token_type == IP_LMATCH_CODE_CLOSE) {
break;
} else {
ip_lmatch_print_parse_error(why, pattern, saved_cp, cp,
"need \",\" or \"%c\"",
IP_LMATCH_CODE_CLOSE);
return (-1);
}
} else {
ip_lmatch_print_parse_error(why, pattern, saved_cp, cp,
"need decimal number 0..255");
return (-1);
}
}
if (matched == 0)
return (0);
break;
/*
* Invalid field.
*/
default:
ip_lmatch_print_parse_error(why, pattern, saved_cp, cp,
"need decimal number 0..255 or \"%c\"",
IP_LMATCH_CODE_OPEN);
return (-1);
}
octet_count += 1;
/*
* Require four address fields. Not one more, not one less.
*/
if (octet_count == 4) {
if (*cp != 0) {
(void) ip_lmatch_next_token(&cp, &saved_cp, &oval);
ip_lmatch_print_parse_error(why, pattern, saved_cp, cp,
"garbage after pattern");
return (-1);
}
return (1);
}
/*
* Require "." before the next address field.
*/
if (ip_lmatch_next_token(&cp, &saved_cp, &oval) != '.') {
ip_lmatch_print_parse_error(why, pattern, saved_cp, cp,
"need \".\"");
return (-1);
}
}
}
#ifdef TEST
/*
* Dummy main program for regression tests.
*/
#include <sys/socket.h>
#include <stdlib.h>
#include <unistd.h>
#include <vstream.h>
#include <vstring_vstream.h>
#include <stringops.h>
int main(int argc, char **argv)
{
VSTRING *why = vstring_alloc(100);
VSTRING *line_buf = vstring_alloc(100);
char *bufp;
char *user_pattern;
char *user_address;
int echo_input = !isatty(0);
int match_status;
/*
* Iterate over the input stream. The input format is a pattern, followed
* by addresses to match against.
*/
while (vstring_fgets_nonl(line_buf, VSTREAM_IN)) {
bufp = STR(line_buf);
if (echo_input) {
vstream_printf("> %s\n", bufp);
vstream_fflush(VSTREAM_OUT);
}
if (*bufp == '#')
continue;
if ((user_pattern = mystrtok(&bufp, " \t")) == 0)
continue;
/*
* Match the patterns.
*/
while ((user_address = mystrtok(&bufp, " \t")) != 0) {
match_status = ip_lmatch(user_pattern, user_address, &why);
if (match_status < 0) {
vstream_printf("Error: %s\n", STR(why));
} else {
vstream_printf("Match %s: %s\n", user_address,
match_status ? "yes" : "no");
}
vstream_fflush(VSTREAM_OUT);
}
}
vstring_free(line_buf);
vstring_free(why);
exit(0);
}
#endif

View File

@ -1,35 +0,0 @@
#ifndef _IP_LMATCH_H_INCLUDED_
#define _IP_LMATCH_H_INCLUDED_
/*++
/* NAME
/* ip_lmatch 3h
/* SUMMARY
/* lazy IP address pattern matching
/* SYNOPSIS
/* #include <ip_lmatch.h>
/* DESCRIPTION
/* .nf
/*
* Utility library.
*/
#include <vstring.h>
/*
* External interface.
*/
extern int ip_lmatch(char *, const char *, VSTRING **);
/* 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
/*--*/
#endif

View File

@ -1,21 +0,0 @@
1.2.3.4 1.2.3.4
1.2.300.4 1.2.3.4
1.2.3. 1.2.3.4
1.2.3 1.2.3.4
a 1.2.3.4
1.2.3,4 1.2.3.4
1.2.[3].4 1.2.3.4
1.2.[].4 1.2.3.4
1.2.[.4 1.2.3.4
1.2.].4 1.2.3.4
1.2.[1..127,128..255].5 1.2.3.4
1.2.[1-255].5 1.2.3.4
1.2.[1..127.128..255].5 1.2.3.4
1.2.3.[4] 1.2.3.4
1.2.3.[4..1] 1.2.3.4
1.2.3.[4.1] 1.2.3.4
1.2.3.[4.x] 1.2.3.4
1.2.3.[x] 1.2.3.4
1.2.3.4x 1.2.3.4
1.2.[3..11].5 1.2.3.5 1.2.2.5 1.2.11.5 1.2.12.5 1.2.11.6
1.2.[3,5,7,9,11].5 1.2.3.5 1.2.2.5 1.2.4.5 1.2.11.5 1.2.12.5 1.2.11.6

View File

@ -1,51 +0,0 @@
> 1.2.3.4 1.2.3.4
Match 1.2.3.4: yes
> 1.2.300.4 1.2.3.4
Error: need decimal number 0..255 or "[" at "1.2.>300<.4"
> 1.2.3. 1.2.3.4
Error: need decimal number 0..255 or "[" at "1.2.3.><"
> 1.2.3 1.2.3.4
Error: need "." at "1.2.3><"
> a 1.2.3.4
Error: need decimal number 0..255 or "[" at ">a<"
> 1.2.3,4 1.2.3.4
Error: need "." at "1.2.3>,<4"
> 1.2.[3].4 1.2.3.4
Match 1.2.3.4: yes
> 1.2.[].4 1.2.3.4
Error: need decimal number 0..255 at "1.2.[>]<.4"
> 1.2.[.4 1.2.3.4
Error: need decimal number 0..255 at "1.2.[>.<4"
> 1.2.].4 1.2.3.4
Error: need decimal number 0..255 or "[" at "1.2.>]<.4"
> 1.2.[1..127,128..255].5 1.2.3.4
Match 1.2.3.4: no
> 1.2.[1-255].5 1.2.3.4
Error: need "," or "]" at "1.2.[1>-<255].5"
> 1.2.[1..127.128..255].5 1.2.3.4
Error: need "," or "]" at "1.2.[1..127>.<128..255].5"
> 1.2.3.[4] 1.2.3.4
Match 1.2.3.4: yes
> 1.2.3.[4..1] 1.2.3.4
Error: numeric range error at "1.2.3.[4..>1<]"
> 1.2.3.[4.1] 1.2.3.4
Error: numeric range error at "1.2.3.[4.>1<]"
> 1.2.3.[4.x] 1.2.3.4
Error: numeric range error at "1.2.3.[4.>x<]"
> 1.2.3.[x] 1.2.3.4
Error: need decimal number 0..255 at "1.2.3.[>x<]"
> 1.2.3.4x 1.2.3.4
Error: garbage after pattern at "1.2.3.4>x<"
> 1.2.[3..11].5 1.2.3.5 1.2.2.5 1.2.11.5 1.2.12.5 1.2.11.6
Match 1.2.3.5: yes
Match 1.2.2.5: no
Match 1.2.11.5: yes
Match 1.2.12.5: no
Match 1.2.11.6: no
> 1.2.[3,5,7,9,11].5 1.2.3.5 1.2.2.5 1.2.4.5 1.2.11.5 1.2.12.5 1.2.11.6
Match 1.2.3.5: yes
Match 1.2.2.5: no
Match 1.2.4.5: no
Match 1.2.11.5: yes
Match 1.2.12.5: no
Match 1.2.11.6: no

View File

@ -24,8 +24,8 @@
/* This module supports IP address pattern matching. See below /* This module supports IP address pattern matching. See below
/* for a description of the supported address pattern syntax. /* for a description of the supported address pattern syntax.
/* /*
/* This implementation aims to minimize the cost of translating /* This implementation aims to minimize the cost of encoding
/* the pattern to internal form, while still providing good /* the pattern in internal form, while still providing good
/* matching performance in the typical case. The first byte /* matching performance in the typical case. The first byte
/* of an encoded pattern specifies the expected address family /* of an encoded pattern specifies the expected address family
/* (for example, AF_INET); other details of the encoding are /* (for example, AF_INET); other details of the encoding are
@ -357,8 +357,8 @@ int ip_match_execute(const char *byte_codes, const char *addr_bytes)
static int ip_match_next_token(char **pstart, char **psaved_start, int *poval) static int ip_match_next_token(char **pstart, char **psaved_start, int *poval)
{ {
unsigned char *cp; unsigned char *cp;
unsigned char *next; int oval; /* octet value */
int oval; int type; /* token value */
/* /*
* Return a literal, error, or EOF token. Update the read pointer to the * Return a literal, error, or EOF token. Update the read pointer to the
@ -370,8 +370,8 @@ static int ip_match_next_token(char **pstart, char **psaved_start, int *poval)
/* /*
* Return a token that contains an IPv4 address octet value. * Return a token that contains an IPv4 address octet value.
*/ */
#define IP_MATCH_RETURN_TOK_OVAL(next, oval) do { \ #define IP_MATCH_RETURN_TOK_VAL(next, type, oval) do { \
*poval = (oval); IP_MATCH_RETURN_TOK((next), IP_MATCH_CODE_OVAL); \ *poval = (oval); IP_MATCH_RETURN_TOK((next), type); \
} while (0) } while (0)
/* /*
@ -382,13 +382,14 @@ static int ip_match_next_token(char **pstart, char **psaved_start, int *poval)
cp = (unsigned char *) *pstart; cp = (unsigned char *) *pstart;
if (ISDIGIT(*cp)) { if (ISDIGIT(*cp)) {
oval = *cp - '0'; oval = *cp - '0';
for (next = cp + 1; ISDIGIT(*next); next++) { type = IP_MATCH_CODE_OVAL;
for (cp += 1; ISDIGIT(*cp); cp++) {
oval *= 10; oval *= 10;
oval += *next - '0'; oval += *cp - '0';
if (oval > 255) if (oval > 255)
IP_MATCH_RETURN_TOK(next + 1, IP_MATCH_CODE_ERR); type = IP_MATCH_CODE_ERR;
} }
IP_MATCH_RETURN_TOK_OVAL(next, oval); IP_MATCH_RETURN_TOK_VAL(cp, type, oval);
} else { } else {
IP_MATCH_RETURN_TOK(*cp ? cp + 1 : cp, *cp); IP_MATCH_RETURN_TOK(*cp ? cp + 1 : cp, *cp);
} }

View File

@ -1,5 +1,6 @@
1.2.3.4 1.2.3.4
1.2.300.4 1.2.300.4
1.2.3000.4
1.2.3. 1.2.3.
1.2.3 1.2.3
a a

View File

@ -2,6 +2,8 @@
Code: 1.2.3.4 Code: 1.2.3.4
> 1.2.300.4 > 1.2.300.4
Error: need decimal number 0..255 or "[" at "1.2.>300<.4" Error: need decimal number 0..255 or "[" at "1.2.>300<.4"
> 1.2.3000.4
Error: need decimal number 0..255 or "[" at "1.2.>3000<.4"
> 1.2.3. > 1.2.3.
Error: need decimal number 0..255 or "[" at "1.2.3.><" Error: need decimal number 0..255 or "[" at "1.2.3.><"
> 1.2.3 > 1.2.3