]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.8-20110108
authorWietse Venema <wietse@porcupine.org>
Sat, 8 Jan 2011 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:36:54 +0000 (06:36 +0000)
43 files changed:
postfix/HISTORY
postfix/README_FILES/POSTSCREEN_README
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/html/POSTSCREEN_README.html
postfix/html/postconf.5.html
postfix/html/postscreen.8.html
postfix/html/smtpd.8.html
postfix/man/man5/postconf.5
postfix/man/man8/postscreen.8
postfix/man/man8/smtpd.8
postfix/mantools/postlink
postfix/proto/POSTSCREEN_README.html
postfix/proto/postconf.proto
postfix/src/global/Makefile.in
postfix/src/global/mail_conf.c
postfix/src/global/mail_conf.h
postfix/src/global/mail_params.h
postfix/src/global/mail_proto.h
postfix/src/global/mail_version.h
postfix/src/global/smtp_reply_footer.c [new file with mode: 0644]
postfix/src/global/smtp_reply_footer.h [new file with mode: 0644]
postfix/src/postscreen/Makefile.in
postfix/src/postscreen/postscreen.c
postfix/src/postscreen/postscreen.h
postfix/src/postscreen/postscreen_dict.c
postfix/src/postscreen/postscreen_early.c
postfix/src/postscreen/postscreen_expand.c [new file with mode: 0644]
postfix/src/postscreen/postscreen_send.c
postfix/src/postscreen/postscreen_smtpd.c
postfix/src/postscreen/postscreen_state.c
postfix/src/smtp/smtp_proto.c
postfix/src/smtpd/Makefile.in
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd.h
postfix/src/smtpd/smtpd_chat.c
postfix/src/smtpd/smtpd_expand.c
postfix/src/smtpd/smtpd_state.c
postfix/src/tls/tls_proxy.h
postfix/src/tls/tls_proxy_clnt.c
postfix/src/tls/tls_proxy_print.c
postfix/src/tls/tls_proxy_scan.c
postfix/src/tlsproxy/tlsproxy.c

index 214b50711a20d671a317963058888b7dd9569b95..29ce6f50fb14317055901dfe1568a028fc39d544 100644 (file)
@@ -16326,6 +16326,10 @@ Apologies for any names omitted.
        stress-dependent.  Files: global/mail_params.h,
        proto/postconf.proto.
 
+       Compatibility: postscreen_discard_ehlo_keyword(s|maps)
+       support for compatibility with smtpd_discard_ehlo_keyword(s|maps).
+       Files: postscreen/postscreen_smtpd.c.
+
 20110102
 
        Feature: STARTTLS support for the postscreen(8) daemon.
@@ -16353,7 +16357,7 @@ Apologies for any names omitted.
 20110104
 
        Feature: add contact information to each SMTP server reject
-       message. For example, "smtpd_reject_contact_information =
+       message. For example, "smtpd_reject_footer =
        call 800-555-0101 for assistance", with macro expansion and
        with multi-line support. Files: global/mail_params.h,
        mantools/postlink, proto/postconf.proto, smtpd/smtpd.c,
@@ -16370,3 +16374,35 @@ Apologies for any names omitted.
        Seen from outside, Postfix works just as if it has TLS
        support built into in smtpd(8). Files: smtpd/smtpd.c,
        tls/tls_proxy*.[hc], tlsproxy/tlsproxy.c, util/vstream.[hc].
+
+       Bugfix (introduced with the Postfix TLS patch): discard
+       plaintext following the STARTTLS command or response. This
+       matters only for the minority of SMTP clients that actually
+       verify server certificates.  Files: smtpd/smtpd.c,
+       smtp/smtp_proto.c.
+
+20110106:
+
+       Non-production: cleaned up the tlsproxy support in the
+       Postfix SMTP server for stress testing of the tlsproxy
+       daemon (still #ifdef TLSPROXY). File: smtpd/smtpd.c.
+
+20110107
+
+       Cleanup: smtpd_reject_contact_information is renamed to
+       smtpd_reject_footer, because it can be used for non-contact
+       information.
+
+       Compatibility: postscreen_reject_footer support for
+       compatibility with smtpd_reject_footer.  Files:
+       global/smtp_reply_footer.[hc], global/mail_conf.[hc],
+       postscreen/postscreen_expand.c, postscreen/postscreen_send.c,
+       postscreen/postscreen.c, smtpd/smtpd_chat.c.
+
+       Compatibility: postscreen_command_filter support for
+       compatibility with smtpd_command_filter. Files:
+       postscreen/postscreen_dict.c, postscreen/postscreen_smtpd.c
+
+       Cleanup: postscreen(8) now displays control characters in
+       PREGREET responses as C-style \letter escapes, instead of
+       "?".  File: postscreen/postscreen_early.c.
index 52ae2a09b2e3a4595db320dfa8beeafea5f101b5..aa794311918c5c7ddd52a3a1dc57ded3ebb35b49 100644 (file)
@@ -197,7 +197,8 @@ elapsed, postscreen(8) logs this as:
 Translation: the client at [address]:port sent count bytes before its turn to
 speak. This happened time seconds after the postscreen_greet_wait timer was
 started. The text is what the client sent (truncated to 100 bytes, and with
-non-printable characters replaced with "?").
+non-printable characters replaced with C-style escapes such as \r for carriage-
+return and \n for newline).
 
 The postscreen_greet_action parameter specifies the action that is taken next.
 See "When tests fail before the 220 SMTP server greeting" below.
index 59f0445f8fb908bbac851dc25b6c84516c8461f3..bb8ba6de5b71aebcf5f0c1b08d86c235d11decf0 100644 (file)
@@ -43,7 +43,7 @@ aren't logged to the maillog file, such as responses to syntax
 errors, or unsupported commands.
 
 Example:
-   smtpd_reject_contact_information = For assistance, call 800-555-0101.
+   smtpd_reject_footer = For assistance, call 800-555-0101.
 
 Server response:
    550-5.5.1 <user@example> Recipient address rejected: User unknown
@@ -52,6 +52,10 @@ Server response:
 This feature supports macro expansion ($client_address, $localtime,
 etc.), as documented in the postconf(5) manpage.
 
+This feature is also supported as postscreen_reject_footer
+using the same setting as smtpd_reject_footer by
+default.
+
 Incompatibility with snapshot 20110102
 ======================================
 
index e243dcd866baeb01cc22eb9d482ec4d3d9d93924..510ae4ba878ac043458e5a3794099bc204f66ed2 100644 (file)
@@ -4,6 +4,21 @@ Wish list:
 
        Re-run "make depend" with all plugins enabled.
 
+       Make very clear in postscreen manpage and readme that this
+       program is not to be used against your own mail clients.
+
+       Test postscreen on Solaris.
+
+       match_list support that does not recompile CIDR patterns
+       on every call.
+
+       tlsproxy(8) should receive TLS preferences from postscreen(8)
+       and smtpd(8), instead of reading them from main.cf. This
+       means that many tlsproxy_ parameters become postscreen_
+       parameters. This also means that tls_server_init() must not
+       "validate" preferences that are supplied later at
+       tls_server_start() time, which was dubious design anyway.
+
        anvil rate limit for sasl_username.
 
        Encapsulate nbbio buffer access and update by tlsproxy.
@@ -29,9 +44,6 @@ Wish list:
        This would apply to postmaster notices and bounce messages
        (DKIM), and address verification (BATV).
 
-       Replace sscanf() numerical conversions by strto[dl]()
-       for better error reporting.
-
        As postscreen implements more ESMTP keywords, need to copy
        inter-operability features from smtpd to filter keywords
        and command syntax.
@@ -65,7 +77,7 @@ Wish list:
        the same cleanup_service value for receiving remote mail
        and for submitting postmaster problem reports. Do we need
        separate mumble_cleanup_service_name parameters for "inject",
-       "notify" and "forward" (with backwards compatinble defaults)?
+       "notify" and "forward" (with backwards compatible defaults)?
 
        IF/ENDIF support for CIDR tables.
 
index f9c4e5ae3ec1aea4230f3521f972c6e6ee38ac95..34ec3b5bab5c041bb423018ba1ab6d054dce3606 100644 (file)
@@ -269,7 +269,8 @@ an empty teaser banner: </p>
 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>
 is what the client sent (truncated to 100 bytes, and with non-printable
-characters replaced with "?"). </p>
+characters replaced with C-style escapes such as \r for carriage-return
+and \n for newline). </p>
 
 <p> The <a href="postconf.5.html#postscreen_greet_action">postscreen_greet_action</a> parameter specifies the action that
 is taken next.  See "<a href="#fail_before_220">When tests fail
index 3e7b683e6a70edf79c47ea830ad6a7fee45a66a8..817fbe3da933876d9595d74fdea22f5fc7ca3531 100644 (file)
@@ -6811,6 +6811,17 @@ and error commands.  </p>
 <p> This feature is available in Postfix 2.8.  </p>
 
 
+</DD>
+
+<DT><b><a name="postscreen_command_filter">postscreen_command_filter</a>
+(default: $<a href="postconf.5.html#smtpd_command_filter">smtpd_command_filter</a>)</b></DT><DD>
+
+<p> A mechanism to transform commands from remote SMTP clients.
+See <a href="postconf.5.html#smtpd_command_filter">smtpd_command_filter</a> for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="postscreen_command_time_limit">postscreen_command_time_limit</a>
@@ -7032,6 +7043,18 @@ for details.  </p>
 Preferably, use <a href="postconf.5.html#postscreen_tls_security_level">postscreen_tls_security_level</a> instead. </p>
 
 
+</DD>
+
+<DT><b><a name="postscreen_expansion_filter">postscreen_expansion_filter</a>
+(default: see "postconf -d" output)</b></DT><DD>
+
+<p> List of characters that are permitted in <a href="postconf.5.html#postscreen_reject_footer">postscreen_reject_footer</a>
+attribute expansions.  See <a href="postconf.5.html#smtpd_expansion_filter">smtpd_expansion_filter</a> for further
+details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="postscreen_forbidden_commands">postscreen_forbidden_commands</a>
@@ -7302,6 +7325,17 @@ receive a 421 reponse. </p>
 <p> This feature is available in Postfix 2.8. </p>
 
 
+</DD>
+
+<DT><b><a name="postscreen_reject_footer">postscreen_reject_footer</a>
+(default: $<a href="postconf.5.html#smtpd_reject_footer">smtpd_reject_footer</a>)</b></DT><DD>
+
+<p> Optional information that is appended after a 4XX or 5XX server
+response. See <a href="postconf.5.html#smtpd_reject_footer">smtpd_reject_footer</a> for further details.  </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="postscreen_tls_security_level">postscreen_tls_security_level</a>
@@ -13002,64 +13036,79 @@ Example:
 
 </DD>
 
-<DT><b><a name="smtpd_reject_contact_information">smtpd_reject_contact_information</a>
+<DT><b><a name="smtpd_reject_footer">smtpd_reject_footer</a>
 (default: empty)</b></DT><DD>
 
-<p> Optional contact information that is appended after each SMTP
-server 4XX or 5XX response. </p>
+<p> Optional information that is appended after each SMTP server
+4XX or 5XX response. </p>
 
 <p> Example: </p>
 
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    <a href="postconf.5.html#smtpd_reject_contact_information">smtpd_reject_contact_information</a> = For assistance, call 800-555-0101.
+    <a href="postconf.5.html#smtpd_reject_footer">smtpd_reject_footer</a> = For assistance, call 800-555-0101.
      Please provide the following information in your problem report:
-     time ($localtime) and client address ($client_address).
+     time ($localtime), client ($client_address) and server
+     ($server_name).
 </pre>
 
 <p> Server response: </p>
 
 <pre>
-550-5.5.1 &lt;user@example&gt; Recipient address rejected: User unknown
-550 5.5.1 For assistance, call 800-555-0101. Please provide the
-following information in your problem report: time (Jan 4 15:42:00)
-and client address (192.168.1.248).
+    550-5.5.1 &lt;user@example&gt; Recipient address rejected: User unknown
+    550 5.5.1 For assistance, call 800-555-0101. Please provide the
+    following information in your problem report: time (Jan 4 15:42:00),
+    client (192.168.1.248) and server (mail1.example.com).
 </pre>
 
-<p> Note: this text is meant to make it easier to find the Postfix
-logfile records for a failed SMTP session. The text itself is not
-logged to the Postfix server's maillog file. </p>
+<p> Note: the above text is meant to make it easier to find the
+Postfix logfile records for a failed SMTP session. The text itself
+is not logged to the Postfix SMTP server's maillog file. </p>
 
 <p> Be sure to keep the text as short as possible. Long text may
-be truncated before it is logged in the senders maillog file, or
-before it is returned to the sender in a delivery status notification.
-</p>
+be truncated before it is logged in the Postfix SMTP server's maillog
+file, or before it is returned to the sender in a delivery status
+notification.  </p>
 
 <p> This feature supports a limited number of $name attributes in
-the contact text. These are replaced by their current value for the
+the footer text. These are replaced by their current value for the
 SMTP session: </p>
 
 <dl>
 
-<dt> client_address </dt> <dd> Client IP address </dd>
-
-<dt> client_port </dt> <dd> Client TCP port </dd>
+<dt> <b>client_address</b> </dt> <dd> The Client IP address that
+is logged in the maillog file. </dd>
 
-<dt> localtime </dt> <dd> Server local time (Mmm dd hh:mm:ss) </dd>
+<dt> <b>client_port</b> </dt> <dd> The client TCP port that is
+logged in the maillog file. </dd>
 
-<dt> recipient </dt> <dd> The address in the RCPT TO command </dd>
+<dt> <b>localtime</b> </dt> <dd> The server local time (Mmm dd
+hh:mm:ss) that is logged in the maillog file. </dd>
 
-<dt> sender  </dt> <dd> The address in the MAIL FROM command </dd>
+<dt> <b>server_name</b> </dt> <dd> The server's <a href="postconf.5.html#myhostname">myhostname</a> value.
+This attribute is made available for sites with multiple MTAs
+(perhaps behind a load-balancer), where the server name can help
+the server support team to quickly find the right log files.  </dd>
 
 </dl>
 
-<p> For safety reasons, text that does not match $<a href="postconf.5.html#smtpd_expansion_filter">smtpd_expansion_filter</a>
-is censored. </p>
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> NOT SUPPORTED are other attributes such as sender, recipient,
+or <a href="postconf.5.html">main.cf</a> parameters.  </p>
 
-<p> This feature supports \n as a request for a line break in the
-contact text. Postfix automatically inserts after each line break
-the three-digit SMTP reply code (and optional enhanced status code)
-from the original Postfix reject message.  </p>
+<li> <p> For safety reasons, text that does not match
+$<a href="postconf.5.html#smtpd_expansion_filter">smtpd_expansion_filter</a> is censored. </p>
+
+</ul>
+
+<p> This feature supports the two-character sequence \n as a request
+for a line break in the footer text. Postfix automatically inserts
+after each line break the three-digit SMTP reply code (and optional
+enhanced status code) from the original Postfix reject message.
+</p>
 
 <p> This feature is available in Postfix 2.8 and later. </p>
 
index 4f7250d7e2a2e5412f53308706e7367afa9aa03b..41499a6cc764245e3b35fdbb3fdc1ae90be94672 100644 (file)
@@ -106,55 +106,59 @@ POSTSCREEN(8)                                                    POSTSCREEN(8)
        ter value is the empty string.
 
 <b>COMPATIBILITY CONTROLS</b>
+       <b><a href="postconf.5.html#postscreen_command_filter">postscreen_command_filter</a> ($<a href="postconf.5.html#smtpd_command_filter">smtpd_command_filter</a>)</b>
+              A  mechanism to transform commands from remote SMTP
+              clients.
+
        <b><a href="postconf.5.html#postscreen_discard_ehlo_keyword_address_maps">postscreen_discard_ehlo_keyword_address_maps</a>  ($<a href="postconf.5.html#smtpd_discard_ehlo_keyword_address_maps">smtpd_dis</a>-</b>
        <b><a href="postconf.5.html#smtpd_discard_ehlo_keyword_address_maps">card_ehlo_keyword_address_maps</a>)</b>
-              Lookup  tables,  indexed  by the remote SMTP client
-              address, with case insensitive lists of  EHLO  key-
-              words  (pipelining,  starttls, auth, etc.) that the
-              <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server will  not  send  in  the  EHLO
+              Lookup tables, indexed by the  remote  SMTP  client
+              address,  with  case insensitive lists of EHLO key-
+              words (pipelining, starttls, auth, etc.)  that  the
+              <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  server  will  not  send  in the EHLO
               response to a remote SMTP client.
 
        <b><a href="postconf.5.html#postscreen_discard_ehlo_keywords">postscreen_discard_ehlo_keywords</a> ($<a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_key</a>-</b>
        <b><a href="postconf.5.html#smtpd_discard_ehlo_keywords">words</a>)</b>
-              A  case insensitive list of EHLO keywords (pipelin-
-              ing, starttls, auth, etc.) that  the  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
-              server  will  not  send  in  the EHLO response to a
+              A case insensitive list of EHLO keywords  (pipelin-
+              ing,  starttls,  auth, etc.) that the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
+              server will not send in  the  EHLO  response  to  a
               remote SMTP client.
 
 <b>TRIAGE PARAMETERS</b>
        <b><a href="postconf.5.html#postscreen_bare_newline_action">postscreen_bare_newline_action</a> (ignore)</b>
-              The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes  when  an  SMTP
-              client  sends  a bare newline character, that is, a
+              The  action  that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
+              client sends a bare newline character, that  is,  a
               newline not preceded by carriage return.
 
        <b><a href="postconf.5.html#postscreen_bare_newline_enable">postscreen_bare_newline_enable</a> (no)</b>
-              Enable "bare newline" SMTP protocol  tests  in  the
+              Enable  "bare  newline"  SMTP protocol tests in the
               <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
 
        <b><a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> (ignore)</b>
-              The  action  that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
-              client  is   permanently   blacklisted   with   the
+              The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes  when  an  SMTP
+              client   is   permanently   blacklisted   with  the
               <a href="postconf.5.html#postscreen_blacklist_networks">postscreen_blacklist_networks</a> parameter.
 
        <b><a href="postconf.5.html#postscreen_blacklist_networks">postscreen_blacklist_networks</a> (empty)</b>
               Network addresses that are permanently blacklisted;
-              see the <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a>  parameter  for
+              see  the  <a href="postconf.5.html#postscreen_blacklist_action">postscreen_blacklist_action</a> parameter for
               possible actions.
 
        <b><a href="postconf.5.html#postscreen_disable_vrfy_command">postscreen_disable_vrfy_command</a> ($<a href="postconf.5.html#disable_vrfy_command">disable_vrfy_command</a>)</b>
-              Disable  the SMTP VRFY command in the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
+              Disable the SMTP VRFY command in the  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
               daemon.
 
        <b><a href="postconf.5.html#postscreen_dnsbl_action">postscreen_dnsbl_action</a> (ignore)</b>
-              The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes  when  an  SMTP
+              The  action  that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
               client's  combined  DNSBL  score  is  equal  to  or
-              greater than  a  threshold  (as  defined  with  the
+              greater  than  a  threshold  (as  defined  with the
               <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> and <a href="postconf.5.html#postscreen_dnsbl_threshold">postscreen_dnsbl_thresh</a>-
               <a href="postconf.5.html#postscreen_dnsbl_threshold">old</a> parameters).
 
        <b><a href="postconf.5.html#postscreen_dnsbl_reply_map">postscreen_dnsbl_reply_map</a> (empty)</b>
-              A mapping  from  actual  DNSBL  domain  name  which
-              includes  a  secret  password,  to the DNSBL domain
+              A  mapping  from  actual  DNSBL  domain  name which
+              includes a secret password,  to  the  DNSBL  domain
               name  that  postscreen  will  reply  with  when  it
               rejects mail.
 
@@ -163,16 +167,16 @@ POSTSCREEN(8)                                                    POSTSCREEN(8)
               weight factors.
 
        <b><a href="postconf.5.html#postscreen_dnsbl_threshold">postscreen_dnsbl_threshold</a> (1)</b>
-              The inclusive lower  bound  for  blocking  an  SMTP
+              The  inclusive  lower  bound  for  blocking an SMTP
               client,  based  on  its  combined  DNSBL  score  as
-              defined with the <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a>  parameter.
+              defined  with the <a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> parameter.
 
        <b><a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a> ($<a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a>)</b>
               List of commands that the <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server con-
               siders in violation of the SMTP protocol.
 
        <b><a href="postconf.5.html#postscreen_greet_action">postscreen_greet_action</a> (ignore)</b>
-              The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes  when  an  SMTP
+              The  action  that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
               client speaks before its turn within the time spec-
               ified with the <a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> parameter.
 
@@ -180,157 +184,162 @@ POSTSCREEN(8)                                                    POSTSCREEN(8)
               The  <i>text</i>  in  the  optional  "220-<i>text</i>..."  server
               response that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> sends ahead of the real
               Postfix SMTP server's "220 text..." response, in an
-              attempt  to  confuse  bad SMTP clients so that they
+              attempt to confuse bad SMTP clients  so  that  they
               speak before their turn (pre-greet).
 
        <b><a href="postconf.5.html#postscreen_greet_wait">postscreen_greet_wait</a> (${stress?2}${stress:6}s)</b>
               The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will wait for
-              an  SMTP  client to send a command before its turn,
-              and for DNS  blocklist  lookup  results  to  arrive
-              (default:  up  to  2  seconds under stress, up to 6
+              an SMTP client to send a command before  its  turn,
+              and  for  DNS  blocklist  lookup  results to arrive
+              (default: up to 2 seconds under  stress,  up  to  6
               seconds otherwise).
 
        <b><a href="postconf.5.html#postscreen_helo_required">postscreen_helo_required</a> ($<a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a>)</b>
-              Require that a remote SMTP  client  sends  HELO  or
+              Require  that  a  remote  SMTP client sends HELO or
               EHLO before commencing a MAIL transaction.
 
        <b><a href="postconf.5.html#postscreen_non_smtp_command_action">postscreen_non_smtp_command_action</a> (drop)</b>
-              The  action  that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
-              client sends non-SMTP commands  as  specified  with
+              The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes  when  an  SMTP
+              client  sends  non-SMTP  commands as specified with
               the <a href="postconf.5.html#postscreen_forbidden_commands">postscreen_forbidden_commands</a> parameter.
 
        <b><a href="postconf.5.html#postscreen_non_smtp_command_enable">postscreen_non_smtp_command_enable</a> (no)</b>
-              Enable    "non-SMTP    command"    tests   in   the
+              Enable   "non-SMTP   command"    tests    in    the
               <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
 
        <b><a href="postconf.5.html#postscreen_pipelining_action">postscreen_pipelining_action</a> (enforce)</b>
-              The action that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes  when  an  SMTP
-              client  sends  multiple commands instead of sending
-              one command and waiting for the server to  respond.
+              The  action  that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> takes when an SMTP
+              client sends multiple commands instead  of  sending
+              one  command and waiting for the server to respond.
 
        <b><a href="postconf.5.html#postscreen_pipelining_enable">postscreen_pipelining_enable</a> (no)</b>
-              Enable  "pipelining"  SMTP  protocol  tests  in the
+              Enable "pipelining"  SMTP  protocol  tests  in  the
               <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server.
 
        <b><a href="postconf.5.html#postscreen_whitelist_networks">postscreen_whitelist_networks</a> ($<a href="postconf.5.html#mynetworks">mynetworks</a>)</b>
               Network addresses that are permanently whitelisted,
-              and  that  will  not  be subjected to <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
+              and that will not  be  subjected  to  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
               checks.
 
        <b><a href="postconf.5.html#smtpd_service_name">smtpd_service_name</a> (smtpd)</b>
-              The internal service  that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  forwards
+              The  internal  service  that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> forwards
               allowed connections to.
 
 <b>CACHE CONTROLS</b>
        <b><a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a> (12h)</b>
-              The  amount  of  time  between  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> cache
+              The amount  of  time  between  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  cache
               cleanup runs.
 
        <b><a href="postconf.5.html#postscreen_cache_map">postscreen_cache_map</a> (btree:$<a href="postconf.5.html#data_directory">data_directory</a>/ps_cache)</b>
-              Persistent storage  for  the  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  server
+              Persistent  storage  for  the  <a href="postscreen.8.html"><b>postscreen</b>(8)</a> server
               decisions.
 
        <b><a href="postconf.5.html#postscreen_cache_retention_time">postscreen_cache_retention_time</a> (7d)</b>
               The amount of time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache an
-              expired temporary  whitelist  entry  before  it  is
+              expired  temporary  whitelist  entry  before  it is
               removed.
 
        <b><a href="postconf.5.html#postscreen_bare_newline_ttl">postscreen_bare_newline_ttl</a> (30d)</b>
-              The  amount  of  time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
-              results from a successful "bare newline" SMTP  pro-
+              The amount of time that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  will  cache
+              results  from a successful "bare newline" SMTP pro-
               tocol test.
 
        <b><a href="postconf.5.html#postscreen_dnsbl_ttl">postscreen_dnsbl_ttl</a> (1h)</b>
-              The  amount  of  time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
+              The amount of time that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  will  cache
               results from a successful DNS blocklist test.
 
        <b><a href="postconf.5.html#postscreen_greet_ttl">postscreen_greet_ttl</a> (1d)</b>
-              The amount of time that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  will  cache
+              The  amount  of  time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
               results from a successful PREGREET test.
 
        <b><a href="postconf.5.html#postscreen_non_smtp_command_ttl">postscreen_non_smtp_command_ttl</a> (30d)</b>
-              The  amount  of  time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
-              results from a successful  "non_smtp_command"  SMTP
+              The amount of time that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  will  cache
+              results  from  a successful "non_smtp_command" SMTP
               protocol test.
 
        <b><a href="postconf.5.html#postscreen_pipelining_ttl">postscreen_pipelining_ttl</a> (30d)</b>
-              The  amount  of  time that <a href="postscreen.8.html"><b>postscreen</b>(8)</a> will cache
-              results from a successful "pipelining" SMTP  proto-
+              The amount of time that  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>  will  cache
+              results  from a successful "pipelining" SMTP proto-
               col test.
 
 <b>RESOURCE CONTROLS</b>
        <b><a href="postconf.5.html#line_length_limit">line_length_limit</a> (2048)</b>
-              Upon  input,  long lines are chopped up into pieces
-              of at most this length; upon delivery,  long  lines
+              Upon input, long lines are chopped up  into  pieces
+              of  at  most this length; upon delivery, long lines
               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
+              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>
-              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
+              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
               engine.
 
        <b><a href="postconf.5.html#postscreen_command_time_limit">postscreen_command_time_limit</a> (${stress?10}${stress:300}s)</b>
-              The command "read" time limit  for  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s
+              The  command  "read" time limit for <a href="postscreen.8.html"><b>postscreen</b>(8)</a>'s
               built-in SMTP protocol engine.
 
        <b><a href="postconf.5.html#postscreen_post_queue_limit">postscreen_post_queue_limit</a> ($<a href="postconf.5.html#default_process_limit">default_process_limit</a>)</b>
-              The  number of clients that can be waiting for ser-
+              The number of clients that can be waiting for  ser-
               vice from a real SMTP server process.
 
        <b><a href="postconf.5.html#postscreen_pre_queue_limit">postscreen_pre_queue_limit</a> ($<a href="postconf.5.html#default_process_limit">default_process_limit</a>)</b>
-              The number of non-whitelisted clients that  can  be
-              waiting  for  a  decision whether they will receive
+              The  number  of non-whitelisted clients that can be
+              waiting for a decision whether  they  will  receive
               service from a real SMTP server process.
 
        <b><a href="postconf.5.html#postscreen_watchdog_timeout">postscreen_watchdog_timeout</a> (10s)</b>
-              How much time a <a href="postscreen.8.html"><b>postscreen</b>(8)</a> process may  take  to
-              respond  to  an SMTP client command or to perform a
+              How  much  time a <a href="postscreen.8.html"><b>postscreen</b>(8)</a> process may take to
+              respond to an SMTP client command or to  perform  a
               cache operation before it is terminated by a built-
               in watchdog timer.
 
 <b>STARTTLS CONTROLS</b>
        <b><a href="postconf.5.html#postscreen_tls_security_level">postscreen_tls_security_level</a> ($<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a>)</b>
-              The  SMTP  TLS security level for the <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
-              server; when a non-empty value is  specified,  this
+              The SMTP TLS security level for  the  <a href="postscreen.8.html"><b>postscreen</b>(8)</a>
+              server;  when  a non-empty value is specified, this
               overrides       the       obsolete       parameters
               <a href="postconf.5.html#postscreen_use_tls">postscreen_use_tls</a> and <a href="postconf.5.html#postscreen_enforce_tls">postscreen_enforce_tls</a>.
 
 <b>OBSOLETE STARTTLS SUPPORT CONTROLS</b>
-       These parameters  are  supported  for  compatibility  with
+       These  parameters  are  supported  for  compatibility with
        <a href="smtpd.8.html"><b>smtpd</b>(8)</a> legacy parameters.
 
        <b><a href="postconf.5.html#postscreen_use_tls">postscreen_use_tls</a> ($<a href="postconf.5.html#smtpd_use_tls">smtpd_use_tls</a>)</b>
-              Opportunistic  TLS:  announce  STARTTLS  support to
-              SMTP clients, but do not require that  clients  use
+              Opportunistic TLS:  announce  STARTTLS  support  to
+              SMTP  clients,  but do not require that clients use
               TLS encryption.
 
        <b><a href="postconf.5.html#postscreen_enforce_tls">postscreen_enforce_tls</a> ($<a href="postconf.5.html#smtpd_enforce_tls">smtpd_enforce_tls</a>)</b>
-              Mandatory  TLS:  announce  STARTTLS support to SMTP
-              clients, and require that clients use  TLS  encryp-
+              Mandatory TLS: announce STARTTLS  support  to  SMTP
+              clients,  and  require that clients use TLS encryp-
               tion.
 
+<b>TROUBLE SHOOTING CONTROLS</b>
+       <b><a href="postconf.5.html#postscreen_expansion_filter">postscreen_expansion_filter</a> (see 'postconf -d' output)</b>
+              List  of   characters   that   are   permitted   in
+              <a href="postconf.5.html#postscreen_reject_footer">postscreen_reject_footer</a> attribute expansions.
+
+       <b><a href="postconf.5.html#postscreen_reject_footer">postscreen_reject_footer</a> ($<a href="postconf.5.html#smtpd_reject_footer">smtpd_reject_footer</a>)</b>
+              Optional  information  that is appended after a 4XX
+              or 5XX server response.
+
 <b>MISCELLANEOUS CONTROLS</b>
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location  of  the Postfix <a href="postconf.5.html">main.cf</a> and
+              The default location of  the  Postfix  <a href="postconf.5.html">main.cf</a>  and
               <a href="master.5.html">master.cf</a> configuration files.
 
        <b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
-              The maximal number  of  digits  after  the  decimal
+              The  maximal  number  of  digits  after the decimal
               point when logging sub-second delay values.
 
        <b><a href="postconf.5.html#command_directory">command_directory</a> (see 'postconf -d' output)</b>
-              The  location  of  all  postfix administrative com-
+              The location of  all  postfix  administrative  com-
               mands.
 
-       <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
-              The time limit for sending or receiving information
-              over an internal communication channel.
-
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
               The  maximum  amount  of  time that an idle Postfix
               daemon process waits  for  an  incoming  connection
index 841eb9cbefcac4a8d3acd850dcec8ade66d8bb21..a7aa8245f71f5367a815e247d86e4783f25d2517 100644 (file)
@@ -647,9 +647,9 @@ SMTPD(8)                                                              SMTPD(8)
               The  list of error classes that are reported to the
               postmaster.
 
-       <b><a href="postconf.5.html#smtpd_reject_contact_information">smtpd_reject_contact_information</a> (empty)</b>
-              Optional contact information that is appended after
-              each SMTP server 4XX or 5XX response.
+       <b><a href="postconf.5.html#smtpd_reject_footer">smtpd_reject_footer</a> (empty)</b>
+              Optional information that is  appended  after  each
+              SMTP server 4XX or 5XX response.
 
        <b><a href="postconf.5.html#soft_bounce">soft_bounce</a> (no)</b>
               Safety net to keep mail queued that would otherwise
index 0258f573c6e9cb88eaf1f4fb3dfb049cba84abd0..9fcc06c530c3e5f201cb417197de2874869a7d4b 100644 (file)
@@ -3835,6 +3835,11 @@ no need to enforce separate limits on the number of junk commands
 and error commands.
 .PP
 This feature is available in Postfix 2.8.
+.SH postscreen_command_filter (default: $smtpd_command_filter)
+A mechanism to transform commands from remote SMTP clients.
+See smtpd_command_filter for further details.
+.PP
+This feature is available in Postfix 2.8 and later.
 .SH postscreen_command_time_limit (default: ${stress?10}${stress:300}s)
 The command "read" time limit for \fBpostscreen\fR(8)'s built-in SMTP
 protocol engine. This bounds the time to receive an entire command.
@@ -3994,6 +3999,12 @@ for details.
 .PP
 This feature is available in Postfix 2.8 and later.
 Preferably, use postscreen_tls_security_level instead.
+.SH postscreen_expansion_filter (default: see "postconf -d" output)
+List of characters that are permitted in postscreen_reject_footer
+attribute expansions.  See smtpd_expansion_filter for further
+details.
+.PP
+This feature is available in Postfix 2.8 and later.
 .SH postscreen_forbidden_commands (default: $smtpd_forbidden_commands)
 List of commands that the \fBpostscreen\fR(8) server considers in
 violation of the SMTP protocol. See smtpd_forbidden_commands for
@@ -4149,6 +4160,11 @@ process. When this queue is full, all non-whitelisted clients will
 receive a 421 reponse.
 .PP
 This feature is available in Postfix 2.8.
+.SH postscreen_reject_footer (default: $smtpd_reject_footer)
+Optional information that is appended after a 4XX or 5XX server
+response. See smtpd_reject_footer for further details.
+.PP
+This feature is available in Postfix 2.8 and later.
 .SH postscreen_tls_security_level (default: $smtpd_tls_security_level)
 The SMTP TLS security level for the \fBpostscreen\fR(8) server; when
 a non-empty value is specified, this overrides the obsolete parameters
@@ -8094,9 +8110,9 @@ smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
 .fi
 .ad
 .ft R
-.SH smtpd_reject_contact_information (default: empty)
-Optional contact information that is appended after each SMTP
-server 4XX or 5XX response.
+.SH smtpd_reject_footer (default: empty)
+Optional information that is appended after each SMTP server
+4XX or 5XX response.
 .PP
 Example:
 .PP
@@ -8104,9 +8120,10 @@ Example:
 .na
 .ft C
 /etc/postfix/main.cf:
-    smtpd_reject_contact_information = For assistance, call 800-555-0101.
+    smtpd_reject_footer = For assistance, call 800-555-0101.
      Please provide the following information in your problem report:
-     time ($localtime) and client address ($client_address).
+     time ($localtime), client ($client_address) and server
+     ($server_name).
 .fi
 .ad
 .ft R
@@ -8116,43 +8133,53 @@ Server response:
 .nf
 .na
 .ft C
-550-5.5.1 <user@example> Recipient address rejected: User unknown
-550 5.5.1 For assistance, call 800-555-0101. Please provide the
-following information in your problem report: time (Jan 4 15:42:00)
-and client address (192.168.1.248).
+    550-5.5.1 <user@example> Recipient address rejected: User unknown
+    550 5.5.1 For assistance, call 800-555-0101. Please provide the
+    following information in your problem report: time (Jan 4 15:42:00),
+    client (192.168.1.248) and server (mail1.example.com).
 .fi
 .ad
 .ft R
 .PP
-Note: this text is meant to make it easier to find the Postfix
-logfile records for a failed SMTP session. The text itself is not
-logged to the Postfix server's maillog file.
+Note: the above text is meant to make it easier to find the
+Postfix logfile records for a failed SMTP session. The text itself
+is not logged to the Postfix SMTP server's maillog file.
 .PP
 Be sure to keep the text as short as possible. Long text may
-be truncated before it is logged in the senders maillog file, or
-before it is returned to the sender in a delivery status notification.
+be truncated before it is logged in the Postfix SMTP server's maillog
+file, or before it is returned to the sender in a delivery status
+notification.
 .PP
 This feature supports a limited number of $name attributes in
-the contact text. These are replaced by their current value for the
+the footer text. These are replaced by their current value for the
 SMTP session:
-.IP "client_address"
-Client IP address
-.IP "client_port"
-Client TCP port
-.IP "localtime"
-Server local time (Mmm dd hh:mm:ss)
-.IP "recipient"
-The address in the RCPT TO command
-.IP "sender"
-The address in the MAIL FROM command
-.PP
-For safety reasons, text that does not match $smtpd_expansion_filter
-is censored.
-.PP
-This feature supports \en as a request for a line break in the
-contact text. Postfix automatically inserts after each line break
-the three-digit SMTP reply code (and optional enhanced status code)
-from the original Postfix reject message.
+.IP "\fBclient_address\fR"
+The Client IP address that
+is logged in the maillog file.
+.IP "\fBclient_port\fR"
+The client TCP port that is
+logged in the maillog file.
+.IP "\fBlocaltime\fR"
+The server local time (Mmm dd
+hh:mm:ss) that is logged in the maillog file.
+.IP "\fBserver_name\fR"
+The server's myhostname value.
+This attribute is made available for sites with multiple MTAs
+(perhaps behind a load-balancer), where the server name can help
+the server support team to quickly find the right log files.
+.PP
+Notes:
+.IP \(bu
+NOT SUPPORTED are other attributes such as sender, recipient,
+or main.cf parameters.
+.IP \(bu
+For safety reasons, text that does not match
+$smtpd_expansion_filter is censored.
+.PP
+This feature supports the two-character sequence \en as a request
+for a line break in the footer text. Postfix automatically inserts
+after each line break the three-digit SMTP reply code (and optional
+enhanced status code) from the original Postfix reject message.
 .PP
 This feature is available in Postfix 2.8 and later.
 .SH smtpd_reject_unlisted_recipient (default: yes)
index 67b09c982157dd086d94e25cdbe802b9eb199a3c..e6822c0bc84858fc9a5c6f2ff67d20f5f6122a30 100644 (file)
@@ -119,6 +119,8 @@ parameter value is the empty string.
 .nf
 .ad
 .fi
+.IP "\fBpostscreen_command_filter ($smtpd_command_filter)\fR"
+A mechanism to transform commands from remote SMTP clients.
 .IP "\fBpostscreen_discard_ehlo_keyword_address_maps ($smtpd_discard_ehlo_keyword_address_maps)\fR"
 Lookup tables, indexed by the remote SMTP client address, with
 case insensitive lists of EHLO keywords (pipelining, starttls, auth,
@@ -282,6 +284,17 @@ but do not require that clients use TLS encryption.
 .IP "\fBpostscreen_enforce_tls ($smtpd_enforce_tls)\fR"
 Mandatory TLS: announce STARTTLS support to SMTP clients, and
 require that clients use TLS encryption.
+.SH "TROUBLE SHOOTING CONTROLS"
+.na
+.nf
+.ad
+.fi
+.IP "\fBpostscreen_expansion_filter (see 'postconf -d' output)\fR"
+List of characters that are permitted in postscreen_reject_footer
+attribute expansions.
+.IP "\fBpostscreen_reject_footer ($smtpd_reject_footer)\fR"
+Optional information that is appended after a 4XX or 5XX server
+response.
 .SH "MISCELLANEOUS CONTROLS"
 .na
 .nf
@@ -295,9 +308,6 @@ The maximal number of digits after the decimal point when logging
 sub-second delay values.
 .IP "\fBcommand_directory (see 'postconf -d' output)\fR"
 The location of all postfix administrative commands.
-.IP "\fBipc_timeout (3600s)\fR"
-The time limit for sending or receiving information over an internal
-communication channel.
 .IP "\fBmax_idle (100s)\fR"
 The maximum amount of time that an idle Postfix daemon process waits
 for an incoming connection before terminating voluntarily.
index a4f7fd5ea84de8d5e26c5bd8ae2a09e52d0f5a69..005495efd70eac17b5ce750b6a292490668b7754 100644 (file)
@@ -527,9 +527,9 @@ before-queue content inspection by non_smtpd_milters, header_checks
 and body_checks.
 .IP "\fBnotify_classes (resource, software)\fR"
 The list of error classes that are reported to the postmaster.
-.IP "\fBsmtpd_reject_contact_information (empty)\fR"
-Optional contact information that is appended after each SMTP
-server 4XX or 5XX response.
+.IP "\fBsmtpd_reject_footer (empty)\fR"
+Optional information that is appended after each SMTP server
+4XX or 5XX response.
 .IP "\fBsoft_bounce (no)\fR"
 Safety net to keep mail queued that would otherwise be returned to
 the sender.
index e77614fe51c5d8a2f96202613f113b1c7774800e..96269579a765ec0e7724245644312fbaabdebf5c 100755 (executable)
@@ -666,7 +666,7 @@ while (<>) {
     s;\bsmtpd_tls_always_issue_session_ids\b;<a href="postconf.5.html#smtpd_tls_always_issue_session_ids">$&</a>;g;
     s;\bsmtpd_tls_wrappermode\b;<a href="postconf.5.html#smtpd_tls_wrappermode">$&</a>;g;
     s;\bsmtpd_use_tls\b;<a href="postconf.5.html#smtpd_use_tls">$&</a>;g;
-    s;\bsmtpd_reject_contact_information\b;<a href="postconf.5.html#smtpd_reject_contact_information">$&</a>;g;
+    s;\bsmtpd_reject_footer\b;<a href="postconf.5.html#smtpd_reject_footer">$&</a>;g;
     s;\btls_daemon_random_bytes\b;<a href="postconf.5.html#tls_daemon_random_bytes">$&</a>;g;
     s;\btls_daemon_random_source\b;<a href="postconf.5.html#tls_daemon_random_source">$&</a>;g;
     s;\btls_ran[-</Bb>]*\n* *[<Bb>]*dom_bytes\b;<a href="postconf.5.html#tls_random_bytes">$&</a>;g;
@@ -954,6 +954,9 @@ while (<>) {
     s;\bpostscreen_use_tls\b;<a href="postconf.5.html#postscreen_use_tls">$&</a>;g;
     s;\bpostscreen_discard_ehlo_keyword_address_maps\b;<a href="postconf.5.html#postscreen_discard_ehlo_keyword_address_maps">$&</a>;g;
     s;\bpostscreen_discard_ehlo_keywords\b;<a href="postconf.5.html#postscreen_discard_ehlo_keywords">$&</a>;g;
+    s;\bpostscreen_expansion_filter\b;<a href="postconf.5.html#postscreen_expansion_filter">$&</a>;g;
+    s;\bpostscreen_reject_footer\b;<a href="postconf.5.html#postscreen_reject_footer">$&</a>;g;
+    s;\bpostscreen_command_filter\b;<a href="postconf.5.html#postscreen_command_filter">$&</a>;g;
 
     s;\btlsproxy_watchdog_timeout\b;<a href="postconf.5.html#tlsproxy_watchdog_timeout">$&</a>;g;
     s;\btlsproxy_enforce_tls\b;<a href="postconf.5.html#tlsproxy_enforce_tls">$&</a>;g;
index e744ef554cf1060c28cc26554e256343dbf4049d..5adef75807f6dc69b38b0a037c609e41a8708f4a 100644 (file)
@@ -269,7 +269,8 @@ postscreen_greet_wait time has elapsed, postscreen(8) logs this as:
 bytes before its turn to speak. This happened <i>time</i> seconds
 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
-characters replaced with "?"). </p>
+characters replaced with C-style escapes such as \r for carriage-return
+and \n for newline). </p>
 
 <p> The postscreen_greet_action parameter specifies the action that
 is taken next.  See "<a href="#fail_before_220">When tests fail
index c39a711cc79f4672c91bce4e298eefa89a705567..2885e9807675d5442d52ad022874214c93634efb 100644 (file)
@@ -13822,62 +13822,99 @@ for further details. </p>
 
 <p> This feature is available in Postfix 2.8 and later. </p>
 
-%PARAM smtpd_reject_contact_information
+%PARAM smtpd_reject_footer
 
-<p> Optional contact information that is appended after each SMTP
-server 4XX or 5XX response. </p>
+<p> Optional information that is appended after each SMTP server
+4XX or 5XX response. </p>
 
 <p> Example: </p>
 
 <pre>
 /etc/postfix/main.cf:
-    smtpd_reject_contact_information = For assistance, call 800-555-0101.
+    smtpd_reject_footer = For assistance, call 800-555-0101.
      Please provide the following information in your problem report:
-     time ($localtime) and client address ($client_address).
+     time ($localtime), client ($client_address) and server
+     ($server_name).
 </pre>
 
 <p> Server response: </p>
 
 <pre>
-550-5.5.1 &lt;user@example&gt; Recipient address rejected: User unknown
-550 5.5.1 For assistance, call 800-555-0101. Please provide the
-following information in your problem report: time (Jan 4 15:42:00)
-and client address (192.168.1.248).
+    550-5.5.1 &lt;user@example&gt; Recipient address rejected: User unknown
+    550 5.5.1 For assistance, call 800-555-0101. Please provide the
+    following information in your problem report: time (Jan 4 15:42:00),
+    client (192.168.1.248) and server (mail1.example.com).
 </pre>
 
-<p> Note: this text is meant to make it easier to find the Postfix
-logfile records for a failed SMTP session. The text itself is not
-logged to the Postfix server's maillog file. </p>
+<p> Note: the above text is meant to make it easier to find the
+Postfix logfile records for a failed SMTP session. The text itself
+is not logged to the Postfix SMTP server's maillog file. </p>
 
 <p> Be sure to keep the text as short as possible. Long text may
-be truncated before it is logged in the senders maillog file, or
-before it is returned to the sender in a delivery status notification.
-</p>
+be truncated before it is logged in the Postfix SMTP server's maillog
+file, or before it is returned to the sender in a delivery status
+notification.  </p>
 
 <p> This feature supports a limited number of $name attributes in
-the contact text. These are replaced by their current value for the
+the footer text. These are replaced by their current value for the
 SMTP session: </p>
 
 <dl>
 
-<dt> client_address </dt> <dd> Client IP address </dd>
-
-<dt> client_port </dt> <dd> Client TCP port </dd>
+<dt> <b>client_address</b> </dt> <dd> The Client IP address that
+is logged in the maillog file. </dd>
 
-<dt> localtime </dt> <dd> Server local time (Mmm dd hh:mm:ss) </dd>
+<dt> <b>client_port</b> </dt> <dd> The client TCP port that is
+logged in the maillog file. </dd>
 
-<dt> recipient </dt> <dd> The address in the RCPT TO command </dd>
+<dt> <b>localtime</b> </dt> <dd> The server local time (Mmm dd
+hh:mm:ss) that is logged in the maillog file. </dd>
 
-<dt> sender  </dt> <dd> The address in the MAIL FROM command </dd>
+<dt> <b>server_name</b> </dt> <dd> The server's myhostname value.
+This attribute is made available for sites with multiple MTAs
+(perhaps behind a load-balancer), where the server name can help
+the server support team to quickly find the right log files.  </dd>
 
 </dl>
 
-<p> For safety reasons, text that does not match $smtpd_expansion_filter
-is censored. </p>
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> NOT SUPPORTED are other attributes such as sender, recipient,
+or main.cf parameters.  </p>
+
+<li> <p> For safety reasons, text that does not match
+$smtpd_expansion_filter is censored. </p>
+
+</ul>
+
+<p> This feature supports the two-character sequence \n as a request
+for a line break in the footer text. Postfix automatically inserts
+after each line break the three-digit SMTP reply code (and optional
+enhanced status code) from the original Postfix reject message.
+</p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM postscreen_expansion_filter see "postconf -d" output
+
+<p> List of characters that are permitted in postscreen_reject_footer
+attribute expansions.  See smtpd_expansion_filter for further
+details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
 
-<p> This feature supports \n as a request for a line break in the
-contact text. Postfix automatically inserts after each line break
-the three-digit SMTP reply code (and optional enhanced status code)
-from the original Postfix reject message.  </p>
+%PARAM postscreen_reject_footer $smtpd_reject_footer
+
+<p> Optional information that is appended after a 4XX or 5XX server
+response. See smtpd_reject_footer for further details.  </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM postscreen_command_filter $smtpd_command_filter
+
+<p> A mechanism to transform commands from remote SMTP clients.
+See smtpd_command_filter for further details. </p>
 
 <p> This feature is available in Postfix 2.8 and later. </p>
index 47ab4d16a77dcbe601b9478ecbef231e473d2ba1..4ee8d867784ae6fbe96133ae4868b31457441a11 100644 (file)
@@ -29,7 +29,8 @@ SRCS  = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
        user_acl.c valid_mailhost_addr.c verify.c verify_clnt.c \
        verp_sender.c wildcard_inet_addr.c xtext.c delivered_hdr.c \
        fold_addr.c header_body_checks.c mkmap_proxy.c data_redirect.c \
-       match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c
+       match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \
+       smtp_reply_footer.c
 OBJS   = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
        canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
        clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \
@@ -60,7 +61,8 @@ OBJS  = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
        user_acl.o valid_mailhost_addr.o verify.o verify_clnt.o \
        verp_sender.o wildcard_inet_addr.o xtext.o delivered_hdr.o \
        fold_addr.o header_body_checks.o mkmap_proxy.o data_redirect.o \
-       match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o
+       match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \
+       smtp_reply_footer.o
 HDRS   = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
        canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
        conv_time.h db_common.h debug_peer.h debug_process.h defer.h \
@@ -85,7 +87,7 @@ HDRS  = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
        trace.h user_acl.h valid_mailhost_addr.h verify.h verify_clnt.h \
        verp_sender.h wildcard_inet_addr.h xtext.h delivered_hdr.h \
        fold_addr.h header_body_checks.h data_redirect.h match_service.h \
-       addr_match_list.h
+       addr_match_list.h smtp_reply_footer.h
 TESTSRC        = rec2stream.c stream2rec.c recdump.c
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@@ -795,25 +797,8 @@ delivered_hdr.o: quote_822_local.h
 delivered_hdr.o: quote_flags.h
 delivered_hdr.o: rec_type.h
 delivered_hdr.o: record.h
-dict_ldap.o: ../../include/argv.h
-dict_ldap.o: ../../include/binhash.h
-dict_ldap.o: ../../include/dict.h
-dict_ldap.o: ../../include/match_list.h
-dict_ldap.o: ../../include/match_ops.h
-dict_ldap.o: ../../include/msg.h
-dict_ldap.o: ../../include/mymalloc.h
-dict_ldap.o: ../../include/name_code.h
-dict_ldap.o: ../../include/stringops.h
 dict_ldap.o: ../../include/sys_defs.h
-dict_ldap.o: ../../include/vbuf.h
-dict_ldap.o: ../../include/vstream.h
-dict_ldap.o: ../../include/vstring.h
-dict_ldap.o: cfg_parser.h
-dict_ldap.o: db_common.h
 dict_ldap.o: dict_ldap.c
-dict_ldap.o: dict_ldap.h
-dict_ldap.o: mail_conf.h
-dict_ldap.o: string_list.h
 dict_mysql.o: ../../include/sys_defs.h
 dict_mysql.o: dict_mysql.c
 dict_pgsql.o: ../../include/sys_defs.h
@@ -1444,15 +1429,7 @@ mime_state.o: mail_params.h
 mime_state.o: mime_state.c
 mime_state.o: mime_state.h
 mime_state.o: rec_type.h
-mkmap_cdb.o: ../../include/argv.h
-mkmap_cdb.o: ../../include/dict.h
-mkmap_cdb.o: ../../include/dict_cdb.h
-mkmap_cdb.o: ../../include/mymalloc.h
 mkmap_cdb.o: ../../include/sys_defs.h
-mkmap_cdb.o: ../../include/vbuf.h
-mkmap_cdb.o: ../../include/vstream.h
-mkmap_cdb.o: ../../include/vstring.h
-mkmap_cdb.o: mkmap.h
 mkmap_cdb.o: mkmap_cdb.c
 mkmap_db.o: ../../include/argv.h
 mkmap_db.o: ../../include/dict.h
@@ -1829,6 +1806,15 @@ sent.o: sent.c
 sent.o: sent.h
 sent.o: trace.h
 sent.o: verify.h
+smtp_reply_footer.o: ../../include/mac_expand.h
+smtp_reply_footer.o: ../../include/mac_parse.h
+smtp_reply_footer.o: ../../include/msg.h
+smtp_reply_footer.o: ../../include/sys_defs.h
+smtp_reply_footer.o: ../../include/vbuf.h
+smtp_reply_footer.o: ../../include/vstring.h
+smtp_reply_footer.o: dsn_util.h
+smtp_reply_footer.o: smtp_reply_footer.c
+smtp_reply_footer.o: smtp_reply_footer.h
 smtp_stream.o: ../../include/iostuff.h
 smtp_stream.o: ../../include/msg.h
 smtp_stream.o: ../../include/sys_defs.h
index c5d3d4321cb948aa399d9e296e1837f0aaea3b7f..1fc7847fcf72abdc5a99387978d3c448b49bc2ea 100644 (file)
@@ -22,6 +22,9 @@
 /*     const char *mail_conf_eval(string)
 /*     const char *string;
 /*
+/*     const char *mail_conf_eval_once(string)
+/*     const char *string;
+/*
 /*     const char *mail_conf_lookup_eval(name)
 /*     const char *name;
 /* DESCRIPTION
 /*     string argument. The result is volatile and should be copied
 /*     if it is to be used for any appreciable amount of time.
 /*
+/*     mail_conf_eval_once() non-recursively expands any $parameters
+/*     in the string argument. The result is volatile and should
+/*     be copied if it is to be used for any appreciable amount
+/*     of time.
+/*
 /*     mail_conf_lookup_eval() looks up the named parameter, and expands any
 /*     $parameters in the result. The result is volatile and should be
 /*     copied if it is to be used for any appreciable amount of time.
@@ -201,6 +209,15 @@ const char *mail_conf_eval(const char *string)
     return (dict_eval(CONFIG_DICT, string, RECURSIVE));
 }
 
+/* mail_conf_eval_once - expand one level of macros in string */
+
+const char *mail_conf_eval_once(const char *string)
+{
+#define NONRECURSIVE   0
+
+    return (dict_eval(CONFIG_DICT, string, NONRECURSIVE));
+}
+
 /* mail_conf_lookup - lookup named variable */
 
 const char *mail_conf_lookup(const char *name)
index 5c050921463e9a188bb0d06a3a6e14a905fb8f2c..ea6e8bd25f999da58b54a50003ef707de183d737 100644 (file)
@@ -40,6 +40,7 @@ extern void mail_conf_flush(void);
 extern void mail_conf_update(const char *, const char *);
 extern const char *mail_conf_lookup(const char *);
 extern const char *mail_conf_eval(const char *);
+extern const char *mail_conf_eval_once(const char *);
 extern const char *mail_conf_lookup_eval(const char *);
 
  /*
index c5644526bfb447592362906234b4ca7d15975cee..fa01c529340e802cc4ee8ff9b896ce69b5bca06a 100644 (file)
@@ -3423,6 +3423,18 @@ extern bool var_psc_disable_vrfy;
 #define DEF_PSC_CCONN_LIMIT    "$" VAR_SMTPD_CCONN_LIMIT
 extern int var_psc_cconn_limit;
 
+#define VAR_PSC_REJ_FOOTER     "postscreen_reject_footer"
+#define DEF_PSC_REJ_FOOTER     "$" VAR_SMTPD_REJ_FOOTER
+extern char *var_psc_rej_footer;
+
+#define VAR_PSC_EXP_FILTER     "postscreen_expansion_filter"
+#define DEF_PSC_EXP_FILTER     "$" VAR_SMTPD_EXP_FILTER
+extern char *var_psc_exp_filter;
+
+#define VAR_PSC_CMD_FILTER     "postscreen_command_filter"
+#define DEF_PSC_CMD_FILTER     ""
+extern char *var_psc_cmd_filter;
+
 #define VAR_DNSBLOG_DELAY      "dnsblog_reply_delay"
 #define DEF_DNSBLOG_DELAY      "0s"
 extern int var_dnsblog_delay;
@@ -3557,9 +3569,9 @@ extern bool var_tlsp_tls_set_sessid;
  /*
   * SMTPD "reject" contact info.
   */
-#define VAR_SMTPD_REJ_CONTACT  "smtpd_reject_contact_information"
-#define DEF_SMTPD_REJ_CONTACT  ""
-extern char *var_smtpd_rej_contact;
+#define VAR_SMTPD_REJ_FOOTER   "smtpd_reject_footer"
+#define DEF_SMTPD_REJ_FOOTER   ""
+extern char *var_smtpd_rej_footer;
 
 /* LICENSE
 /* .ad
index 84e825473d5fe07ee28c8072eb10a72215cd9c46..d33f0ccb4b9f64a4987102164c0e1eea01761134 100644 (file)
@@ -254,6 +254,11 @@ extern char *mail_pathname(const char *, const char *);
 #define MAIL_ATTR_CIPHER_USEBITS       "cipher_usebits"
 #define MAIL_ATTR_CIPHER_ALGBITS       "cipher_algbits"
 
+ /*
+  * SMTP reply footer support.
+  */
+#define MAIL_ATTR_SERVER_NAME  "server_name"
+
 /* LICENSE
 /* .ad
 /* .fi
index ffb3e0e7e7e26c4f8fa39e497764ce05536b8bf6..e92f57391f28bcbea91cbd8b30093261f33f6abc 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20110105"
+#define MAIL_RELEASE_DATE      "20110108"
 #define MAIL_VERSION_NUMBER    "2.8"
 
 #ifdef SNAPSHOT
diff --git a/postfix/src/global/smtp_reply_footer.c b/postfix/src/global/smtp_reply_footer.c
new file mode 100644 (file)
index 0000000..5018a47
--- /dev/null
@@ -0,0 +1,166 @@
+/*++
+/* NAME
+/*     smtp_reply_footer 3
+/* SUMMARY
+/*     SMTP reply footer text support
+/* SYNOPSIS
+/*     #include <smtp_reply_footer.h>
+/*
+/*     int     smtp_reply_footer(buffer, start, template, filter,
+/*                                     lookup, context)
+/*     VSTRING *buffer;
+/*     ssize_t start;
+/*     char    *template;
+/*     const char *filter;
+/*     const char *(*lookup) (const char *name, char *context);
+/*     char    *context;
+/* DESCRIPTION
+/*     smtp_reply_footer() expands a reply template to an existing
+/*     reply text.
+/*
+/*     Arguments:
+/* .IP buffer
+/*     Result buffer. This should contain a properly formatted
+/*     one-line or multi-line SMTP reply, with or without the final
+/*     <CR><LF>. The reply code and optional enhanced status code
+/*     will be replicated in the footer text.  One space character
+/*     after the SMTP reply code is replaced by '-'. If the existing
+/*     reply ends in <CR><LF>, the result text will also end in
+/*     <CR><LF>.
+/* .IP start
+/*     The beginning of the SMTP reply that the footer will be
+/*     appended to. This supports applications that buffer up
+/*     multiple responses in one buffer.
+/* .IP template
+/*     Template text, with optional $name attributes that will be
+/*     expanded. The two-character sequence "\n" is replaced by a
+/*     line break followed by a copy of the original SMTP reply
+/*     code and optional enhanced status code.
+/* .IP filter
+/*     The set of characters that are allowed in attribute expansion.
+/* .IP lookup
+/*     Attribute name/value lookup function. The result value must
+/*     be a null for a name that is not found, otherwise a pointer
+/*     to null-terminated string.
+/* .IP context
+/*     Call-back context for the lookup function.
+/* SEE ALSO
+/*     mac_expand(3) macro expansion
+/* DIAGNOSTICS
+/*     smtp_reply_footer() returns 0 upon success, -1 if the
+/*     existing reply text is malformed.
+/*
+/*     Fatal errors: memory allocation problem.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <string.h>
+#include <ctype.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <vstring.h>
+
+/* Global library. */
+
+#include <dsn_util.h>
+#include <smtp_reply_footer.h>
+
+/* SLMs. */
+
+#define STR    vstring_str
+
+int     smtp_reply_footer(VSTRING *buffer, ssize_t start,
+                                 char *template,
+                                 const char *filter,
+                                 MAC_EXP_LOOKUP_FN lookup,
+                                 char *context)
+{
+    const char *myname = "smtp_reply_footer";
+    char   *cp;
+    char   *next;
+    char   *end;
+    ssize_t dsn_len;
+    int     crlf_at_end = 0;
+
+    /*
+     * Sanity check.
+     */
+    if (start < 0 || start > VSTRING_LEN(buffer))
+       msg_panic("%s: bad start: %ld", myname, (long) start);
+    if (*template == 0)
+       msg_panic("%s: empty template", myname);
+
+    /*
+     * Scan and patch the original response. If the response is not what we
+     * expect, we stop making changes.
+     */
+    for (cp = STR(buffer) + start, end = cp + strlen(cp);;) {
+       if (!ISDIGIT(cp[0]) || !ISDIGIT(cp[1]) || !ISDIGIT(cp[2])
+           || (cp[3] != ' ' && cp[3] != '-'))
+           return (-1);
+       cp[3] = '-';
+       if ((next = strstr(cp, "\r\n")) == 0) {
+           next = end;
+           break;
+       }
+       cp = next + 2;
+       if (cp == end) {
+           crlf_at_end = 1;
+           break;
+       }
+    }
+
+    /*
+     * Truncate text after the first null, and truncate the trailing CRLF.
+     */
+    if (next < vstring_end(buffer))
+       vstring_truncate(buffer, next - STR(buffer));
+
+    /*
+     * Append the footer text one line at a time. Caution: before we append
+     * parts from the buffer to itself, we must extend the buffer first,
+     * otherwise we would have a dangling pointer "read" bug.
+     */
+    dsn_len = dsn_valid(STR(buffer) + start + 4);
+    for (cp = template, end = cp + strlen(cp);;) {
+       if ((next = strstr(cp, "\\n")) != 0) {
+           *next = 0;
+       } else {
+           next = end;
+       }
+       /* Append a clone of the SMTP reply code. */
+       vstring_strcat(buffer, "\r\n");
+       VSTRING_SPACE(buffer, 3);
+       vstring_strncat(buffer, STR(buffer) + start, 3);
+       vstring_strcat(buffer, next != end ? "-" : " ");
+       /* Append a clone of the optional enhanced status code. */
+       if (dsn_len > 0) {
+           VSTRING_SPACE(buffer, dsn_len);
+           vstring_strncat(buffer, STR(buffer) + start + 4, (int) dsn_len);
+           vstring_strcat(buffer, " ");
+       }
+       /* Append one line of footer text. */
+       mac_expand(buffer, cp, MAC_EXP_FLAG_APPEND, filter, lookup, context);
+       if (next < end) {
+           *next = '\\';
+           cp = next + 2;
+       } else
+           break;
+    }
+    if (crlf_at_end)
+       vstring_strcat(buffer, "\r\n");
+    return (0);
+}
diff --git a/postfix/src/global/smtp_reply_footer.h b/postfix/src/global/smtp_reply_footer.h
new file mode 100644 (file)
index 0000000..6cb65f6
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _SMTP_REPLY_FOOTER_H_INCLUDED_
+#define _SMTP_REPLY_FOOTER_H_INCLUDED_
+
+/*++
+/* NAME
+/*     smtp_reply_footer 3h
+/* SUMMARY
+/*     SMTP reply footer text support
+/* SYNOPSIS
+/*     #include <smtp_reply_footer.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstring.h>
+#include <mac_expand.h>
+
+ /*
+  * External interface.
+  */
+extern int smtp_reply_footer(VSTRING *, ssize_t, char *, const char *,
+                                    MAC_EXP_LOOKUP_FN, char *);
+
+/* 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
index 615ebb8f8eada6594c6d05fda60d4703a6bd323b..013f0f7b49dfb8fc5d375fc813a80bd75f8f4b4d 100644 (file)
@@ -2,11 +2,11 @@ SHELL = /bin/sh
 SRCS   = postscreen.c postscreen_dict.c postscreen_dnsbl.c \
        postscreen_early.c postscreen_smtpd.c postscreen_misc.c \
        postscreen_state.c postscreen_tests.c postscreen_send.c \
-       postscreen_starttls.c
+       postscreen_starttls.c postscreen_expand.c
 OBJS   = postscreen.o postscreen_dict.o postscreen_dnsbl.o \
        postscreen_early.o postscreen_smtpd.o postscreen_misc.o \
        postscreen_state.o postscreen_tests.o postscreen_send.o \
-       postscreen_starttls.o
+       postscreen_starttls.o postscreen_expand.o
 HDRS   = 
 TESTSRC        =
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
@@ -78,6 +78,7 @@ postscreen.o: ../../include/mail_params.h
 postscreen.o: ../../include/mail_proto.h
 postscreen.o: ../../include/mail_server.h
 postscreen.o: ../../include/mail_version.h
+postscreen.o: ../../include/maps.h
 postscreen.o: ../../include/match_list.h
 postscreen.o: ../../include/match_ops.h
 postscreen.o: ../../include/msg.h
@@ -98,6 +99,7 @@ postscreen_dict.o: ../../include/dict.h
 postscreen_dict.o: ../../include/dict_cache.h
 postscreen_dict.o: ../../include/events.h
 postscreen_dict.o: ../../include/htable.h
+postscreen_dict.o: ../../include/maps.h
 postscreen_dict.o: ../../include/match_list.h
 postscreen_dict.o: ../../include/match_ops.h
 postscreen_dict.o: ../../include/msg.h
@@ -120,6 +122,7 @@ postscreen_dnsbl.o: ../../include/iostuff.h
 postscreen_dnsbl.o: ../../include/ip_match.h
 postscreen_dnsbl.o: ../../include/mail_params.h
 postscreen_dnsbl.o: ../../include/mail_proto.h
+postscreen_dnsbl.o: ../../include/maps.h
 postscreen_dnsbl.o: ../../include/match_list.h
 postscreen_dnsbl.o: ../../include/match_ops.h
 postscreen_dnsbl.o: ../../include/msg.h
@@ -141,6 +144,7 @@ postscreen_early.o: ../../include/dict_cache.h
 postscreen_early.o: ../../include/events.h
 postscreen_early.o: ../../include/htable.h
 postscreen_early.o: ../../include/mail_params.h
+postscreen_early.o: ../../include/maps.h
 postscreen_early.o: ../../include/match_list.h
 postscreen_early.o: ../../include/match_ops.h
 postscreen_early.o: ../../include/msg.h
@@ -153,6 +157,28 @@ postscreen_early.o: ../../include/vstream.h
 postscreen_early.o: ../../include/vstring.h
 postscreen_early.o: postscreen.h
 postscreen_early.o: postscreen_early.c
+postscreen_expand.o: ../../include/addr_match_list.h
+postscreen_expand.o: ../../include/argv.h
+postscreen_expand.o: ../../include/attr.h
+postscreen_expand.o: ../../include/dict.h
+postscreen_expand.o: ../../include/dict_cache.h
+postscreen_expand.o: ../../include/events.h
+postscreen_expand.o: ../../include/htable.h
+postscreen_expand.o: ../../include/iostuff.h
+postscreen_expand.o: ../../include/mail_params.h
+postscreen_expand.o: ../../include/mail_proto.h
+postscreen_expand.o: ../../include/maps.h
+postscreen_expand.o: ../../include/match_list.h
+postscreen_expand.o: ../../include/match_ops.h
+postscreen_expand.o: ../../include/msg.h
+postscreen_expand.o: ../../include/string_list.h
+postscreen_expand.o: ../../include/stringops.h
+postscreen_expand.o: ../../include/sys_defs.h
+postscreen_expand.o: ../../include/vbuf.h
+postscreen_expand.o: ../../include/vstream.h
+postscreen_expand.o: ../../include/vstring.h
+postscreen_expand.o: postscreen.h
+postscreen_expand.o: postscreen_expand.c
 postscreen_misc.o: ../../include/addr_match_list.h
 postscreen_misc.o: ../../include/argv.h
 postscreen_misc.o: ../../include/dict.h
@@ -162,6 +188,7 @@ postscreen_misc.o: ../../include/format_tv.h
 postscreen_misc.o: ../../include/htable.h
 postscreen_misc.o: ../../include/iostuff.h
 postscreen_misc.o: ../../include/mail_params.h
+postscreen_misc.o: ../../include/maps.h
 postscreen_misc.o: ../../include/match_list.h
 postscreen_misc.o: ../../include/match_ops.h
 postscreen_misc.o: ../../include/msg.h
@@ -180,10 +207,14 @@ postscreen_send.o: ../../include/dict_cache.h
 postscreen_send.o: ../../include/events.h
 postscreen_send.o: ../../include/htable.h
 postscreen_send.o: ../../include/iostuff.h
+postscreen_send.o: ../../include/mac_expand.h
+postscreen_send.o: ../../include/mac_parse.h
 postscreen_send.o: ../../include/mail_params.h
+postscreen_send.o: ../../include/maps.h
 postscreen_send.o: ../../include/match_list.h
 postscreen_send.o: ../../include/match_ops.h
 postscreen_send.o: ../../include/msg.h
+postscreen_send.o: ../../include/smtp_reply_footer.h
 postscreen_send.o: ../../include/string_list.h
 postscreen_send.o: ../../include/sys_defs.h
 postscreen_send.o: ../../include/vbuf.h
@@ -201,6 +232,7 @@ postscreen_smtpd.o: ../../include/events.h
 postscreen_smtpd.o: ../../include/htable.h
 postscreen_smtpd.o: ../../include/iostuff.h
 postscreen_smtpd.o: ../../include/is_header.h
+postscreen_smtpd.o: ../../include/lex_822.h
 postscreen_smtpd.o: ../../include/mail_params.h
 postscreen_smtpd.o: ../../include/mail_proto.h
 postscreen_smtpd.o: ../../include/maps.h
@@ -230,6 +262,7 @@ postscreen_starttls.o: ../../include/htable.h
 postscreen_starttls.o: ../../include/iostuff.h
 postscreen_starttls.o: ../../include/mail_params.h
 postscreen_starttls.o: ../../include/mail_proto.h
+postscreen_starttls.o: ../../include/maps.h
 postscreen_starttls.o: ../../include/match_list.h
 postscreen_starttls.o: ../../include/match_ops.h
 postscreen_starttls.o: ../../include/msg.h
@@ -256,6 +289,7 @@ postscreen_state.o: ../../include/htable.h
 postscreen_state.o: ../../include/iostuff.h
 postscreen_state.o: ../../include/mail_proto.h
 postscreen_state.o: ../../include/mail_server.h
+postscreen_state.o: ../../include/maps.h
 postscreen_state.o: ../../include/match_list.h
 postscreen_state.o: ../../include/match_ops.h
 postscreen_state.o: ../../include/msg.h
@@ -275,6 +309,7 @@ postscreen_tests.o: ../../include/dict_cache.h
 postscreen_tests.o: ../../include/events.h
 postscreen_tests.o: ../../include/htable.h
 postscreen_tests.o: ../../include/mail_params.h
+postscreen_tests.o: ../../include/maps.h
 postscreen_tests.o: ../../include/match_list.h
 postscreen_tests.o: ../../include/match_ops.h
 postscreen_tests.o: ../../include/msg.h
index 5809554612db9283a27d3c54fe4828dfa2faf7cb..cc7f3aa41859f2c523e6742eb6a872ddfb60b463 100644 (file)
 /* COMPATIBILITY CONTROLS
 /* .ad
 /* .fi
+/* .IP "\fBpostscreen_command_filter ($smtpd_command_filter)\fR"
+/*     A mechanism to transform commands from remote SMTP clients.
 /* .IP "\fBpostscreen_discard_ehlo_keyword_address_maps ($smtpd_discard_ehlo_keyword_address_maps)\fR"
 /*     Lookup tables, indexed by the remote SMTP client address, with
 /*     case insensitive lists of EHLO keywords (pipelining, starttls, auth,
 /* .IP "\fBpostscreen_enforce_tls ($smtpd_enforce_tls)\fR"
 /*     Mandatory TLS: announce STARTTLS support to SMTP clients, and
 /*     require that clients use TLS encryption.
+/* TROUBLE SHOOTING CONTROLS
+/* .ad
+/* .fi
+/* .IP "\fBpostscreen_expansion_filter (see 'postconf -d' output)\fR"
+/*     List of characters that are permitted in postscreen_reject_footer
+/*     attribute expansions.
+/* .IP "\fBpostscreen_reject_footer ($smtpd_reject_footer)\fR"
+/*     Optional information that is appended after a 4XX or 5XX server
+/*     response.
 /* MISCELLANEOUS CONTROLS
 /* .ad
 /* .fi
 /*     sub-second delay values.
 /* .IP "\fBcommand_directory (see 'postconf -d' output)\fR"
 /*     The location of all postfix administrative commands.
-/* .IP "\fBipc_timeout (3600s)\fR"
-/*     The time limit for sending or receiving information over an internal
-/*     communication channel.
 /* .IP "\fBmax_idle (100s)\fR"
 /*     The maximum amount of time that an idle Postfix daemon process waits
 /*     for an incoming connection before terminating voluntarily.
@@ -353,6 +361,9 @@ char   *var_smtpd_banner;
 bool    var_disable_vrfy_cmd;
 bool    var_helo_required;
 
+char   *var_smtpd_cmd_filter;
+char   *var_psc_cmd_filter;
+
 char   *var_smtpd_forbid_cmds;
 char   *var_psc_forbid_cmds;
 
@@ -410,9 +421,15 @@ int     var_psc_barlf_ttl;
 int     var_psc_cmd_count;
 char   *var_psc_cmd_time;
 
+char   *var_smtpd_rej_footer;
+char   *var_psc_rej_footer;
+
 int     var_smtpd_cconn_limit;
 int     var_psc_cconn_limit;
 
+char   *var_smtpd_exp_filter;
+char   *var_psc_exp_filter;
+
  /*
   * Global variables.
   */
@@ -835,6 +852,7 @@ static void post_jail_init(char *unused_name, char **unused_argv)
        0, -1,
     };
     int     cache_flags;
+    const char *tmp;
 
     /*
      * This routine runs after the skeleton code has entered the chroot jail.
@@ -843,6 +861,24 @@ static void post_jail_init(char *unused_name, char **unused_argv)
      */
     var_use_limit = 0;
 
+    /*
+     * Workaround for parameters whose values may contain "$", and that have
+     * a default of "$parametername". Not sure if it would be a good idea to
+     * always to this in the mail_conf_raw(3) module.
+     */
+    if (*var_psc_rej_footer == '$'
+       && mail_conf_lookup(var_psc_rej_footer + 1)) {
+       tmp = mail_conf_eval_once(var_psc_rej_footer);
+       myfree(var_psc_rej_footer);
+       var_psc_rej_footer = mystrdup(tmp);
+    }
+    if (*var_psc_exp_filter == '$'
+       && mail_conf_lookup(var_psc_exp_filter + 1)) {
+       tmp = mail_conf_eval_once(var_psc_exp_filter);
+       myfree(var_psc_exp_filter);
+       var_psc_exp_filter = mystrdup(tmp);
+    }
+
     /*
      * Other one-time initialization.
      */
@@ -952,6 +988,7 @@ int     main(int argc, char **argv)
        VAR_SMTPD_EHLO_DIS_WORDS, DEF_SMTPD_EHLO_DIS_WORDS, &var_smtpd_ehlo_dis_words, 0, 0,
        VAR_SMTPD_EHLO_DIS_MAPS, DEF_SMTPD_EHLO_DIS_MAPS, &var_smtpd_ehlo_dis_maps, 0, 0,
        VAR_SMTPD_TLS_LEVEL, DEF_SMTPD_TLS_LEVEL, &var_smtpd_tls_level, 0, 0,
+       VAR_SMTPD_CMD_FILTER, DEF_SMTPD_CMD_FILTER, &var_smtpd_cmd_filter, 0, 0,
        VAR_PSC_CACHE_MAP, DEF_PSC_CACHE_MAP, &var_psc_cache_map, 0, 0,
        VAR_PSC_PREGR_BANNER, DEF_PSC_PREGR_BANNER, &var_psc_pregr_banner, 0, 0,
        VAR_PSC_PREGR_ACTION, DEF_PSC_PREGR_ACTION, &var_psc_pregr_action, 1, 0,
@@ -968,6 +1005,7 @@ int     main(int argc, char **argv)
        VAR_PSC_EHLO_DIS_MAPS, DEF_PSC_EHLO_DIS_MAPS, &var_psc_ehlo_dis_maps, 0, 0,
        VAR_PSC_DNSBL_REPLY, DEF_PSC_DNSBL_REPLY, &var_psc_dnsbl_reply, 0, 0,
        VAR_PSC_TLS_LEVEL, DEF_PSC_TLS_LEVEL, &var_psc_tls_level, 0, 0,
+       VAR_PSC_CMD_FILTER, DEF_PSC_CMD_FILTER, &var_psc_cmd_filter, 0, 0,
        0,
     };
     static const CONFIG_INT_TABLE int_table[] = {
@@ -1007,6 +1045,10 @@ int     main(int argc, char **argv)
     };
     static const CONFIG_RAW_TABLE raw_table[] = {
        VAR_PSC_CMD_TIME, DEF_PSC_CMD_TIME, &var_psc_cmd_time, 1, 0,
+       VAR_SMTPD_REJ_FOOTER, DEF_SMTPD_REJ_FOOTER, &var_smtpd_rej_footer, 0, 0,
+       VAR_PSC_REJ_FOOTER, DEF_PSC_REJ_FOOTER, &var_psc_rej_footer, 0, 0,
+       VAR_SMTPD_EXP_FILTER, DEF_SMTPD_EXP_FILTER, &var_smtpd_exp_filter, 1, 0,
+       VAR_PSC_EXP_FILTER, DEF_PSC_EXP_FILTER, &var_psc_exp_filter, 1, 0,
        0,
     };
     static const CONFIG_NBOOL_TABLE nbool_table[] = {
index f5b894e3d93c5dbcadbafe28156796b0c422346a..74f35a30d0f859b5868135ec289ba7fc9146107a 100644 (file)
@@ -26,6 +26,7 @@
   */
 #include <addr_match_list.h>
 #include <string_list.h>
+#include <maps.h>
 
  /*
   * Preliminary stuff, to be fixed.
@@ -67,6 +68,7 @@ typedef struct {
     int     read_state;                        /* command read state machine */
     /* smtpd(8) compatibility */
     int     ehlo_discard_mask;         /* EHLO filter */
+    VSTRING *expand_buf;               /* macro expansion */
 } PSC_STATE;
 
 #define PSC_TIME_STAMP_NEW             (0)     /* test was never passed */
@@ -384,6 +386,8 @@ extern const char *psc_print_state_flags(int, const char *);
 extern int psc_addr_match_list_match(ADDR_MATCH_LIST *, const char *);
 extern const char *psc_cache_lookup(DICT_CACHE *, const char *);
 extern void psc_cache_update(DICT_CACHE *, const char *, const char *);
+const char *psc_dict_get(DICT *, const char *);
+const char *psc_maps_find(MAPS *, const char *, int);
 
  /*
   * postscreen_dnsbl.c
@@ -448,6 +452,13 @@ extern void psc_send_socket(PSC_STATE *);
   */
 extern void psc_starttls_open(PSC_STATE *, EVENT_NOTIFY_FN);
 
+ /*
+  * postscreen_expand.c
+  */
+extern VSTRING *psc_expand_filter;
+extern void psc_expand_init(void);
+extern const char *psc_expand_lookup(const char *, int, char *);
+
 /* LICENSE
 /* .ad
 /* .fi
index 92c0ba450167e3e991234e68dfe158ddd218a0f3..1db010251c7aca4af7ddab59c62b8fe9f865aa19 100644 (file)
 /*     DICT_CACHE *cache;
 /*     const char *key;
 /*     const char *value;
+/*
+/*     void    psc_dict_get(dict, key)
+/*     DICT    *dict;
+/*     const char *key;
+/*
+/*     void    psc_maps_find(maps, key, flags)
+/*     MAPS    *maps;
+/*     const char *key;
+/*     int     flags;
 /* DESCRIPTION
 /*     This module implements wrappers around time-critical table
 /*     access functions.  The functions log a warning when table
@@ -28,6 +37,9 @@
 /*
 /*     psc_cache_lookup() and psc_cache_update() are wrappers around
 /*     the corresponding dict_cache() methods.
+/*
+/*     psc_dict_get() and psc_maps_find() are wrappers around
+/*     dict_get() and maps_find(), respectively.
 /* LICENSE
 /* .ad
 /* .fi
 /* Utility library. */
 
 #include <msg.h>
+#include <dict.h>
+
+/* Global library. */
+
+#include <maps.h>
 
 /* Application-specific. */
 
@@ -105,3 +122,29 @@ void    psc_cache_update(DICT_CACHE *cache, const char *key, const char *value)
     dict_cache_update(cache, key, value);
     PSC_CHECK_TIME_AFTER_LOOKUP(dict_cache_name(cache), "update");
 }
+
+/* psc_dict_get - time-critical table lookup */
+
+const char *psc_dict_get(DICT *dict, const char *key)
+{
+    const char *myname = "psc_dict_get";
+    const char *result;
+
+    PSC_GET_TIME_BEFORE_LOOKUP;
+    result = dict_get(dict, key);
+    PSC_CHECK_TIME_AFTER_LOOKUP(dict->name, "lookup");
+    return (result);
+}
+
+/* psc_maps_find - time-critical table lookup */
+
+const char *psc_maps_find(MAPS *maps, const char *key, int flags)
+{
+    const char *myname = "psc_maps_find";
+    const char *result;
+
+    PSC_GET_TIME_BEFORE_LOOKUP;
+    result = maps_find(maps, key, flags);
+    PSC_CHECK_TIME_AFTER_LOOKUP(maps->title, "lookup");
+    return (result);
+}
index 807a0c9d506e63d2cce39e49073777bd9517b5de..cd77f5afd23081463024ac028efa9271fb79543e 100644 (file)
@@ -48,6 +48,7 @@
 #include <postscreen.h>
 
 static char *psc_teaser_greeting;
+static VSTRING *psc_escape_buf;
 
 /* psc_early_event - handle pre-greet, EOF, and DNSBL results. */
 
@@ -172,9 +173,10 @@ static void psc_early_event(int event, char *context)
            return;
        }
        read_buf[read_count] = 0;
+       escape(psc_escape_buf, read_buf, read_count);
        msg_info("PREGREET %d after %s from [%s]:%s: %.100s", read_count,
               psc_format_delta_time(psc_temp, state->start_time, &elapsed),
-                PSC_CLIENT_ADDR_PORT(state), printable(read_buf, '?'));
+                PSC_CLIENT_ADDR_PORT(state), STR(psc_escape_buf));
        PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_PREGR_FAIL);
        switch (psc_pregr_action) {
        case PSC_ACT_DROP:
@@ -288,5 +290,6 @@ void    psc_early_init(void)
     if (*var_psc_pregr_banner) {
        vstring_sprintf(psc_temp, "220-%s\r\n", var_psc_pregr_banner);
        psc_teaser_greeting = mystrdup(STR(psc_temp));
+       psc_escape_buf = vstring_alloc(100);
     }
 }
diff --git a/postfix/src/postscreen/postscreen_expand.c b/postfix/src/postscreen/postscreen_expand.c
new file mode 100644 (file)
index 0000000..24e6728
--- /dev/null
@@ -0,0 +1,141 @@
+/*++
+/* NAME
+/*     postscreen_expand 3
+/* SUMMARY
+/*     SMTP server macro expansion
+/* SYNOPSIS
+/*     #include <postscreen.h>
+/*
+/*     void    psc_expand_init()
+/*
+/*     VSTRING *psc_expand_filter;
+/*
+/*     const char *psc_expand_lookup(name, unused_mode, context)
+/*     const char *name;
+/*     int     unused_mode;
+/*     char    *context;
+/* DESCRIPTION
+/*     This module expands session-related macros.
+/*
+/*     psc_expand_init() performs one-time initialization
+/*     of the psc_expand_filter buffer.
+/*
+/*     The psc_expand_filter buffer contains the characters
+/*     that are allowed in macro expansion, as specified with the
+/*     psc_expand_filter configuration parameter.
+/*
+/*     psc_expand_lookup() returns the value of the named
+/*     macro or a null pointer.
+/*
+/*     Arguments:
+/* .IP name
+/*     Macro name.
+/* .IP context
+/*     Call-back context (a PSC_STATE pointer).
+/* DIAGNOSTICS
+/*     Panic: interface violations. Fatal errors: out of memory.
+/*     internal protocol errors. postscreen_expand() returns the
+/*     binary OR of MAC_PARSE_ERROR (syntax error) and MAC_PARSE_UNDEF
+/*     (undefined macro name).
+/* 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 <time.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <vstring.h>
+#include <stringops.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+#include <mail_proto.h>
+
+/* Application-specific. */
+
+#include <postscreen.h>
+
+ /*
+  * Pre-parsed expansion filter.
+  */
+VSTRING *psc_expand_filter;
+
+/* psc_expand_init - initialize once during process lifetime */
+
+void    psc_expand_init(void)
+{
+
+    /*
+     * Expand the expansion filter :-)
+     */
+    psc_expand_filter = vstring_alloc(10);
+    unescape(psc_expand_filter, var_psc_exp_filter);
+}
+
+/* psc_expand_lookup - generic SMTP attribute $name expansion */
+
+const char *psc_expand_lookup(const char *name, int unused_mode,
+                                       char *context)
+{
+    PSC_STATE *state = (PSC_STATE *) context;
+    time_t  now;
+    struct tm *lt;
+
+    if (state->expand_buf == 0)
+       state->expand_buf = vstring_alloc(10);
+
+    if (msg_verbose > 1)
+       msg_info("psc_expand_lookup: ${%s}", name);
+
+#define STREQ(x,y)    (*(x) == *(y) && strcmp((x), (y)) == 0)
+#define STREQN(x,y,n) (*(x) == *(y) && strncmp((x), (y), (n)) == 0)
+#define CONST_LEN(x)  (sizeof(x) - 1)
+
+    /*
+     * Don't query main.cf parameters, as the result of expansion could
+     * reveal system-internal information in server replies.
+     * 
+     * XXX: This said, multiple servers may be behind a single client-visible
+     * name or IP address, and each may generate its own logs. Therefore, it
+     * may be useful to expose the replying MTA id (myhostname) in the
+     * contact footer, to identify the right logs. So while we don't expose
+     * the raw configuration dictionary, we do expose "$myhostname" as
+     * expanded in var_myhostname.
+     * 
+     * Return NULL only for non-existent names.
+     */
+    if (STREQ(name, MAIL_ATTR_SERVER_NAME)) {
+       return (var_myhostname);
+    } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_ADDR)) {
+       return (state->smtp_client_addr);
+    } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_PORT)) {
+       return (state->smtp_client_port);
+    } if (STREQ(name, MAIL_ATTR_LOCALTIME)) {
+       if (time(&now) == (time_t) - 1)
+           msg_fatal("time lookup failed: %m");
+       lt = localtime(&now);
+       VSTRING_RESET(state->expand_buf);
+       do {
+           VSTRING_SPACE(state->expand_buf, 100);
+       } while (strftime(STR(state->expand_buf),
+                         vstring_avail(state->expand_buf),
+                         "%b %d %H:%M:%S", lt) == 0);
+       return (STR(state->expand_buf));
+    } else {
+       msg_warn("unknown macro name \"%s\" in expansion request", name);
+       return (0);
+    }
+}
index d74e6004982bad7a1d0fdb93f8da6cf63b659563..808afa69dd197cb5fe1ceaaa6fa6fd74cc3be64f 100644 (file)
@@ -58,6 +58,7 @@
 /* Global library. */
 
 #include <mail_params.h>
+#include <smtp_reply_footer.h>
 
 /* Application-specific. */
 
@@ -74,7 +75,7 @@
 
 int     psc_send_reply(PSC_STATE *state, const char *text)
 {
-    int     start;
+    ssize_t start;
     int     ret;
 
     if (msg_verbose)
@@ -87,6 +88,10 @@ int     psc_send_reply(PSC_STATE *state, const char *text)
      */
     start = VSTRING_LEN(state->send_buf);
     vstring_strcat(state->send_buf, text);
+    if (*var_psc_rej_footer && (*text == '4' || *text == '5'))
+       smtp_reply_footer(state->send_buf, start, var_psc_rej_footer,
+                          STR(psc_expand_filter), psc_expand_lookup,
+                          (char *) state);
 
     /*
      * XXX For soft_bounce support, it is not sufficient to fix replies here.
index 5384eb80e7c4077e8a763da5b73f47654d70abf9..377347eb8307e037f8b21f8cbe422d2ff5d70c33 100644 (file)
 #include <string_list.h>
 #include <maps.h>
 #include <ehlo_mask.h>
+#include <lex_822.h>
 
 /* TLS library. */
 
@@ -205,6 +206,11 @@ static void psc_smtpd_read_event(int, char *);
 static MAPS *psc_ehlo_discard_maps;
 static int psc_ehlo_discard_mask;
 
+ /*
+  * Command editing filter.
+  */
+static DICT *psc_cmd_filter;
+
  /*
   * Encapsulation. We must not forget turn off input/timer events when we
   * terminate the SMTP protocol engine.
@@ -319,8 +325,8 @@ static int psc_ehlo_cmd(PSC_STATE *state, char *args)
      * smtpd(8) compatibility: dynamic reply filtering.
      */
     if (psc_ehlo_discard_maps != 0
-       && (ehlo_words = maps_find(psc_ehlo_discard_maps,
-                                  state->smtp_client_addr, 0)) != 0
+       && (ehlo_words = psc_maps_find(psc_ehlo_discard_maps,
+                                      state->smtp_client_addr, 0)) != 0
        && (discard_mask = ehlo_mask(ehlo_words)) != psc_ehlo_discard_mask) {
        if (discard_mask && !(discard_mask & EHLO_MASK_SILENT))
            msg_info("[%s]%s: discarding EHLO keywords: %s",
@@ -348,13 +354,14 @@ static void psc_starttls_resume(int unused_event, char *context)
     PSC_STATE *state = (PSC_STATE *) context;
 
     /*
-     * Reset SMTP server state if STARTTLS was successful. Todo: reset SASL
-     * AUTH state. Dovecot responses may change when it knows that a
-     * connection is encrypted.
+     * Reset SMTP server state if STARTTLS was successful.
      */
     if (state->flags & PSC_STATE_FLAG_USING_TLS) {
        PSC_STRING_RESET(state->helo_name);
        PSC_STRING_RESET(state->sender);
+#ifdef TODO_SASL_AUTH
+       /* Reset SASL AUTH state. Dovecot responses may change. */
+#endif
     }
 
     /*
@@ -791,11 +798,28 @@ static void psc_smtpd_read_event(int event, char *context)
        }
 
        /*
-        * Terminate the command line, and reset the command buffer write
-        * pointer and state machine in preparation for the next command. For
-        * this to work as expected, VSTRING_RESET() must be non-destructive.
+        * Terminate the command buffer, and apply the last-resort command
+        * editing workaround.
         */
        VSTRING_TERMINATE(state->cmd_buffer);
+       if (psc_cmd_filter != 0) {
+           const char *cp;
+
+           for (cp = STR(state->cmd_buffer); *cp && IS_SPACE_TAB(*cp); cp++)
+                /* void */ ;
+           if ((cp = psc_dict_get(psc_cmd_filter, cp)) != 0) {
+               msg_info("[%s]:%s: replacing command \"%.100s\" with \"%.100s\"",
+                        state->smtp_client_addr, state->smtp_client_port,
+                        STR(state->cmd_buffer), cp);
+               vstring_strcpy(state->cmd_buffer, cp);
+           }
+       }
+
+       /*
+        * Reset the command buffer write pointer and state machine in
+        * preparation for the next command. For this to work as expected,
+        * VSTRING_RESET() must be non-destructive.
+        */
        state->read_state = PSC_SMTPD_CMD_ST_ANY;
        VSTRING_RESET(state->cmd_buffer);
 
@@ -1099,6 +1123,12 @@ void    psc_smtpd_init(void)
     vstring_sprintf(psc_temp, "421 %s Service unavailable - try again later\r\n",
                    var_myhostname);
     psc_smtpd_421_reply = mystrdup(STR(psc_temp));
+
+    /*
+     * Initialize the reply footer.
+     */
+    if (*var_psc_rej_footer)
+       psc_expand_init();
 }
 
 /* psc_smtpd_pre_jail_init - per-process deep protocol test initialization */
@@ -1113,8 +1143,16 @@ void    psc_smtpd_pre_jail_init(void)
      * 
      * XXX Bugger. This means we have to restart when the table changes!
      */
-    psc_ehlo_discard_maps = maps_create(VAR_PSC_EHLO_DIS_MAPS,
-                                       var_psc_ehlo_dis_maps,
-                                       DICT_FLAG_LOCK);
+    if (*var_psc_ehlo_dis_maps)
+       psc_ehlo_discard_maps = maps_create(VAR_PSC_EHLO_DIS_MAPS,
+                                           var_psc_ehlo_dis_maps,
+                                           DICT_FLAG_LOCK);
     psc_ehlo_discard_mask = ehlo_mask(var_psc_ehlo_dis_words);
+
+    /*
+     * Last-resort command editing support.
+     */
+    if (*var_psc_cmd_filter)
+       psc_cmd_filter = dict_open(var_psc_cmd_filter, O_RDONLY,
+                                  DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
 }
index 97ffae13240c8b89097431a3064d058153437c80..bb205d5e1bbe066a1a5d40568f02f7f29005f0e9 100644 (file)
@@ -165,6 +165,7 @@ PSC_STATE *psc_new_session_state(VSTREAM *stream,
     state->cmd_buffer = 0;
     state->read_state = 0;
     state->ehlo_discard_mask = 0;              /* XXX Should be ~0 */
+    state->expand_buf = 0;
 
     /*
      * Update the stress level.
@@ -225,6 +226,8 @@ void    psc_free_session_state(PSC_STATE *state)
        myfree(state->sender);
     if (state->cmd_buffer)
        vstring_free(state->cmd_buffer);
+    if (state->expand_buf)
+       vstring_free(state->expand_buf);
     myfree((char *) state);
 
     if (psc_check_queue_length < 0 || psc_post_queue_length < 0)
index c288a210cb985a31bbee6a787e7186f05f2f0c04..6a8750e3a688efb70abbb670a600c33aee685774 100644 (file)
@@ -849,6 +849,10 @@ static int smtp_start_tls(SMTP_STATE *state)
                                   SMTP_RESP_FAKE(&fake, "4.7.5"),
                                   "Server certificate not verified"));
 
+
+    /* At this point there must not be any pending plaintext. */
+    vstream_fpurge(session->stream, VSTREAM_PURGE_BOTH);
+
     /*
      * At this point we have to re-negotiate the "EHLO" to reget the
      * feature-list.
index 856e8b8e65167c35635d939a07e2cefb8cd43197..44792befbde62fdcffb2d318bf28ba695ebce090 100644 (file)
@@ -216,7 +216,6 @@ smtpd.o: smtpd_token.h
 smtpd_chat.o: ../../include/argv.h
 smtpd_chat.o: ../../include/attr.h
 smtpd_chat.o: ../../include/cleanup_user.h
-smtpd_chat.o: ../../include/dsn_util.h
 smtpd_chat.o: ../../include/int_filt.h
 smtpd_chat.o: ../../include/iostuff.h
 smtpd_chat.o: ../../include/line_wrap.h
@@ -236,6 +235,7 @@ smtpd_chat.o: ../../include/name_mask.h
 smtpd_chat.o: ../../include/post_mail.h
 smtpd_chat.o: ../../include/rec_type.h
 smtpd_chat.o: ../../include/record.h
+smtpd_chat.o: ../../include/smtp_reply_footer.h
 smtpd_chat.o: ../../include/smtp_stream.h
 smtpd_chat.o: ../../include/stringops.h
 smtpd_chat.o: ../../include/sys_defs.h
index 0026c25712784054dfd59899ea6206a11b57d0c3..0ce3d8580eb14b569a70cdecef63061f55ca5663 100644 (file)
 /*     and body_checks.
 /* .IP "\fBnotify_classes (resource, software)\fR"
 /*     The list of error classes that are reported to the postmaster.
-/* .IP "\fBsmtpd_reject_contact_information (empty)\fR"
-/*     Optional contact information that is appended after each SMTP
-/*     server 4XX or 5XX response.
+/* .IP "\fBsmtpd_reject_footer (empty)\fR"
+/*     Optional information that is appended after each SMTP server
+/*     4XX or 5XX response.
 /* .IP "\fBsoft_bounce (no)\fR"
 /*     Safety net to keep mail queued that would otherwise be returned to
 /*     the sender.
@@ -1187,7 +1187,7 @@ bool    var_smtpd_enforce_tls;
 bool    var_smtpd_tls_wrappermode;
 bool    var_smtpd_tls_auth_only;
 char   *var_smtpd_cmd_filter;
-char   *var_smtpd_rej_contact;
+char   *var_smtpd_rej_footer;
 
 #ifdef USE_TLS
 char   *var_smtpd_relay_ccerts;
@@ -3936,10 +3936,51 @@ static void chat_reset(SMTPD_STATE *state, int threshold)
 static void smtpd_start_tls(SMTPD_STATE *state)
 {
     int     rate;
+    int     cert_present;
+    int     requirecert;
+
+#ifdef USE_TLSPROXY
+
+    /*
+     * This is non-production code, for tlsproxy(8) load testing only. It
+     * implements enough to enable some Postfix features that depend on TLS
+     * encryption.
+     * 
+     * To insert tlsproxy(8) between this process and the SMTP client, we swap
+     * the file descriptors between the state->tlsproxy and state->client
+     * VSTREAMS, so that we don't lose all the user-configurable
+     * state->client attributes (such as longjump buffers or timeouts).
+     * 
+     * As we implement tlsproy support in the Postfix SMTP client we should
+     * develop a usable abstraction that encapsulates this stream plumbing in
+     * a library module.
+     */
+    vstream_control(state->tlsproxy, VSTREAM_CTL_DOUBLE, VSTREAM_CTL_END);
+    vstream_control(state->client, VSTREAM_CTL_SWAP_FD, state->tlsproxy,
+                   VSTREAM_CTL_END);
+    (void) vstream_fclose(state->tlsproxy);    /* direct-to-client stream! */
+    state->tlsproxy = 0;
+
+    /*
+     * After plumbing the plaintext stream, receive the TLS context object.
+     * For this we must use the same VSTREAM buffer that we also use to
+     * receive subsequent SMTP commands. The attribute protocol is robust
+     * enough that an adversary cannot inject their own bogus TLS context
+     * attributes into the stream.
+     */
+    state->tls_context = tls_proxy_context_receive(state->client);
+
+    /*
+     * XXX Maybe it is better to send this information to tlsproxy(8) when
+     * requesting service, effectively making a remote tls_server_start()
+     * call.
+     */
+    requirecert = (var_smtpd_tls_req_ccert && var_smtpd_enforce_tls);
+
+#else                                          /* USE_TLSPROXY */
     TLS_SERVER_START_PROPS props;
     static char *cipher_grade;
     static VSTRING *cipher_exclusions;
-    int     cert_present;
 
     /*
      * Wrapper mode uses a dedicated port and always requires TLS.
@@ -3976,20 +4017,23 @@ static void smtpd_start_tls(SMTPD_STATE *state)
      * Perform the TLS handshake now. Check the client certificate
      * requirements later, if necessary.
      */
+    requirecert = (var_smtpd_tls_req_ccert && var_smtpd_enforce_tls);
+
     state->tls_context =
        TLS_SERVER_START(&props,
                         ctx = smtpd_tls_ctx,
                         stream = state->client,
                         log_level = var_smtpd_tls_loglevel,
                         timeout = var_smtpd_starttls_tmout,
-                        requirecert = (var_smtpd_tls_req_ccert
-                                       && var_smtpd_enforce_tls),
+                        requirecert = requirecert,
                         serverid = state->service,
                         namaddr = state->namaddr,
                         cipher_grade = cipher_grade,
                         cipher_exclusions = STR(cipher_exclusions),
                         fpt_dgst = var_smtpd_tls_fpt_dgst);
 
+#endif                                         /* USE_TLSPROXY */
+
     /*
      * For new (i.e. not re-used) TLS sessions, increment the client's new
      * TLS session rate counter. We enforce the limit here only for human
@@ -4034,7 +4078,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
      * here. We have a usable TLS session with the client, so no need to
      * disable I/O, ...  we can even be polite and send "421 ...".
      */
-    if (props.requirecert && TLS_CERT_IS_TRUSTED(state->tls_context) == 0) {
+    if (requirecert && TLS_CERT_IS_TRUSTED(state->tls_context) == 0) {
 
        /*
         * Fetch and reject the next command (should be EHLO), then
@@ -4083,11 +4127,6 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
     const char *err;
     int     rate;
 
-#ifdef USE_TLSPROXY
-    VSTREAM *proxy_stream;
-
-#endif
-
     if (argc != 1) {
        state->error_mask |= MAIL_ERROR_PROTOCOL;
        smtpd_chat_reply(state, "501 5.5.4 Syntax: STARTTLS");
@@ -4117,14 +4156,32 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
        smtpd_chat_reply(state, "502 5.5.1 Error: command not implemented");
        return (-1);
     }
-#ifndef USE_TLS_PROXY
+#ifdef USE_TLSPROXY
+
+    /*
+     * Note: state->tlsproxy is left open when smtp_flush() calls longjmp(),
+     * so we garbage-collect the VSTREAM in smtpd_state_reset().
+     */
+#define PROXY_OPEN_FLAGS \
+       (TLS_PROXY_FLAG_ROLE_SERVER | TLS_PROXY_FLAG_SEND_CONTEXT)
+
+    state->tlsproxy = tls_proxy_open(PROXY_OPEN_FLAGS, state->client,
+                                    state->addr, state->port,
+                                    var_smtpd_tmout);
+    if (state->tlsproxy == 0) {
+       state->error_mask |= MAIL_ERROR_SOFTWARE;
+       /* RFC 4954 Section 6. */
+       smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
+       return (-1);
+    }
+#else                                          /* USE_TLSPROXY */
     if (smtpd_tls_ctx == 0) {
        state->error_mask |= MAIL_ERROR_SOFTWARE;
        /* RFC 4954 Section 6. */
        smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
        return (-1);
     }
-#endif
+#endif                                         /* USE_TLSPROXY */
 
     /*
      * Enforce TLS handshake rate limit when this client negotiated too many
@@ -4148,13 +4205,17 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
        smtpd_chat_reply(state,
                       "454 4.7.0 Error: too many new TLS sessions from %s",
                         state->namaddr);
+#ifdef USE_TLSPROXY
+       (void) vstream_fclose(state->tlsproxy);
+       state->tlsproxy = 0;
+#endif
        return (-1);
     }
-#ifndef USE_TLSPROXY
     smtpd_chat_reply(state, "220 2.0.0 Ready to start TLS");
-    /* Flush before we switch the stream's read/write routines. */
+    /* Flush before we switch read/write routines or file descriptors. */
     smtp_flush(state->client);
-    vstream_fpurge(state->client, VSTREAM_PURGE_READ); /* Yay! */
+    /* At this point there must not be any pending plaintext. */
+    vstream_fpurge(state->client, VSTREAM_PURGE_BOTH);
 
     /*
      * Reset all inputs to the initial state.
@@ -4172,73 +4233,6 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
      */
     smtpd_start_tls(state);
     return (0);
-#else                                          /* USE_TLSPROXY */
-
-    /*
-     * This is non-production code, for tlsproxy(8) load testing only. It
-     * implements enough to enable the Postfix features that depend on TLS
-     * encryption.
-     */
-#define PROXY_OPEN_FLAGS \
-       (TLS_PROXY_FLAG_ROLE_SERVER | TLS_PROXY_FLAG_SEND_CONTEXT)
-
-    proxy_stream = tls_proxy_open(PROXY_OPEN_FLAGS, state->client, state->addr,
-                                 state->port, var_smtpd_tmout);
-    if (proxy_stream == 0) {
-       state->error_mask |= MAIL_ERROR_SOFTWARE;
-       /* RFC 4954 Section 6. */
-       smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
-       return (-1);
-    }
-    smtpd_chat_reply(state, "220 2.0.0 Ready to start TLS");
-    smtp_flush(state->client);
-    vstream_fpurge(state->client, VSTREAM_PURGE_READ);
-
-    /*
-     * Reset all inputs to the initial state.
-     * 
-     * XXX RFC 2487 does not forbid the use of STARTTLS while mail transfer is
-     * in progress, so we have to allow it even when it makes no sense.
-     */
-    helo_reset(state);
-    mail_reset(state);
-    rcpt_reset(state);
-#ifdef USE_SASL_AUTH
-    if (var_smtpd_sasl_enable) {
-       if (smtpd_sasl_is_active(state)) {
-           smtpd_sasl_auth_reset(state);
-           smtpd_sasl_deactivate(state);
-       }
-       smtpd_sasl_activate(state, VAR_SMTPD_SASL_TLS_OPTS,
-                           var_smtpd_sasl_tls_opts);
-    }
-#endif
-
-    /*
-     * To insert tlsproxy(8) between this process and the SMTP client, we
-     * swap the file descriptors between the proxy_stream and state->client
-     * VSTREAMS, so that we don't have to worry about loss of all the
-     * user-configurable state->client attributes (such as longjump buffers).
-     */
-    vstream_control(proxy_stream, VSTREAM_CTL_DOUBLE, VSTREAM_CTL_END);
-    vstream_control(state->client, VSTREAM_CTL_SWAP_FD, proxy_stream,
-                   VSTREAM_CTL_END);
-    (void) vstream_fclose(proxy_stream);       /* direct-to-client stream! */
-
-    /*
-     * After plumbing the plaintext stream, receive the TLS context object.
-     * For this we must use the same VSTREAM buffer that we also use to
-     * receive subsequent SMTP commands.
-     * 
-     * When the TLS handshake fails, the conversation is in an unknown state.
-     * There is nothing we can do except to disconnect from the client.
-     */
-    state->tls_context = tls_proxy_state_receive(state->client);
-    if (state->tls_context == 0)
-       vstream_longjmp(state->client, SMTP_ERR_EOF);
-
-    return (0);
-#endif                                         /* USE_TLSPROXY */
 }
 
 /* tls_reset - undo STARTTLS */
@@ -4254,11 +4248,11 @@ static void tls_reset(SMTPD_STATE *state)
        if (vstream_feof(state->client) || vstream_ferror(state->client))
            failure = 1;
        vstream_fflush(state->client);          /* NOT: smtp_flush() */
-#ifndef USE_TLSPROXY
+#ifdef USE_TLSPROXY
+       tls_proxy_context_free(state->tls_context);
+#else
        tls_server_stop(smtpd_tls_ctx, state->client, var_smtpd_starttls_tmout,
                        failure, state->tls_context);
-#else
-       tls_proxy_state_free(state->tls_context);
 #endif
        state->tls_context = 0;
     }
@@ -4379,7 +4373,17 @@ static void smtpd_proto(SMTPD_STATE *state)
 #ifdef USE_TLS
        if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_tls_wrappermode) {
 #ifdef USE_TLSPROXY
-           msg_fatal("Wrapper-mode is unimplemented.");
+           /* We garbage-collect the VSTREAM in smtpd_state_reset() */
+           state->tlsproxy = tls_proxy_open(PROXY_OPEN_FLAGS, state->client,
+                                            state->addr, state->port,
+                                            var_smtpd_tmout);
+           if (state->tlsproxy == 0) {
+               msg_warn("Wrapper-mode request dropped from %s for service %s."
+                      " TLS context initialization failed. For details see"
+                        " earlier warnings in your logs.",
+                        state->namaddr, state->service);
+               break;
+           }
 #else                                          /* USE_TLSPROXY */
            if (smtpd_tls_ctx == 0) {
                msg_warn("Wrapper-mode request dropped from %s for service %s."
@@ -4388,6 +4392,7 @@ static void smtpd_proto(SMTPD_STATE *state)
                         state->namaddr, state->service);
                break;
            }
+#endif                                         /* USE_TLSPROXY */
            if (var_smtpd_cntls_limit > 0
                && !xclient_allowed
                && anvil_clnt
@@ -4401,7 +4406,6 @@ static void smtpd_proto(SMTPD_STATE *state)
                break;
            }
            smtpd_start_tls(state);
-#endif                                         /* USE_TLSPROXY */
        }
 #endif
 
@@ -4517,25 +4521,6 @@ static void smtpd_proto(SMTPD_STATE *state)
                smtp_flush(state->client);
 #endif
            } else {
-#ifdef PREGREET
-               if (*var_stress == 0 && strcmp(state->name, "unknown") == 0) {
-                   smtpd_chat_reply(state, "220-%s", var_smtpd_banner);
-                   smtp_flush(state->client);
-                   if (read_wait(vstream_fileno(state->client), 1) == 0) {
-                       int     n = peekfd(vstream_fileno(state->client));
-
-                       smtpd_chat_query(state);
-                       msg_info("PREGREET %d from %s: %s",
-                            n, state->namaddr, vstring_str(state->buffer));
-                       state->error_mask |= MAIL_ERROR_POLICY;
-                       smtpd_chat_reply(state,
-                                  "521 %s ESMTP not accepting connections",
-                                        var_myhostname);
-                       /* Not: state->error_count++; */
-                       break;
-                   }
-               }
-#endif
                smtpd_chat_reply(state, "220 %s", var_smtpd_banner);
            }
        }
@@ -4587,7 +4572,7 @@ static void smtpd_proto(SMTPD_STATE *state)
                for (cp = STR(state->buffer); *cp && IS_SPACE_TAB(*cp); cp++)
                     /* void */ ;
                if ((cp = dict_get(smtpd_cmd_filter, cp)) != 0) {
-                   msg_info("%s: replacing client command \"%s\" with \"%s\"",
+                   msg_info("%s: replacing command \"%.100s\" with \"%.100s\"",
                             state->namaddr, STR(state->buffer), cp);
                    vstring_strcpy(state->buffer, cp);
                }
@@ -4914,6 +4899,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
     if (getuid() == 0 || getuid() == var_owner_uid) {
        if (var_smtpd_use_tls) {
 #ifdef USE_TLS
+#ifndef USE_TLSPROXY
            TLS_SERVER_INIT_PROPS props;
            const char *cert_file;
            int     have_server_cert;
@@ -4980,6 +4966,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
                                    fpt_dgst = var_smtpd_tls_fpt_dgst);
            else
                msg_warn("No server certs available. TLS won't be enabled");
+#endif                                         /* USE_TLSPROXY */
 #else
            msg_warn("TLS has been selected, but TLS support is not compiled in");
 #endif
@@ -5260,7 +5247,7 @@ int     main(int argc, char **argv)
     static const CONFIG_RAW_TABLE raw_table[] = {
        VAR_SMTPD_EXP_FILTER, DEF_SMTPD_EXP_FILTER, &var_smtpd_exp_filter, 1, 0,
        VAR_DEF_RBL_REPLY, DEF_DEF_RBL_REPLY, &var_def_rbl_reply, 1, 0,
-       VAR_SMTPD_REJ_CONTACT, DEF_SMTPD_REJ_CONTACT, &var_smtpd_rej_contact, 0, 0,
+       VAR_SMTPD_REJ_FOOTER, DEF_SMTPD_REJ_FOOTER, &var_smtpd_rej_footer, 0, 0,
        0,
     };
 
index 9b98ac7d3a05d2ffde5806f8eaa3e49f11fd7b31..0ffa1ee41e9db1f06de69158b30844a129dfbcc2 100644 (file)
@@ -165,6 +165,9 @@ typedef struct {
      * TLS related state.
      */
 #ifdef USE_TLS
+#ifdef USE_TLSPROXY
+    VSTREAM *tlsproxy;                 /* tlsproxy(8) temp. handle */
+#endif
     TLS_SESS_STATE *tls_context;       /* TLS session state */
 #endif
 
index 72f17fd431c892a00c014d379270d5e2d86ac24a..da6e80ce657713896a50bab7d777fef83dbfc310 100644 (file)
@@ -83,7 +83,7 @@
 #include <mail_addr.h>
 #include <post_mail.h>
 #include <mail_error.h>
-#include <dsn_util.h>
+#include <smtp_reply_footer.h>
 
 /* Application-specific. */
 
@@ -147,7 +147,6 @@ void    smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
     char   *cp;
     char   *next;
     char   *end;
-    ssize_t dsn_len;
 
     /*
      * Slow down clients that make errors. Sleep-on-anything slows down
@@ -156,48 +155,16 @@ void    smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
     if (state->error_count >= var_smtpd_soft_erlim)
        sleep(delay = var_smtpd_err_sleep);
 
-    /*
-     * The caller may send multi-line text, so we can't assume that there is
-     * only one SMTP reply code at the beginning of the response.
-     */
     va_start(ap, format);
     vstring_vsprintf(state->buffer, format, ap);
     va_end(ap);
 
-    /*
-     * Append the optional contact footer. Caution: as we append parts from
-     * the buffer to itself, extend the buffer before updating it, or else we
-     * have a dangling pointer bug.
-     */
-    if (*var_smtpd_rej_contact
-       && (*(cp = STR(state->buffer)) == '4' || *cp == '5')
-       && ISDIGIT(cp[1]) && ISDIGIT(cp[2]) && cp[3] == ' ') {
-       dsn_len = dsn_valid(cp + 4);
-       for (cp = var_smtpd_rej_contact, end = cp + strlen(cp);;) {
-           if ((next = strstr(cp, "\\n")) != 0) {
-               *next = 0;
-           } else {
-               next = end;
-           }
-           /* Append a clone of the SMTP reply code. */
-           VSTRING_SPACE(state->buffer, sizeof("\r\n550 "));
-           vstring_sprintf_append(state->buffer, "\r\n%.3s ",
-                                  STR(state->buffer));
-           /* Append a clone of the optional enhanced status code. */
-           if (dsn_len > 0) {
-               VSTRING_SPACE(state->buffer, dsn_len + 1);
-               vstring_sprintf_append(state->buffer, "%.*s ",
-                                    (int) dsn_len, STR(state->buffer) + 4);
-           }
-           /* Append the actual contact information. */
-           smtpd_expand(state, state->buffer, cp, MAC_EXP_FLAG_APPEND);
-           if (next < end) {
-               *next = '\\';
-               cp = next + 2;
-           } else
-               break;
-       }
-    }
+    if (*var_smtpd_rej_footer
+       && (*(cp = STR(state->buffer)) == '4' || *cp == '5'))
+       smtp_reply_footer(state->buffer, 0, var_smtpd_rej_footer,
+                         STR(smtpd_expand_filter), smtpd_expand_lookup,
+                         (char *) state);
+
     /* All 5xx replies must have a 5.xx.xx detail code. */
     for (cp = STR(state->buffer), end = cp + strlen(STR(state->buffer));;) {
        if (var_soft_bounce) {
index 6683f4e0fb3d87d0feee89dee5879eb8cb2c29fe..06dfa1b048f5b8eaa5836c61a49d08270af69b98 100644 (file)
@@ -191,9 +191,18 @@ const char *smtpd_expand_lookup(const char *name, int unused_mode,
      * Don't query main.cf parameters, as the result of expansion could
      * reveal system-internal information in server replies.
      * 
+     * XXX: This said, multiple servers may be behind a single client-visible
+     * name or IP address, and each may generate its own logs. Therefore, it
+     * may be useful to expose the replying MTA id (myhostname) in the
+     * contact footer, to identify the right logs. So while we don't expose
+     * the raw configuration dictionary, we do expose "$myhostname" as
+     * expanded in var_myhostname.
+     * 
      * Return NULL only for non-existent names.
      */
-    if (STREQ(name, MAIL_ATTR_ACT_CLIENT)) {
+    if (STREQ(name, MAIL_ATTR_SERVER_NAME)) {
+       return (var_myhostname);
+    } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT)) {
        return (state->namaddr);
     } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_PORT)) {
        return (state->port);
index 8dc77a0b0fb07b58003e8a08ea790f357e3c3316..98f2f5b830a4102520ebb63709908dc0877208f1 100644 (file)
@@ -138,6 +138,9 @@ void    smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream,
     state->dsn_buf = vstring_alloc(100);
     state->dsn_orcpt_buf = vstring_alloc(100);
 #ifdef USE_TLS
+#ifdef USE_TLSPROXY
+    state->tlsproxy = 0;
+#endif
     state->tls_context = 0;
 #endif
 
@@ -208,4 +211,8 @@ void    smtpd_state_reset(SMTPD_STATE *state)
        vstring_free(state->dsn_buf);
     if (state->dsn_orcpt_buf)
        vstring_free(state->dsn_orcpt_buf);
+#if (defined(USE_TLS) && defined(USE_TLSPROXY))
+    if (state->tlsproxy)                       /* still open after longjmp */
+       vstream_fclose(state->tlsproxy);
+#endif
 }
index 3cf093a5148686f93d866ca1bd4b6fa9cb5264b7..fb80923237f423fb328c190d7eb60db457e8b4e9 100644 (file)
 
 extern VSTREAM *tls_proxy_open(int, VSTREAM *, const char *,
                                       const char *, int);
-extern TLS_SESS_STATE *tls_proxy_state_receive(VSTREAM *);
-extern void tls_proxy_state_free(TLS_SESS_STATE *);
-extern int tls_proxy_print_state(ATTR_SCAN_MASTER_FN, VSTREAM *, int, void *);
-extern int tls_proxy_scan_state(ATTR_SCAN_MASTER_FN, VSTREAM *, int, void *);
+extern TLS_SESS_STATE *tls_proxy_context_receive(VSTREAM *);
+extern void tls_proxy_context_free(TLS_SESS_STATE *);
+extern int tls_proxy_context_print(ATTR_PRINT_MASTER_FN, VSTREAM *, int, void *);
+extern int tls_proxy_context_scan(ATTR_SCAN_MASTER_FN, VSTREAM *, int, void *);
 
 #endif
 
index 9f723d21a538aa02b6ef2e1f39b0f93058062b5a..a6877975d3280e3f1cd57d5476b6b9812d5763a4 100644 (file)
 /*     const char *peer_port;
 /*     int     timeout;
 /*
-/*     TLS_SESS_STATE *tls_proxy_state_receive(proxy_stream)
+/*     TLS_SESS_STATE *tls_proxy_context_receive(proxy_stream)
 /*     VSTREAM *proxy_stream;
 /*
-/*     void    tls_proxy_state_free(tls_context)
+/*     void    tls_proxy_context_free(tls_context)
 /*     TLS_SESS_STATE *tls_context;
 /* DESCRIPTION
 /*     tls_proxy_open() prepares for inserting the tlsproxy(8)
 /*     buffer, timeout, etc.). Once the file descriptors are
 /*     swapped, the proxy stream should be closed.
 /*
-/*     tls_proxy_state_receive() receives the TLS context object
+/*     tls_proxy_context_receive() receives the TLS context object
 /*     for the named proxy stream. This function must be called
 /*     only if the TLS_PROXY_SEND_CONTEXT flag was specified in
 /*     the tls_proxy_open() call. Note that this TLS context object
 /*     is not compatible with tls_session_free(). It must be given
-/*     to tls_proxy_state_free() instead.
+/*     to tls_proxy_context_free() instead.
 /*
 /*     After this, the proxy_stream is ready for plain-text I/O.
 /*
-/*     tls_proxy_state_free() destroys a TLS context object that
-/*     was received with tls_proxy_state_receive().
+/*     tls_proxy_context_free() destroys a TLS context object that
+/*     was received with tls_proxy_context_receive().
 /*
 /*     Arguments:
 /* .IP flags
@@ -68,7 +68,7 @@
 /* .IP proxy_stream
 /*     Stream from tls_proxy_open().
 /* .IP tls_context
-/*     TLS session object from tls_proxy_state_receive().
+/*     TLS session object from tls_proxy_context_receive().
 /* LICENSE
 /* .ad
 /* .fi
@@ -188,27 +188,27 @@ VSTREAM *tls_proxy_open(int flags, VSTREAM *peer_stream,
     return (tlsproxy_stream);
 }
 
-/* tls_proxy_state_receive - receive TLS session object from tlsproxy(8) */
+/* tls_proxy_context_receive - receive TLS session object from tlsproxy(8) */
 
-TLS_SESS_STATE *tls_proxy_state_receive(VSTREAM *proxy_stream)
+TLS_SESS_STATE *tls_proxy_context_receive(VSTREAM *proxy_stream)
 {
     TLS_SESS_STATE *tls_context;
 
     tls_context = (TLS_SESS_STATE *) mymalloc(sizeof(*tls_context));
 
     if (attr_scan(proxy_stream, ATTR_FLAG_STRICT,
-                 ATTR_TYPE_FUNC, tls_proxy_scan_state, (char *) tls_context,
+                 ATTR_TYPE_FUNC, tls_proxy_context_scan, (char *) tls_context,
                  ATTR_TYPE_END) != 1) {
-       tls_proxy_state_free(tls_context);
+       tls_proxy_context_free(tls_context);
        return (0);
     } else {
        return (tls_context);
     }
 }
 
-/* tls_proxy_state_free - destroy object from tls_proxy_state_receive() */
+/* tls_proxy_context_free - destroy object from tls_proxy_context_receive() */
 
-void tls_proxy_state_free(TLS_SESS_STATE *tls_context)
+void tls_proxy_context_free(TLS_SESS_STATE *tls_context)
 {
     if (tls_context->peer_CN)
        myfree(tls_context->peer_CN);
index da759fdeb12357d9fdecade0197f0660064d2c32..36bfc112fc34f622a23d7334f6ea370b81455097 100644 (file)
@@ -6,18 +6,18 @@
 /* SYNOPSIS
 /*     #include <tls_proxy.h>
 /*
-/*     int     tls_proxy_print_state(print_fn, stream, flags, ptr)
+/*     int     tls_proxy_context_print(print_fn, stream, flags, ptr)
 /*     ATTR_PRINT_MASTER_FN print_fn;
 /*     VSTREAM *stream;
 /*     int     flags;
 /*     void    *ptr;
 /* DESCRIPTION
-/*     tls_proxy_print_state() writes a TLS_SESS_STATE structure
+/*     tls_proxy_context_print() writes a TLS_SESS_STATE structure
 /*     to the named stream using the specified attribute print
 /*     routine. TLS_SESS_STATE() is meant to be passed as a call-back
 /*     to attr_print(), thusly:
 /*
-/*     ... ATTR_TYPE_FUNC, tls_proxy_print_state, (void *) tls_context, ...
+/*     ... ATTR_TYPE_FUNC, tls_proxy_context_print, (void *) tls_context, ...
 /* DIAGNOSTICS
 /*     Fatal: out of memory.
 /* LICENSE
@@ -50,9 +50,9 @@
 #include <tls.h>
 #include <tls_proxy.h>
 
-/* tls_proxy_print_state - send TLS session state over stream */
+/* tls_proxy_context_print - send TLS session state over stream */
 
-int     tls_proxy_print_state(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
+int     tls_proxy_context_print(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
                                      int flags, void *ptr)
 {
     TLS_SESS_STATE *tp = (TLS_SESS_STATE *) ptr;
index c684727438aff2a3ba72bfef5e1e21b35fc2e029..fd562103681875fde6e1949352ab46371abb3176 100644 (file)
@@ -6,18 +6,18 @@
 /* SYNOPSIS
 /*     #include <tls_proxy.h>
 /*
-/*     int     tls_proxy_scan_state(scan_fn, stream, flags, ptr)
+/*     int     tls_proxy_context_scan(scan_fn, stream, flags, ptr)
 /*     ATTR_SCAN_MASTER_FN scan_fn;
 /*     VSTREAM *stream;
 /*     int     flags;
 /*     void    *ptr;
 /* DESCRIPTION
-/*     tls_proxy_scan_state() reads a TLS_SESS_STATE structure
+/*     tls_proxy_context_scan() reads a TLS_SESS_STATE structure
 /*     from the named stream using the specified attribute scan
-/*     routine.  tls_proxy_scan_state() is meant to be passed as
+/*     routine.  tls_proxy_context_scan() is meant to be passed as
 /*     a call-back to attr_scan(), thusly:
 /*
-/*     ... ATTR_TYPE_FUNC, tls_proxy_scan_state, (void *) tls_context, ...
+/*     ... ATTR_TYPE_FUNC, tls_proxy_context_scan, (void *) tls_context, ...
 /* DIAGNOSTICS
 /*     Fatal: out of memory.
 /* LICENSE
@@ -50,9 +50,9 @@
 #include <tls.h>
 #include <tls_proxy.h>
 
-/* tls_proxy_scan_state - receive TLS session state from stream */
+/* tls_proxy_context_scan - receive TLS session state from stream */
 
-int     tls_proxy_scan_state(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
+int     tls_proxy_context_scan(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
                                     int flags, void *ptr)
 {
     TLS_SESS_STATE *tls_context = (TLS_SESS_STATE *) ptr;
index 8786f29bfb88ec572a384ffc8b13bbddcec8d1f5..aefe438729db843bf9698c23e7f6f5c40788857b 100644 (file)
@@ -469,7 +469,7 @@ static void tlsp_strategy(TLSP_STATE *state)
        }
        if ((state->req_flags & TLS_PROXY_FLAG_SEND_CONTEXT) != 0
            && (attr_print(state->plaintext_stream, ATTR_FLAG_NONE,
-                          ATTR_TYPE_FUNC, tls_proxy_print_state,
+                          ATTR_TYPE_FUNC, tls_proxy_context_print,
                           (char *) state->tls_context, ATTR_TYPE_END) != 0
                || vstream_fflush(state->plaintext_stream) != 0)) {
            msg_warn("cannot send TLS context: %m");