]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.8-20110105
authorWietse Venema <wietse@porcupine.org>
Wed, 5 Jan 2011 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:36:52 +0000 (06:36 +0000)
38 files changed:
postfix/HISTORY
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/html/postconf.5.html
postfix/html/smtpd.8.html
postfix/man/man5/postconf.5
postfix/man/man8/smtpd.8
postfix/mantools/postlink
postfix/proto/postconf.proto
postfix/src/global/Makefile.in
postfix/src/global/mail_params.h
postfix/src/global/mail_proto.h
postfix/src/global/mail_version.h
postfix/src/postscreen/Makefile.in
postfix/src/postscreen/postscreen_smtpd.c
postfix/src/postscreen/postscreen_starttls.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_check.c
postfix/src/smtpd/smtpd_expand.c [new file with mode: 0644]
postfix/src/smtpd/smtpd_expand.h [new file with mode: 0644]
postfix/src/smtpd/smtpd_sasl_proto.c
postfix/src/smtpd/smtpd_state.c
postfix/src/tls/Makefile.in
postfix/src/tls/tls_proxy.h [new file with mode: 0644]
postfix/src/tls/tls_proxy_clnt.c [new file with mode: 0644]
postfix/src/tls/tls_proxy_print.c [new file with mode: 0644]
postfix/src/tls/tls_proxy_scan.c [new file with mode: 0644]
postfix/src/tlsproxy/Makefile.in
postfix/src/tlsproxy/tlsproxy.c
postfix/src/tlsproxy/tlsproxy.h
postfix/src/util/mac_expand.c
postfix/src/util/mac_expand.h
postfix/src/util/vstream.c
postfix/src/util/vstream.h
postfix/src/xsasl/Makefile.in

index 50274e0f3ab392e78e034ed1ff936736c9ef48a1..214b50711a20d671a317963058888b7dd9569b95 100644 (file)
@@ -16340,7 +16340,7 @@ Apologies for any names omitted.
        Roessner.  Files: util/nbbio.[hc], tlsproxy/*.[hc],
        postscreen/postscreen_starttlsd.c, postscreen/postscreen_smtpd.c.
 
-20101103
+20110103
 
        Cleanup: missing tls_level support in tlsproxy (it has no
        way to send plaintext, but perhaps an informative error
@@ -16349,3 +16349,24 @@ Apologies for any names omitted.
        Cleanup: simplified the handling of throttled output (i.e.
        output that can't be sent because the receiver tries to be
        nasty).  File: postscreen/postscreen_send.c.
+
+20110104
+
+       Feature: add contact information to each SMTP server reject
+       message. For example, "smtpd_reject_contact_information =
+       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,
+       smtpd/smtpd_chat.c, smtpd/smtpd_expand.[hc], util/mac_expand.[hc].
+
+20110105
+
+       Cleanup: the forest of TLS-related booleans was shrunk.
+       Victor Duchovni. Files: smtpd/smtpd.c, postscreen/postscreen.c,
+       postscreen/postscreen_smtpd.c, tlsproxy/tlsproxy.c.
+
+       Non-production: tlsproxy support in the Postfix SMTP server
+       for stress testing of the tlsproxy daemon (#ifdef TLSPROXY).
+       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].
index 3e87926871d2b8b915465b5f11c4be3ef7d96785..59f0445f8fb908bbac851dc25b6c84516c8461f3 100644 (file)
@@ -34,6 +34,24 @@ is the $name of an smtpd_xxx parameter with a stress-dependent
 default).  Other postscreen parameters always evaluate as if the
 stress value is equal to the empty string.
 
+Major changes with snapshot 20110105
+====================================
+
+The SMTP server now supports contact information that is appended
+to "reject" responses. This includes SMTP server responses that
+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.
+
+Server response:
+   550-5.5.1 <user@example> Recipient address rejected: User unknown
+   550 5.5.1 For assistance, call 800-555-0101.
+
+This feature supports macro expansion ($client_address, $localtime,
+etc.), as documented in the postconf(5) manpage.
+
 Incompatibility with snapshot 20110102
 ======================================
 
@@ -397,59 +415,6 @@ any checks on clients in mynetworks (primarily, to avoid problems
 with buggy SMTP implementations in network appliances).  The logging
 function alone is already useful for research.
 
-postscreen(8) can be configured to drop clients that start talking
-too soon, or clients that appear on DNS blocklists. For details,
-see below.
-
 postscreen(8) has been tested on FreeBSD and Linux systems.  It
 probably needs additional work before it can be used on Solaris.
 
-This snapshot adds three new entries to the master.cf file. 
-
-To enable the postscreen(8) service and log client information
-without blocking mail:
-
-1 - Comment out the "smtp  inet ... smtpd" service in master.cf,
-    including any "-o parameter=value" entries that follow.
-
-2 - Uncomment the new "smtpd pass ... smtpd" service in master.cf,
-    and duplicate any "-o parameter=value" entries from the smtpd
-    service that was commented out in step 1.
-
-3 - Uncomment the the new "smtp inet ... postscreen" service in
-    master.cf.
-
-4 - Uncomment the new "dnsblog  unix ... dnsblog" service in
-    master.cf.  This service does DNSBL lookups for postscreen(8)
-    and logs results.
-
-5 - To enable DNSBL lookups, list some DNS blocklist sites in
-    main.cf, e.g., "postscreen_dnsbl_sites = zen.spamhaus.org".
-    Separate domain names with comma or whitespace.
-
-Note: you must stop and start the master daemon.  This is needed
-because the Postfix "pass" master service type did not work reliably
-on all systems.
-
-To use the postscreen(8) service to block mail, edit main.cf and
-specify one or more of:
-
-- "postscreen_greet_action = drop", to drop clients that talk before
-  their turn. This alone stops about one third of all known-to-be
-  illegitimate connections to Wietse's mail server.
-
-- "postscreen_hangup_action = drop", to waste no time on clients
-  that hang up without sending a command. On Wietse's server, only
-  one percent of illegitimate connections behaves like this.
-
-- "postscreen_dnsbl_action = drop", to drop clients that are on DNS
-  blocklists. Different blocklists cover different client categories.
-
-There is also support for permanent blacklists and whitelists; see
-the postscreen(8) manual page for details.
-
-Note: right now, postscreen(8) "drop" actions disconnect the client
-without reporting sender and recipient information. In a future
-implementation, the connection may instead be passed to a dummy
-SMTP protocol engine that logs sender and recipient information
-before dropping the connection.
index 016482248bd6db892a749dad7e5f1ec6e7761939..e243dcd866baeb01cc22eb9d482ec4d3d9d93924 100644 (file)
@@ -2,6 +2,8 @@ Wish list:
 
        Remove this file from the stable release.
 
+       Re-run "make depend" with all plugins enabled.
+
        anvil rate limit for sasl_username.
 
        Encapsulate nbbio buffer access and update by tlsproxy.
index 36e036254fc6dce276ab0d6466653157604bf8c4..3e7b683e6a70edf79c47ea830ad6a7fee45a66a8 100644 (file)
@@ -13000,6 +13000,70 @@ Example:
 </pre>
 
 
+</DD>
+
+<DT><b><a name="smtpd_reject_contact_information">smtpd_reject_contact_information</a>
+(default: empty)</b></DT><DD>
+
+<p> Optional contact 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.
+     Please provide the following information in your problem report:
+     time ($localtime) and client address ($client_address).
+</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).
+</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> 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>
+
+<p> This feature supports a limited number of $name attributes in
+the contact 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> localtime </dt> <dd> Server local time (Mmm dd hh:mm:ss) </dd>
+
+<dt> recipient </dt> <dd> The address in the RCPT TO command </dd>
+
+<dt> sender  </dt> <dd> The address in the MAIL FROM command </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> 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>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="smtpd_reject_unlisted_recipient">smtpd_reject_unlisted_recipient</a>
index e942ab4d065b070889b5ea3f6cd29d2671b9181b..841eb9cbefcac4a8d3acd850dcec8ade66d8bb21 100644 (file)
@@ -388,7 +388,7 @@ SMTPD(8)                                                              SMTPD(8)
               Postfix  SMTP  server  uses  for TLS encrypted SMTP
               sessions.
 
-       <b><a href="postconf.5.html#smtpd_starttls_timeout">smtpd_starttls_timeout</a> (300s)</b>
+       <b><a href="postconf.5.html#smtpd_starttls_timeout">smtpd_starttls_timeout</a> (see 'postconf -d' output)</b>
               The time limit for Postfix SMTP  server  write  and
               read  operations  during  TLS  startup and shutdown
               handshake procedures.
@@ -647,6 +647,10 @@ 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#soft_bounce">soft_bounce</a> (no)</b>
               Safety net to keep mail queued that would otherwise
               be returned to the sender.
@@ -654,22 +658,22 @@ SMTPD(8)                                                              SMTPD(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtpd_authorized_xclient_hosts">smtpd_authorized_xclient_hosts</a> (empty)</b>
-              What  SMTP  clients  are allowed to use the XCLIENT
+              What SMTP clients are allowed to  use  the  XCLIENT
               feature.
 
 <b>KNOWN VERSUS UNKNOWN RECIPIENT CONTROLS</b>
-       As of Postfix version 2.0, the SMTP  server  rejects  mail
-       for  unknown recipients. This prevents the mail queue from
-       clogging up  with  undeliverable  MAILER-DAEMON  messages.
-       Additional   information   on   this   topic   is  in  the
+       As  of  Postfix  version 2.0, the SMTP server rejects mail
+       for unknown recipients. This prevents the mail queue  from
+       clogging  up  with  undeliverable  MAILER-DAEMON messages.
+       Additional  information  on   this   topic   is   in   the
        <a href="LOCAL_RECIPIENT_README.html">LOCAL_RECIPIENT_README</a> and <a href="ADDRESS_CLASS_README.html">ADDRESS_CLASS_README</a> documents.
 
        <b><a href="postconf.5.html#show_user_unknown_table_name">show_user_unknown_table_name</a> (yes)</b>
-              Display  the  name  of  the  recipient table in the
+              Display the name of  the  recipient  table  in  the
               "User unknown" responses.
 
        <b><a href="postconf.5.html#canonical_maps">canonical_maps</a> (empty)</b>
-              Optional address mapping lookup tables for  message
+              Optional  address mapping lookup tables for message
               headers and envelopes.
 
        <b><a href="postconf.5.html#recipient_canonical_maps">recipient_canonical_maps</a> (empty)</b>
@@ -680,7 +684,7 @@ SMTPD(8)                                                              SMTPD(8)
 
        <b><a href="postconf.5.html#mydestination">mydestination</a>  ($<a href="postconf.5.html#myhostname">myhostname</a>,  localhost.$<a href="postconf.5.html#mydomain">mydomain</a>,  local-</b>
        <b>host)</b>
-              The list of domains  that  are  delivered  via  the
+              The  list  of  domains  that  are delivered via the
               $<a href="postconf.5.html#local_transport">local_transport</a> mail delivery transport.
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
@@ -689,146 +693,146 @@ SMTPD(8)                                                              SMTPD(8)
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
               The network interface addresses that this mail sys-
-              tem  receives  mail on by way of a proxy or network
+              tem receives mail on by way of a proxy  or  network
               address translation unit.
 
        <b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (ipv4)</b>
-              The Internet protocols Postfix will attempt to  use
+              The  Internet protocols Postfix will attempt to use
               when making or accepting connections.
 
        <b><a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a>             (<a href="proxymap.8.html">proxy</a>:unix:passwd.byname</b>
        <b>$<a href="postconf.5.html#alias_maps">alias_maps</a>)</b>
-              Lookup  tables with all names or addresses of local
-              recipients: a recipient address is local  when  its
-              domain  matches $<a href="postconf.5.html#mydestination">mydestination</a>, $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a> or
+              Lookup tables with all names or addresses of  local
+              recipients:  a  recipient address is local when its
+              domain matches $<a href="postconf.5.html#mydestination">mydestination</a>, $<a href="postconf.5.html#inet_interfaces">inet_interfaces</a>  or
               $<a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a>.
 
        <b><a href="postconf.5.html#unknown_local_recipient_reject_code">unknown_local_recipient_reject_code</a> (550)</b>
-              The numerical Postfix  SMTP  server  response  code
-              when    a   recipient   address   is   local,   and
-              $<a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a> specifies a  list  of  lookup
+              The  numerical  Postfix  SMTP  server response code
+              when   a   recipient   address   is   local,    and
+              $<a href="postconf.5.html#local_recipient_maps">local_recipient_maps</a>  specifies  a  list of lookup
               tables that does not match the recipient.
 
-       Parameters  concerning  known/unknown  recipients of relay
+       Parameters concerning known/unknown  recipients  of  relay
        destinations:
 
        <b><a href="postconf.5.html#relay_domains">relay_domains</a> ($<a href="postconf.5.html#mydestination">mydestination</a>)</b>
-              What destination domains (and  subdomains  thereof)
+              What  destination  domains (and subdomains thereof)
               this system will relay mail to.
 
        <b><a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> (empty)</b>
-              Optional  lookup tables with all valid addresses in
+              Optional lookup tables with all valid addresses  in
               the domains that match $<a href="postconf.5.html#relay_domains">relay_domains</a>.
 
        <b><a href="postconf.5.html#unknown_relay_recipient_reject_code">unknown_relay_recipient_reject_code</a> (550)</b>
               The numerical Postfix SMTP server reply code when a
-              recipient   address   matches  $<a href="postconf.5.html#relay_domains">relay_domains</a>,  and
-              <a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a> specifies  a  list  of  lookup
+              recipient  address  matches   $<a href="postconf.5.html#relay_domains">relay_domains</a>,   and
+              <a href="postconf.5.html#relay_recipient_maps">relay_recipient_maps</a>  specifies  a  list  of lookup
               tables that does not match the recipient address.
 
-       Parameters  concerning known/unknown recipients in virtual
+       Parameters concerning known/unknown recipients in  virtual
        alias domains:
 
        <b><a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a> ($<a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a>)</b>
               Postfix is final destination for the specified list
-              of  virtual  alias  domains,  that  is, domains for
-              which all addresses are  aliased  to  addresses  in
+              of virtual alias  domains,  that  is,  domains  for
+              which  all  addresses  are  aliased to addresses in
               other local or remote domains.
 
        <b><a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> ($<a href="postconf.5.html#virtual_maps">virtual_maps</a>)</b>
-              Optional  lookup  tables  that  alias specific mail
-              addresses or  domains  to  other  local  or  remote
+              Optional lookup tables  that  alias  specific  mail
+              addresses  or  domains  to  other  local  or remote
               address.
 
        <b><a href="postconf.5.html#unknown_virtual_alias_reject_code">unknown_virtual_alias_reject_code</a> (550)</b>
               The SMTP server reply code when a recipient address
-              matches    $<a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a>,    and     $<a href="postconf.5.html#virtual_alias_maps">vir</a>-
-              <a href="postconf.5.html#virtual_alias_maps">tual_alias_maps</a>  specifies  a list of lookup tables
+              matches     $<a href="postconf.5.html#virtual_alias_domains">virtual_alias_domains</a>,    and    $<a href="postconf.5.html#virtual_alias_maps">vir</a>-
+              <a href="postconf.5.html#virtual_alias_maps">tual_alias_maps</a> specifies a list of  lookup  tables
               that does not match the recipient address.
 
-       Parameters concerning known/unknown recipients in  virtual
+       Parameters  concerning known/unknown recipients in virtual
        mailbox domains:
 
        <b><a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a> ($<a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a>)</b>
               Postfix is final destination for the specified list
-              of  domains;  mail  is  delivered  via  the   $<a href="postconf.5.html#virtual_transport">vir</a>-
+              of   domains;  mail  is  delivered  via  the  $<a href="postconf.5.html#virtual_transport">vir</a>-
               <a href="postconf.5.html#virtual_transport">tual_transport</a> mail delivery transport.
 
        <b><a href="postconf.5.html#virtual_mailbox_maps">virtual_mailbox_maps</a> (empty)</b>
-              Optional  lookup tables with all valid addresses in
+              Optional lookup tables with all valid addresses  in
               the domains that match $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a>.
 
        <b><a href="postconf.5.html#unknown_virtual_mailbox_reject_code">unknown_virtual_mailbox_reject_code</a> (550)</b>
               The SMTP server reply code when a recipient address
-              matches    $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a>,    and   $<a href="postconf.5.html#virtual_mailbox_maps">vir</a>-
+              matches   $<a href="postconf.5.html#virtual_mailbox_domains">virtual_mailbox_domains</a>,    and    $<a href="postconf.5.html#virtual_mailbox_maps">vir</a>-
               <a href="postconf.5.html#virtual_mailbox_maps">tual_mailbox_maps</a> specifies a list of lookup tables
               that does not match the recipient address.
 
 <b>RESOURCE AND RATE CONTROLS</b>
-       The  following parameters limit resource usage by the SMTP
+       The following parameters limit resource usage by the  SMTP
        server and/or control client request rates.
 
        <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#queue_minfree">queue_minfree</a> (0)</b>
-              The minimal amount of free space in  bytes  in  the
+              The  minimal  amount  of free space in bytes in the
               queue file system that is needed to receive mail.
 
        <b><a href="postconf.5.html#message_size_limit">message_size_limit</a> (10240000)</b>
-              The  maximal  size in bytes of a message, including
+              The maximal size in bytes of a  message,  including
               envelope information.
 
        <b><a href="postconf.5.html#smtpd_recipient_limit">smtpd_recipient_limit</a> (1000)</b>
-              The maximal number of recipients that  the  Postfix
+              The  maximal  number of recipients that the Postfix
               SMTP server accepts per message delivery request.
 
        <b><a href="postconf.5.html#smtpd_timeout">smtpd_timeout</a> (normal: 300s, overload: 10s)</b>
-              The  time  limit  for sending a Postfix SMTP server
-              response and for receiving  a  remote  SMTP  client
+              The time limit for sending a  Postfix  SMTP  server
+              response  and  for  receiving  a remote SMTP client
               request.
 
        <b><a href="postconf.5.html#smtpd_history_flush_threshold">smtpd_history_flush_threshold</a> (100)</b>
-              The  maximal  number  of  lines in the Postfix SMTP
-              server command history before it  is  flushed  upon
+              The maximal number of lines  in  the  Postfix  SMTP
+              server  command  history  before it is flushed upon
               receipt of EHLO, RSET, or end of DATA.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#smtpd_peername_lookup">smtpd_peername_lookup</a> (yes)</b>
               Attempt to look up the remote SMTP client hostname,
-              and verify that the  name  matches  the  client  IP
+              and  verify  that  the  name  matches the client IP
               address.
 
        The per SMTP client connection count and request rate lim-
        its are implemented in co-operation with the <a href="anvil.8.html"><b>anvil</b>(8)</a> ser-
-       vice,  and are available in Postfix version 2.2 and later.
+       vice, and are available in Postfix version 2.2 and  later.
 
        <b><a href="postconf.5.html#smtpd_client_connection_count_limit">smtpd_client_connection_count_limit</a> (50)</b>
-              How many simultaneous  connections  any  client  is
+              How  many  simultaneous  connections  any client is
               allowed to make to this service.
 
        <b><a href="postconf.5.html#smtpd_client_connection_rate_limit">smtpd_client_connection_rate_limit</a> (0)</b>
               The  maximal  number  of  connection  attempts  any
-              client is allowed to make to this service per  time
+              client  is allowed to make to this service per time
               unit.
 
        <b><a href="postconf.5.html#smtpd_client_message_rate_limit">smtpd_client_message_rate_limit</a> (0)</b>
-              The  maximal  number  of  message delivery requests
-              that any client is allowed to make to this  service
+              The maximal number  of  message  delivery  requests
+              that  any client is allowed to make to this service
               per time unit, regardless of whether or not Postfix
               actually accepts those messages.
 
        <b><a href="postconf.5.html#smtpd_client_recipient_rate_limit">smtpd_client_recipient_rate_limit</a> (0)</b>
-              The maximal number of recipient addresses that  any
-              client  is allowed to send to this service per time
+              The  maximal number of recipient addresses that any
+              client is allowed to send to this service per  time
               unit, regardless of whether or not Postfix actually
               accepts those recipients.
 
        <b><a href="postconf.5.html#smtpd_client_event_limit_exceptions">smtpd_client_event_limit_exceptions</a> ($<a href="postconf.5.html#mynetworks">mynetworks</a>)</b>
-              Clients       that      are      excluded      from
+              Clients      that      are      excluded       from
               smtpd_client_*_count/rate_limit restrictions.
 
        Available in Postfix version 2.3 and later:
@@ -839,52 +843,52 @@ SMTPD(8)                                                              SMTPD(8)
               tiate with this service per time unit.
 
 <b>TARPIT CONTROLS</b>
-       When a remote SMTP client makes errors, the  Postfix  SMTP
-       server  can insert delays before responding. This can help
-       to slow down run-away  software.   The  behavior  is  con-
-       trolled  by  an  error  counter  that counts the number of
-       errors within an SMTP session that a client makes  without
+       When  a  remote SMTP client makes errors, the Postfix SMTP
+       server can insert delays before responding. This can  help
+       to  slow  down  run-away  software.   The behavior is con-
+       trolled by an error counter  that  counts  the  number  of
+       errors  within an SMTP session that a client makes without
        delivering mail.
 
        <b><a href="postconf.5.html#smtpd_error_sleep_time">smtpd_error_sleep_time</a> (1s)</b>
               With Postfix version 2.1 and later: the SMTP server
-              response delay after a client has  made  more  than
-              $<a href="postconf.5.html#smtpd_soft_error_limit">smtpd_soft_error_limit</a>   errors,  and  fewer  than
-              $<a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> errors, without  delivering
+              response  delay  after  a client has made more than
+              $<a href="postconf.5.html#smtpd_soft_error_limit">smtpd_soft_error_limit</a>  errors,  and  fewer   than
+              $<a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a>  errors, without delivering
               mail.
 
        <b><a href="postconf.5.html#smtpd_soft_error_limit">smtpd_soft_error_limit</a> (10)</b>
-              The  number  of  errors  a  remote  SMTP  client is
-              allowed to make without delivering mail before  the
+              The number  of  errors  a  remote  SMTP  client  is
+              allowed  to make without delivering mail before the
               Postfix SMTP server slows down all its responses.
 
        <b><a href="postconf.5.html#smtpd_hard_error_limit">smtpd_hard_error_limit</a> (normal: 20, overload: 1)</b>
-              The  maximal  number of errors a remote SMTP client
+              The maximal number of errors a remote  SMTP  client
               is allowed to make without delivering mail.
 
        <b><a href="postconf.5.html#smtpd_junk_command_limit">smtpd_junk_command_limit</a> (normal: 100, overload: 1)</b>
-              The number of junk commands (NOOP,  VRFY,  ETRN  or
+              The  number  of  junk commands (NOOP, VRFY, ETRN or
               RSET) that a remote SMTP client can send before the
-              Postfix SMTP server starts to increment  the  error
+              Postfix  SMTP  server starts to increment the error
               counter with each junk command.
 
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtpd_recipient_overshoot_limit">smtpd_recipient_overshoot_limit</a> (1000)</b>
-              The  number of recipients that a remote SMTP client
-              can send in excess  of  the  limit  specified  with
+              The number of recipients that a remote SMTP  client
+              can  send  in  excess  of  the limit specified with
               $<a href="postconf.5.html#smtpd_recipient_limit">smtpd_recipient_limit</a>,  before  the  Postfix  SMTP
-              server increments the per-session error  count  for
+              server  increments  the per-session error count for
               each excess recipient.
 
 <b>ACCESS POLICY DELEGATION CONTROLS</b>
-       As  of  version 2.1, Postfix can be configured to delegate
-       access policy decisions to an external  server  that  runs
-       outside  Postfix.   See  the  file <a href="SMTPD_POLICY_README.html">SMTPD_POLICY_README</a> for
+       As of version 2.1, Postfix can be configured  to  delegate
+       access  policy  decisions  to an external server that runs
+       outside Postfix.  See  the  file  <a href="SMTPD_POLICY_README.html">SMTPD_POLICY_README</a>  for
        more information.
 
        <b><a href="postconf.5.html#smtpd_policy_service_max_idle">smtpd_policy_service_max_idle</a> (300s)</b>
-              The time after which an idle SMTPD  policy  service
+              The  time  after which an idle SMTPD policy service
               connection is closed.
 
        <b><a href="postconf.5.html#smtpd_policy_service_max_ttl">smtpd_policy_service_max_ttl</a> (1000s)</b>
@@ -892,151 +896,151 @@ SMTPD(8)                                                              SMTPD(8)
               connection is closed.
 
        <b><a href="postconf.5.html#smtpd_policy_service_timeout">smtpd_policy_service_timeout</a> (100s)</b>
-              The time limit for connecting  to,  writing  to  or
+              The  time  limit  for  connecting to, writing to or
               receiving from a delegated SMTPD policy server.
 
 <b>ACCESS CONTROLS</b>
-       The  <a href="SMTPD_ACCESS_README.html">SMTPD_ACCESS_README</a> document gives an introduction to
+       The <a href="SMTPD_ACCESS_README.html">SMTPD_ACCESS_README</a> document gives an introduction  to
        all the SMTP server access control features.
 
        <b><a href="postconf.5.html#smtpd_delay_reject">smtpd_delay_reject</a> (yes)</b>
-              Wait until the RCPT TO  command  before  evaluating
+              Wait  until  the  RCPT TO command before evaluating
               $<a href="postconf.5.html#smtpd_client_restrictions">smtpd_client_restrictions</a>,    $smtpd_helo_restric-
               tions and $<a href="postconf.5.html#smtpd_sender_restrictions">smtpd_sender_restrictions</a>, or wait until
-              the      ETRN     command     before     evaluating
+              the     ETRN     command     before      evaluating
               $<a href="postconf.5.html#smtpd_client_restrictions">smtpd_client_restrictions</a> and $smtpd_helo_restric-
               tions.
 
-       <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a>  (see  'postconf -d' out-</b>
+       <b><a href="postconf.5.html#parent_domain_matches_subdomains">parent_domain_matches_subdomains</a> (see 'postconf  -d'  out-</b>
        <b>put)</b>
               What   Postfix   features   match   subdomains   of
               "domain.tld" automatically, instead of requiring an
               explicit ".domain.tld" pattern.
 
        <b><a href="postconf.5.html#smtpd_client_restrictions">smtpd_client_restrictions</a> (empty)</b>
-              Optional  SMTP  server  access  restrictions in the
+              Optional SMTP server  access  restrictions  in  the
               context of a client SMTP connection request.
 
        <b><a href="postconf.5.html#smtpd_helo_required">smtpd_helo_required</a> (no)</b>
               Require that a remote SMTP client introduces itself
-              with  the  HELO  or EHLO command before sending the
-              MAIL command or other commands  that  require  EHLO
+              with the HELO or EHLO command  before  sending  the
+              MAIL  command  or  other commands that require EHLO
               negotiation.
 
        <b><a href="postconf.5.html#smtpd_helo_restrictions">smtpd_helo_restrictions</a> (empty)</b>
-              Optional  restrictions that the Postfix SMTP server
+              Optional restrictions that the Postfix SMTP  server
               applies in the context of the SMTP HELO command.
 
        <b><a href="postconf.5.html#smtpd_sender_restrictions">smtpd_sender_restrictions</a> (empty)</b>
-              Optional restrictions that the Postfix SMTP  server
+              Optional  restrictions that the Postfix SMTP server
               applies in the context of the MAIL FROM command.
 
        <b><a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a>           (<a href="postconf.5.html#permit_mynetworks">permit_mynetworks</a>,</b>
        <b><a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a>)</b>
               The  access  restrictions  that  the  Postfix  SMTP
-              server applies in the context of the RCPT  TO  com-
+              server  applies  in the context of the RCPT TO com-
               mand.
 
        <b><a href="postconf.5.html#smtpd_etrn_restrictions">smtpd_etrn_restrictions</a> (empty)</b>
-              Optional  SMTP  server  access  restrictions in the
+              Optional SMTP server  access  restrictions  in  the
               context of a client ETRN request.
 
        <b><a href="postconf.5.html#allow_untrusted_routing">allow_untrusted_routing</a> (no)</b>
-              Forward   mail   with   sender-specified    routing
-              (user[@%!]remote[@%!]site)  from  untrusted clients
+              Forward    mail   with   sender-specified   routing
+              (user[@%!]remote[@%!]site) from  untrusted  clients
               to destinations matching $<a href="postconf.5.html#relay_domains">relay_domains</a>.
 
        <b><a href="postconf.5.html#smtpd_restriction_classes">smtpd_restriction_classes</a> (empty)</b>
-              User-defined aliases for groups of access  restric-
+              User-defined  aliases for groups of access restric-
               tions.
 
        <b><a href="postconf.5.html#smtpd_null_access_lookup_key">smtpd_null_access_lookup_key</a> (</b>&lt;&gt;<b>)</b>
-              The  lookup key to be used in SMTP <a href="access.5.html"><b>access</b>(5)</a> tables
+              The lookup key to be used in SMTP <a href="access.5.html"><b>access</b>(5)</a>  tables
               instead of the null sender address.
 
        <b><a href="postconf.5.html#permit_mx_backup_networks">permit_mx_backup_networks</a> (empty)</b>
               Restrict  the  use  of  the  <a href="postconf.5.html#permit_mx_backup">permit_mx_backup</a>  SMTP
-              access  feature  to  only  domains whose primary MX
+              access feature to only  domains  whose  primary  MX
               hosts match the listed networks.
 
        Available in Postfix version 2.0 and later:
 
        <b><a href="postconf.5.html#smtpd_data_restrictions">smtpd_data_restrictions</a> (empty)</b>
-              Optional access restrictions that the Postfix  SMTP
+              Optional  access restrictions that the Postfix SMTP
               server applies in the context of the SMTP DATA com-
               mand.
 
        <b><a href="postconf.5.html#smtpd_expansion_filter">smtpd_expansion_filter</a> (see 'postconf -d' output)</b>
-              What characters are allowed in $name expansions  of
+              What  characters are allowed in $name expansions of
               RBL reply templates.
 
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtpd_reject_unlisted_sender">smtpd_reject_unlisted_sender</a> (no)</b>
-              Request  that  the Postfix SMTP server rejects mail
-              from  unknown  sender  addresses,  even   when   no
-              explicit  <a href="postconf.5.html#reject_unlisted_sender">reject_unlisted_sender</a> access restriction
+              Request that the Postfix SMTP server  rejects  mail
+              from   unknown   sender  addresses,  even  when  no
+              explicit <a href="postconf.5.html#reject_unlisted_sender">reject_unlisted_sender</a> access  restriction
               is specified.
 
        <b><a href="postconf.5.html#smtpd_reject_unlisted_recipient">smtpd_reject_unlisted_recipient</a> (yes)</b>
-              Request that the Postfix SMTP server  rejects  mail
+              Request  that  the Postfix SMTP server rejects mail
               for  unknown  recipient  addresses,  even  when  no
-              explicit <a href="postconf.5.html#reject_unlisted_recipient">reject_unlisted_recipient</a> access  restric-
+              explicit  <a href="postconf.5.html#reject_unlisted_recipient">reject_unlisted_recipient</a> access restric-
               tion is specified.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtpd_end_of_data_restrictions">smtpd_end_of_data_restrictions</a> (empty)</b>
-              Optional  access restrictions that the Postfix SMTP
-              server applies in the context of the  SMTP  END-OF-
+              Optional access restrictions that the Postfix  SMTP
+              server  applies  in the context of the SMTP END-OF-
               DATA command.
 
 <b>SENDER AND RECIPIENT ADDRESS VERIFICATION CONTROLS</b>
-       Postfix   version  2.1  introduces  sender  and  recipient
-       address verification.   This  feature  is  implemented  by
-       sending  probe email messages that are not actually deliv-
-       ered.  This feature is requested  via  the  reject_unveri-
-       fied_sender    and    <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a>   access
-       restrictions.  The status of verification probes is  main-
+       Postfix  version  2.1  introduces  sender  and   recipient
+       address  verification.   This  feature  is  implemented by
+       sending probe email messages that are not actually  deliv-
+       ered.   This  feature  is requested via the reject_unveri-
+       fied_sender   and    <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a>    access
+       restrictions.   The status of verification probes is main-
        tained by the <a href="verify.8.html"><b>verify</b>(8)</a> server.  See the file <a href="ADDRESS_VERIFICATION_README.html">ADDRESS_VER</a>-
-       <a href="ADDRESS_VERIFICATION_README.html">IFICATION_README</a> for information about  how  to  configure
+       <a href="ADDRESS_VERIFICATION_README.html">IFICATION_README</a>  for  information  about how to configure
        and operate the Postfix sender/recipient address verifica-
        tion service.
 
        <b><a href="postconf.5.html#address_verify_poll_count">address_verify_poll_count</a> (normal: 3, overload: 1)</b>
-              How many times to query the <a href="verify.8.html"><b>verify</b>(8)</a>  service  for
-              the  completion  of an address verification request
+              How  many  times to query the <a href="verify.8.html"><b>verify</b>(8)</a> service for
+              the completion of an address  verification  request
               in progress.
 
        <b><a href="postconf.5.html#address_verify_poll_delay">address_verify_poll_delay</a> (3s)</b>
-              The delay between queries for the completion of  an
+              The  delay between queries for the completion of an
               address verification request in progress.
 
        <b><a href="postconf.5.html#address_verify_sender">address_verify_sender</a> ($<a href="postconf.5.html#double_bounce_sender">double_bounce_sender</a>)</b>
-              The  sender  address to use in address verification
+              The sender address to use in  address  verification
               probes; prior to Postfix 2.5 the default was "post-
               master".
 
        <b><a href="postconf.5.html#unverified_sender_reject_code">unverified_sender_reject_code</a> (450)</b>
-              The  numerical  Postfix  SMTP  server response code
-              when  a  recipient  address  is  rejected  by   the
+              The numerical Postfix  SMTP  server  response  code
+              when   a  recipient  address  is  rejected  by  the
               <a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a> restriction.
 
        <b><a href="postconf.5.html#unverified_recipient_reject_code">unverified_recipient_reject_code</a> (450)</b>
-              The  numerical  Postfix SMTP server response when a
+              The numerical Postfix SMTP server response  when  a
               recipient address is rejected by the reject_unveri-
               fied_recipient restriction.
 
        Available in Postfix version 2.6 and later:
 
        <b><a href="postconf.5.html#unverified_sender_defer_code">unverified_sender_defer_code</a> (450)</b>
-              The  numerical  Postfix  SMTP  server response code
-              when a sender address probe fails due to  a  tempo-
+              The numerical Postfix  SMTP  server  response  code
+              when  a  sender address probe fails due to a tempo-
               rary error condition.
 
        <b><a href="postconf.5.html#unverified_recipient_defer_code">unverified_recipient_defer_code</a> (450)</b>
-              The  numerical  Postfix SMTP server response when a
-              recipient address probe fails due  to  a  temporary
+              The numerical Postfix SMTP server response  when  a
+              recipient  address  probe  fails due to a temporary
               error condition.
 
        <b><a href="postconf.5.html#unverified_sender_reject_reason">unverified_sender_reject_reason</a> (empty)</b>
@@ -1050,7 +1054,7 @@ SMTPD(8)                                                              SMTPD(8)
        <b><a href="postconf.5.html#unverified_sender_tempfail_action">unverified_sender_tempfail_action</a>           ($<a href="postconf.5.html#reject_tempfail_action">reject_temp</a>-</b>
        <b><a href="postconf.5.html#reject_tempfail_action">fail_action</a>)</b>
               The Postfix SMTP server's action when <a href="postconf.5.html#reject_unverified_sender">reject_unver</a>-
-              <a href="postconf.5.html#reject_unverified_sender">ified_sender</a> fails due to a temporary error  condi-
+              <a href="postconf.5.html#reject_unverified_sender">ified_sender</a>  fails due to a temporary error condi-
               tion.
 
        <b><a href="postconf.5.html#unverified_recipient_tempfail_action">unverified_recipient_tempfail_action</a>        ($<a href="postconf.5.html#reject_tempfail_action">reject_temp</a>-</b>
@@ -1060,7 +1064,7 @@ SMTPD(8)                                                              SMTPD(8)
               dition.
 
 <b>ACCESS CONTROL RESPONSES</b>
-       The  following  parameters  control  numerical  SMTP reply
+       The following  parameters  control  numerical  SMTP  reply
        codes and/or text responses.
 
        <b><a href="postconf.5.html#access_map_reject_code">access_map_reject_code</a> (554)</b>
@@ -1068,18 +1072,18 @@ SMTPD(8)                                                              SMTPD(8)
               an <a href="access.5.html"><b>access</b>(5)</a> map "reject" action.
 
        <b><a href="postconf.5.html#defer_code">defer_code</a> (450)</b>
-              The  numerical  Postfix  SMTP  server response code
-              when a remote SMTP client request  is  rejected  by
+              The numerical Postfix  SMTP  server  response  code
+              when  a  remote  SMTP client request is rejected by
               the "defer" restriction.
 
        <b><a href="postconf.5.html#invalid_hostname_reject_code">invalid_hostname_reject_code</a> (501)</b>
-              The  numerical  Postfix  SMTP  server response code
-              when the client HELO or EHLO command  parameter  is
-              rejected    by   the   <a href="postconf.5.html#reject_invalid_helo_hostname">reject_invalid_helo_hostname</a>
+              The numerical Postfix  SMTP  server  response  code
+              when  the  client HELO or EHLO command parameter is
+              rejected   by   the    <a href="postconf.5.html#reject_invalid_helo_hostname">reject_invalid_helo_hostname</a>
               restriction.
 
        <b><a href="postconf.5.html#maps_rbl_reject_code">maps_rbl_reject_code</a> (554)</b>
-              The numerical Postfix  SMTP  server  response  code
+              The  numerical  Postfix  SMTP  server response code
               when a remote SMTP client request is blocked by the
               <a href="postconf.5.html#reject_rbl_client">reject_rbl_client</a>,             <a href="postconf.5.html#reject_rhsbl_client">reject_rhsbl_client</a>,
               <a href="postconf.5.html#reject_rhsbl_reverse_client">reject_rhsbl_reverse_client</a>, <a href="postconf.5.html#reject_rhsbl_sender">reject_rhsbl_sender</a> or
@@ -1087,53 +1091,53 @@ SMTPD(8)                                                              SMTPD(8)
 
        <b><a href="postconf.5.html#non_fqdn_reject_code">non_fqdn_reject_code</a> (504)</b>
               The numerical Postfix SMTP server reply code when a
-              client     request     is     rejected    by    the
+              client    request    is     rejected     by     the
               <a href="postconf.5.html#reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a>,
               <a href="postconf.5.html#reject_non_fqdn_sender">reject_non_fqdn_sender</a> or <a href="postconf.5.html#reject_non_fqdn_recipient">reject_non_fqdn_recipient</a>
               restriction.
 
        <b><a href="postconf.5.html#plaintext_reject_code">plaintext_reject_code</a> (450)</b>
-              The numerical Postfix  SMTP  server  response  code
-              when  a  request  is  rejected by the <b>reject_plain-</b>
+              The  numerical  Postfix  SMTP  server response code
+              when a request is  rejected  by  the  <b>reject_plain-</b>
               <b>text_session</b> restriction.
 
        <b><a href="postconf.5.html#reject_code">reject_code</a> (554)</b>
-              The numerical Postfix  SMTP  server  response  code
-              when  a  remote  SMTP client request is rejected by
+              The  numerical  Postfix  SMTP  server response code
+              when a remote SMTP client request  is  rejected  by
               the "reject" restriction.
 
        <b><a href="postconf.5.html#relay_domains_reject_code">relay_domains_reject_code</a> (554)</b>
-              The numerical Postfix  SMTP  server  response  code
-              when   a   client   request   is  rejected  by  the
+              The  numerical  Postfix  SMTP  server response code
+              when  a  client  request   is   rejected   by   the
               <a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a> recipient restriction.
 
        <b><a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> (450)</b>
-              The numerical Postfix  SMTP  server  response  code
-              when  a  sender or recipient address is rejected by
+              The  numerical  Postfix  SMTP  server response code
+              when a sender or recipient address is  rejected  by
               the         <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a>         or
               <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a> restriction.
 
        <b><a href="postconf.5.html#unknown_client_reject_code">unknown_client_reject_code</a> (450)</b>
-              The  numerical  Postfix  SMTP  server response code
-              when a client without valid address &lt;=&gt;  name  map-
+              The numerical Postfix  SMTP  server  response  code
+              when  a  client without valid address &lt;=&gt; name map-
               ping is rejected by the reject_unknown_client_host-
               name restriction.
 
        <b><a href="postconf.5.html#unknown_hostname_reject_code">unknown_hostname_reject_code</a> (450)</b>
-              The numerical Postfix  SMTP  server  response  code
-              when  the  hostname specified with the HELO or EHLO
-              command       is       rejected       by        the
+              The  numerical  Postfix  SMTP  server response code
+              when the hostname specified with the HELO  or  EHLO
+              command        is       rejected       by       the
               <a href="postconf.5.html#reject_unknown_helo_hostname">reject_unknown_helo_hostname</a> restriction.
 
        Available in Postfix version 2.0 and later:
 
        <b><a href="postconf.5.html#default_rbl_reply">default_rbl_reply</a> (see 'postconf -d' output)</b>
-              The  default  SMTP  server  response template for a
-              request that is rejected by an  RBL-based  restric-
+              The default SMTP server  response  template  for  a
+              request  that  is rejected by an RBL-based restric-
               tion.
 
        <b><a href="postconf.5.html#multi_recipient_bounce_reject_code">multi_recipient_bounce_reject_code</a> (550)</b>
-              The  numerical  Postfix  SMTP  server response code
+              The numerical Postfix  SMTP  server  response  code
               when a remote SMTP client request is blocked by the
               <a href="postconf.5.html#reject_multi_recipient_bounce">reject_multi_recipient_bounce</a> restriction.
 
@@ -1144,38 +1148,38 @@ SMTPD(8)                                                              SMTPD(8)
 
        <b><a href="postconf.5.html#access_map_defer_code">access_map_defer_code</a> (450)</b>
               The numerical Postfix SMTP server response code for
-              an   <a href="access.5.html"><b>access</b>(5)</a>   map   "defer"   action,  including
+              an  <a href="access.5.html"><b>access</b>(5)</a>   map   "defer"   action,   including
               "<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>" or "<a href="postconf.5.html#defer_if_reject">defer_if_reject</a>".
 
        <b><a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a> (<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>)</b>
               The Postfix SMTP server's action when a reject-type
-              restriction  fails  due to a temporary error condi-
+              restriction fails due to a temporary  error  condi-
               tion.
 
        <b><a href="postconf.5.html#unknown_helo_hostname_tempfail_action">unknown_helo_hostname_tempfail_action</a>       ($<a href="postconf.5.html#reject_tempfail_action">reject_temp</a>-</b>
        <b><a href="postconf.5.html#reject_tempfail_action">fail_action</a>)</b>
-              The   Postfix    SMTP    server's    action    when
+              The    Postfix    SMTP    server's    action   when
               <a href="postconf.5.html#reject_unknown_helo_hostname">reject_unknown_helo_hostname</a> fails due to an tempo-
               rary error condition.
 
        <b><a href="postconf.5.html#unknown_address_tempfail_action">unknown_address_tempfail_action</a> ($<a href="postconf.5.html#reject_tempfail_action">reject_tempfail_action</a>)</b>
-              The   Postfix    SMTP    server's    action    when
+              The    Postfix    SMTP    server's    action   when
               <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a>                     or
-              <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a> fail due to a  tem-
+              <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a>  fail due to a tem-
               porary error condition.
 
 <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#daemon_timeout">daemon_timeout</a> (18000s)</b>
-              How much time a Postfix daemon process may take  to
-              handle  a  request  before  it  is  terminated by a
+              How  much time a Postfix daemon process may take to
+              handle a request  before  it  is  terminated  by  a
               built-in watchdog timer.
 
        <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#double_bounce_sender">double_bounce_sender</a> (double-bounce)</b>
@@ -1196,37 +1200,37 @@ SMTPD(8)                                                              SMTPD(8)
               and most Postfix daemon processes.
 
        <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
+              The  maximum  amount  of  time that an idle Postfix
+              daemon process waits  for  an  incoming  connection
               before terminating voluntarily.
 
        <b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
-              The maximal number of incoming connections  that  a
-              Postfix  daemon  process will service before termi-
+              The  maximal  number of incoming connections that a
+              Postfix daemon process will service  before  termi-
               nating voluntarily.
 
        <b><a href="postconf.5.html#myhostname">myhostname</a> (see 'postconf -d' output)</b>
               The internet hostname of this mail system.
 
        <b><a href="postconf.5.html#mynetworks">mynetworks</a> (see 'postconf -d' output)</b>
-              The list of "trusted" SMTP clients that  have  more
+              The  list  of "trusted" SMTP clients that have more
               privileges than "strangers".
 
        <b><a href="postconf.5.html#myorigin">myorigin</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
               The domain name that locally-posted mail appears to
-              come from, and that locally posted mail  is  deliv-
+              come  from,  and that locally posted mail is deliv-
               ered to.
 
        <b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
-              The  process  ID  of  a  Postfix  command or daemon
+              The process ID  of  a  Postfix  command  or  daemon
               process.
 
        <b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
-              The process name of a  Postfix  command  or  daemon
+              The  process  name  of  a Postfix command or daemon
               process.
 
        <b><a href="postconf.5.html#queue_directory">queue_directory</a> (see 'postconf -d' output)</b>
-              The  location of the Postfix top-level queue direc-
+              The location of the Postfix top-level queue  direc-
               tory.
 
        <b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
@@ -1234,28 +1238,28 @@ SMTPD(8)                                                              SMTPD(8)
               sions (user+foo).
 
        <b><a href="postconf.5.html#smtpd_banner">smtpd_banner</a> ($<a href="postconf.5.html#myhostname">myhostname</a> ESMTP $<a href="postconf.5.html#mail_name">mail_name</a>)</b>
-              The  text  that  follows the 220 status code in the
+              The text that follows the 220 status  code  in  the
               SMTP greeting banner.
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
-              The mail system  name  that  is  prepended  to  the
-              process  name  in  syslog  records, so that "smtpd"
+              The  mail  system  name  that  is  prepended to the
+              process name in syslog  records,  so  that  "smtpd"
               becomes, for example, "postfix/smtpd".
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a> (CONNECT, GET, POST)</b>
               List of commands that cause the Postfix SMTP server
-              to  immediately  terminate  the  session with a 221
+              to immediately terminate the  session  with  a  221
               code.
 
        Available in Postfix version 2.5 and later:
 
        <b><a href="postconf.5.html#smtpd_client_port_logging">smtpd_client_port_logging</a> (no)</b>
-              Enable logging of the remote SMTP  client  port  in
+              Enable  logging  of  the remote SMTP client port in
               addition to the hostname and IP address.
 
 <b>SEE ALSO</b>
@@ -1285,7 +1289,7 @@ SMTPD(8)                                                              SMTPD(8)
        <a href="XFORWARD_README.html">XFORWARD_README</a>, Postfix XFORWARD extension
 
 <b>LICENSE</b>
-       The Secure Mailer license must be  distributed  with  this
+       The  Secure  Mailer  license must be distributed with this
        software.
 
 <b>AUTHOR(S)</b>
index 66beefb092c9e98e116c8bfeb8d9c8c46305ac69..0258f573c6e9cb88eaf1f4fb3dfb049cba84abd0 100644 (file)
@@ -8094,6 +8094,67 @@ 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.
+.PP
+Example:
+.PP
+.nf
+.na
+.ft C
+/etc/postfix/main.cf:
+    smtpd_reject_contact_information = For assistance, call 800-555-0101.
+     Please provide the following information in your problem report:
+     time ($localtime) and client address ($client_address).
+.fi
+.ad
+.ft R
+.PP
+Server response:
+.PP
+.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).
+.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.
+.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.
+.PP
+This feature supports a limited number of $name attributes in
+the contact 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.
+.PP
+This feature is available in Postfix 2.8 and later.
 .SH smtpd_reject_unlisted_recipient (default: yes)
 Request that the Postfix SMTP server rejects mail for unknown
 recipient addresses, even when no explicit reject_unlisted_recipient
index 1dd8cc5ae1553b55286642413e470c8d95c08403..a4f7fd5ea84de8d5e26c5bd8ae2a09e52d0f5a69 100644 (file)
@@ -341,7 +341,7 @@ smtpd_use_tls and smtpd_enforce_tls.
 .IP "\fBsmtpd_sasl_tls_security_options ($smtpd_sasl_security_options)\fR"
 The SASL authentication security options that the Postfix SMTP
 server uses for TLS encrypted SMTP sessions.
-.IP "\fBsmtpd_starttls_timeout (300s)\fR"
+.IP "\fBsmtpd_starttls_timeout (see 'postconf -d' output)\fR"
 The time limit for Postfix SMTP server write and read operations
 during TLS startup and shutdown handshake procedures.
 .IP "\fBsmtpd_tls_CAfile (empty)\fR"
@@ -527,6 +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 "\fBsoft_bounce (no)\fR"
 Safety net to keep mail queued that would otherwise be returned to
 the sender.
index 937495de4b001bc620bac613690e981c1f54710b..e77614fe51c5d8a2f96202613f113b1c7774800e 100755 (executable)
@@ -666,6 +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;\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;
index 0a44cfdfcaa83a41dfb6a54c6cecbcd3f2a55572..c39a711cc79f4672c91bce4e298eefa89a705567 100644 (file)
@@ -13822,3 +13822,62 @@ for further details. </p>
 
 <p> This feature is available in Postfix 2.8 and later. </p>
 
+%PARAM smtpd_reject_contact_information
+
+<p> Optional contact 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.
+     Please provide the following information in your problem report:
+     time ($localtime) and client address ($client_address).
+</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).
+</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> 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>
+
+<p> This feature supports a limited number of $name attributes in
+the contact 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> localtime </dt> <dd> Server local time (Mmm dd hh:mm:ss) </dd>
+
+<dt> recipient </dt> <dd> The address in the RCPT TO command </dd>
+
+<dt> sender  </dt> <dd> The address in the MAIL FROM command </dd>
+
+</dl>
+
+<p> For safety reasons, text that does not match $smtpd_expansion_filter
+is censored. </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>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
index 6c1e0166d638e32e500de312e86d1d4a4d44c164..47ab4d16a77dcbe601b9478ecbef231e473d2ba1 100644 (file)
@@ -802,6 +802,7 @@ 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
@@ -811,6 +812,7 @@ 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
index a0796063ba1e3c0793186b450e67580781f6d663..c5644526bfb447592362906234b4ca7d15975cee 100644 (file)
@@ -3554,6 +3554,13 @@ extern int var_tlsp_tls_scache_timeout;
 #define DEF_TLSP_TLS_SET_SESSID        "$" VAR_SMTPD_TLS_SET_SESSID
 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;
+
 /* LICENSE
 /* .ad
 /* .fi
index c3c97b5added0ef0c9a2a41f117ead41da61b882..84e825473d5fe07ee28c8072eb10a72215cd9c46 100644 (file)
@@ -111,6 +111,7 @@ extern char *mail_pathname(const char *, const char *);
 #define MAIL_ATTR_ERRTO                "errors-to"
 #define MAIL_ATTR_RRCPT                "return-receipt"
 #define MAIL_ATTR_TIME         "time"
+#define MAIL_ATTR_LOCALTIME    "localtime"
 #define MAIL_ATTR_CREATE_TIME  "create_time"
 #define MAIL_ATTR_RULE         "rule"
 #define MAIL_ATTR_ADDR         "address"
@@ -244,6 +245,14 @@ extern char *mail_pathname(const char *, const char *);
 #define MAIL_ATTR_ROLE_SERVER  "server"
 #define MAIL_ATTR_ROLE_CLIENT  "client"
 #define MAIL_ATTR_TIMEOUT      "timeout"
+#define MAIL_ATTR_PEER_CN      "peer_CN"
+#define MAIL_ATTR_ISSUER_CN    "issuer_CN"
+#define MAIL_ATTR_PEER_FPT     "peer_fingerprint"
+#define MAIL_ATTR_PEER_STATUS  "peer_status"
+#define MAIL_ATTR_CIPHER_PROTOCOL      "cipher_protocol"
+#define MAIL_ATTR_CIPHER_NAME  "cipher_name"
+#define MAIL_ATTR_CIPHER_USEBITS       "cipher_usebits"
+#define MAIL_ATTR_CIPHER_ALGBITS       "cipher_algbits"
 
 /* LICENSE
 /* .ad
index c7ae8e44ef6fd230e4685c736737636a9c5d6d64..ffb3e0e7e7e26c4f8fa39e497764ce05536b8bf6 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      "20110103"
+#define MAIL_RELEASE_DATE      "20110105"
 #define MAIL_VERSION_NUMBER    "2.8"
 
 #ifdef SNAPSHOT
index 5e41241a9c8fc9f820d6c01076131fbbcfa8a24b..615ebb8f8eada6594c6d05fda60d4703a6bd323b 100644 (file)
@@ -234,9 +234,13 @@ postscreen_starttls.o: ../../include/match_list.h
 postscreen_starttls.o: ../../include/match_ops.h
 postscreen_starttls.o: ../../include/msg.h
 postscreen_starttls.o: ../../include/mymalloc.h
+postscreen_starttls.o: ../../include/name_code.h
+postscreen_starttls.o: ../../include/name_mask.h
 postscreen_starttls.o: ../../include/string_list.h
 postscreen_starttls.o: ../../include/stringops.h
 postscreen_starttls.o: ../../include/sys_defs.h
+postscreen_starttls.o: ../../include/tls.h
+postscreen_starttls.o: ../../include/tls_proxy.h
 postscreen_starttls.o: ../../include/vbuf.h
 postscreen_starttls.o: ../../include/vstream.h
 postscreen_starttls.o: ../../include/vstring.h
index 07ebc8ca8ea56468b6b1dda94b1db4879cb0726e..5384eb80e7c4077e8a763da5b73f47654d70abf9 100644 (file)
@@ -205,20 +205,6 @@ static void psc_smtpd_read_event(int, char *);
 static MAPS *psc_ehlo_discard_maps;
 static int psc_ehlo_discard_mask;
 
- /*
-  * STARTTLS support. Note the complete absence of #ifdef USE_TLS throughout
-  * the postscreen(8) source code. If Postfix is built without TLS support,
-  * then the TLS proxy will simply report that TLS is not available, and
-  * conventional error handling will take care of the issue.
-  */
-static int psc_tls_use_tls;
-static int psc_tls_enforce_tls;
-
-#ifdef TODO_USE_SASL_AUTH
-static int psc_tls_auth_only;
-
-#endif
-
  /*
   * Encapsulation. We must not forget turn off input/timer events when we
   * terminate the SMTP protocol engine.
@@ -261,7 +247,7 @@ static int psc_helo_cmd(PSC_STATE *state, char *args)
 /* psc_smtpd_format_ehlo_reply - format EHLO response */
 
 static void psc_smtpd_format_ehlo_reply(VSTRING *buf, int discard_mask
-       /*, const char *sasl_mechanism_list */)
+                                  /* , const char *sasl_mechanism_list */ )
 {
     const char *myname = "psc_smtpd_format_ehlo_reply";
     int     saved_len = 0;
@@ -291,12 +277,11 @@ static void psc_smtpd_format_ehlo_reply(VSTRING *buf, int discard_mask
        PSC_EHLO_APPEND(saved_len, psc_temp, "250-VRFY\r\n");
     if ((discard_mask & EHLO_MASK_ETRN) == 0)
        PSC_EHLO_APPEND(saved_len, psc_temp, "250-ETRN\r\n");
-    if ((discard_mask & EHLO_MASK_STARTTLS) == 0
-       && (psc_tls_use_tls || psc_tls_enforce_tls))
+    if ((discard_mask & EHLO_MASK_STARTTLS) == 0 && var_psc_use_tls)
        PSC_EHLO_APPEND(saved_len, psc_temp, "250-STARTTLS\r\n");
 #ifdef TODO_SASL_AUTH
     if ((discard_mask & EHLO_MASK_AUTH) == 0 && sasl_mechanism_list
-       && (psc_tls_auth_only == 0 || (discard_mask & EHLO_MASK_STARTTLS))) {
+       && (!var_psc_tls_auth_only || (discard_mask & EHLO_MASK_STARTTLS))) {
        PSC_EHLO_APPEND1(saved_len, psc_temp, "AUTH %s", sasl_mechanism_list);
        if (var_broken_auth_clients)
            PSC_EHLO_APPEND1(saved_len, psc_temp, "AUTH=%s", sasl_mechanism_list);
@@ -393,7 +378,7 @@ static int psc_starttls_cmd(PSC_STATE *state, char *args)
     if (state->flags & PSC_STATE_FLAG_USING_TLS)
        return (PSC_SEND_REPLY(state,
                               "554 5.5.1 Error: TLS already active\r\n"));
-    if (psc_tls_use_tls == 0 || (state->ehlo_discard_mask & EHLO_MASK_STARTTLS))
+    if (var_psc_use_tls == 0 || (state->ehlo_discard_mask & EHLO_MASK_STARTTLS))
        return (PSC_SEND_REPLY(state,
                           "502 5.5.1 Error: command not implemented\r\n"));
 
@@ -955,7 +940,7 @@ static void psc_smtpd_read_event(int event, char *context)
        if (cmdp->name == 0 || (cmdp->flags & PSC_SMTPD_CMD_FLAG_ENABLE) == 0) {
            write_stat = PSC_SEND_REPLY(state,
                             "502 5.5.2 Error: command not recognized\r\n");
-       } else if (psc_tls_enforce_tls
+       } else if (var_psc_enforce_tls
                   && (state->flags & PSC_STATE_FLAG_USING_TLS) == 0
                   && (cmdp->flags & PSC_SMTPD_CMD_FLAG_PRE_TLS) == 0) {
            write_stat = PSC_SEND_REPLY(state,
@@ -1052,8 +1037,14 @@ void    psc_smtpd_init(void)
     psc_smtpd_helo_reply = mystrdup(STR(psc_temp));
 
     /*
-     * Legacy code copied from smtpd(8). The pre-fabricated EHLO reply
-     * depends on this.
+     * STARTTLS support. Note the complete absence of #ifdef USE_TLS
+     * throughout the postscreen(8) source code. If Postfix is built without
+     * TLS support, then the TLS proxy will simply report that TLS is not
+     * available, and conventional error handling will take care of the
+     * issue.
+     * 
+     * Legacy code copied from smtpd(8). The pre-fabricated EHLO reply depends
+     * on this.
      */
     if (*var_psc_tls_level) {
        switch (tls_level_lookup(var_psc_tls_level)) {
@@ -1079,11 +1070,9 @@ void    psc_smtpd_init(void)
            break;
        }
     }
-    psc_tls_enforce_tls = var_psc_enforce_tls;
-    psc_tls_use_tls = var_psc_use_tls || var_psc_enforce_tls;
+    var_psc_use_tls = var_psc_use_tls || var_psc_enforce_tls;
 #ifdef TODO_SASL_AUTH
-    if (var_psc_tls_auth_only || psc_tls_enforce_tls)
-       psc_tls_auth_only = 1;
+    var_psc_tls_auth_only = var_psc_tls_auth_only || var_psc_enforce_tls;
 #endif
 
     /*
index f43b53ec0c5bba4e4148054072aa9376bacf6468..9d8c1280539396bc9f513484508de8b85145cc8f 100644 (file)
 #include <mail_params.h>
 #include <mail_proto.h>
 
+/* TLS library. */
+
+#include <tls_proxy.h>
+
 /* Application-specific. */
 
 #include <postscreen.h>
@@ -74,7 +78,6 @@ typedef struct {
     PSC_STATE *smtp_state;             /* SMTP session state */
 } PSC_STARTTLS;
 
-#define TLSPROXY_SERVICE               "tlsproxy"
 #define TLSPROXY_INIT_TIMEOUT          10
 
 /* psc_starttls_finish - complete negotiation with TLS proxy */
@@ -155,9 +158,15 @@ static void psc_starttls_finish(int event, char *context)
         * Replace our SMTP client stream by the TLS proxy stream.  Once the
         * TLS handshake is done, the TLS proxy will deliver plaintext SMTP
         * commands to postscreen(8).
+        * 
+        * Swap the file descriptors from under the VSTREAM so that we don't
+        * have to worry about loss of user-configurable VSTREAM attributes.
         */
-       vstream_fclose(smtp_state->smtp_client_stream);
-       smtp_state->smtp_client_stream = tlsproxy_stream;
+       vstream_fpurge(smtp_state->smtp_client_stream, VSTREAM_PURGE_BOTH);
+       vstream_control(smtp_state->smtp_client_stream,
+                       VSTREAM_CTL_SWAP_FD, tlsproxy_stream,
+                       VSTREAM_CTL_END);
+       vstream_fclose(tlsproxy_stream);        /* direct-to-client stream! */
        smtp_state->flags |= PSC_STATE_FLAG_USING_TLS;
     }
 
@@ -210,7 +219,7 @@ void    psc_starttls_open(PSC_STATE *smtp_state, EVENT_NOTIFY_FN resume_event)
                               smtp_state->smtp_client_port, (char *) 0);
     attr_print(tlsproxy_stream, ATTR_FLAG_NONE,
               ATTR_TYPE_STR, MAIL_ATTR_REMOTE_ENDPT, remote_endpt,
-              ATTR_TYPE_STR, MAIL_ATTR_ROLE, MAIL_ATTR_ROLE_SERVER,
+              ATTR_TYPE_INT, MAIL_ATTR_FLAGS, TLS_PROXY_FLAG_ROLE_SERVER,
               ATTR_TYPE_INT, MAIL_ATTR_TIMEOUT, psc_normal_cmd_time_limit,
               ATTR_TYPE_END);
     myfree(remote_endpt);
index 0273877d68e17cf89e8ac33ec8d2d9b61f6b2bd4..856e8b8e65167c35635d939a07e2cefb8cd43197 100644 (file)
@@ -1,13 +1,15 @@
 SHELL  = /bin/sh
 SRCS   = smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \
        smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \
-       smtpd_xforward.c smtpd_dsn_fix.c smtpd_milter.c smtpd_resolve.c
+       smtpd_xforward.c smtpd_dsn_fix.c smtpd_milter.c smtpd_resolve.c \
+       smtpd_expand.c
 OBJS   = smtpd.o smtpd_token.o smtpd_check.o smtpd_chat.o smtpd_state.o \
        smtpd_peer.o smtpd_sasl_proto.o smtpd_sasl_glue.o smtpd_proxy.o \
-       smtpd_xforward.o smtpd_dsn_fix.o smtpd_milter.o smtpd_resolve.o
+       smtpd_xforward.o smtpd_dsn_fix.o smtpd_milter.o smtpd_resolve.o \
+       smtpd_expand.o
 HDRS   = smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \
        smtpd_sasl_glue.h smtpd_proxy.h smtpd_dsn_fix.h smtpd_milter.h \
-       smtpd_resolve.h
+       smtpd_resolve.h smtpd_expand.h
 TESTSRC        = smtpd_token_test.c
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@@ -156,6 +158,8 @@ smtpd.o: ../../include/input_transp.h
 smtpd.o: ../../include/iostuff.h
 smtpd.o: ../../include/is_header.h
 smtpd.o: ../../include/lex_822.h
+smtpd.o: ../../include/mac_expand.h
+smtpd.o: ../../include/mac_parse.h
 smtpd.o: ../../include/mail_conf.h
 smtpd.o: ../../include/mail_date.h
 smtpd.o: ../../include/mail_error.h
@@ -188,6 +192,7 @@ smtpd.o: ../../include/string_list.h
 smtpd.o: ../../include/stringops.h
 smtpd.o: ../../include/sys_defs.h
 smtpd.o: ../../include/tls.h
+smtpd.o: ../../include/tls_proxy.h
 smtpd.o: ../../include/tok822.h
 smtpd.o: ../../include/valid_hostname.h
 smtpd.o: ../../include/valid_mailhost_addr.h
@@ -202,6 +207,7 @@ smtpd.o: smtpd.c
 smtpd.o: smtpd.h
 smtpd.o: smtpd_chat.h
 smtpd.o: smtpd_check.h
+smtpd.o: smtpd_expand.h
 smtpd.o: smtpd_milter.h
 smtpd.o: smtpd_proxy.h
 smtpd.o: smtpd_sasl_glue.h
@@ -210,9 +216,12 @@ 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
+smtpd_chat.o: ../../include/mac_expand.h
+smtpd_chat.o: ../../include/mac_parse.h
 smtpd_chat.o: ../../include/mail_addr.h
 smtpd_chat.o: ../../include/mail_error.h
 smtpd_chat.o: ../../include/mail_params.h
@@ -237,6 +246,7 @@ smtpd_chat.o: ../../include/vstring.h
 smtpd_chat.o: smtpd.h
 smtpd_chat.o: smtpd_chat.c
 smtpd_chat.o: smtpd_chat.h
+smtpd_chat.o: smtpd_expand.h
 smtpd_check.o: ../../include/argv.h
 smtpd_check.o: ../../include/attr.h
 smtpd_check.o: ../../include/attr_clnt.h
@@ -303,12 +313,35 @@ smtpd_check.o: smtpd.h
 smtpd_check.o: smtpd_check.c
 smtpd_check.o: smtpd_check.h
 smtpd_check.o: smtpd_dsn_fix.h
+smtpd_check.o: smtpd_expand.h
 smtpd_check.o: smtpd_resolve.h
 smtpd_check.o: smtpd_sasl_glue.h
 smtpd_dsn_fix.o: ../../include/msg.h
 smtpd_dsn_fix.o: ../../include/sys_defs.h
 smtpd_dsn_fix.o: smtpd_dsn_fix.c
 smtpd_dsn_fix.o: smtpd_dsn_fix.h
+smtpd_expand.o: ../../include/argv.h
+smtpd_expand.o: ../../include/attr.h
+smtpd_expand.o: ../../include/iostuff.h
+smtpd_expand.o: ../../include/mac_expand.h
+smtpd_expand.o: ../../include/mac_parse.h
+smtpd_expand.o: ../../include/mail_params.h
+smtpd_expand.o: ../../include/mail_proto.h
+smtpd_expand.o: ../../include/mail_stream.h
+smtpd_expand.o: ../../include/milter.h
+smtpd_expand.o: ../../include/msg.h
+smtpd_expand.o: ../../include/myaddrinfo.h
+smtpd_expand.o: ../../include/name_code.h
+smtpd_expand.o: ../../include/name_mask.h
+smtpd_expand.o: ../../include/stringops.h
+smtpd_expand.o: ../../include/sys_defs.h
+smtpd_expand.o: ../../include/tls.h
+smtpd_expand.o: ../../include/vbuf.h
+smtpd_expand.o: ../../include/vstream.h
+smtpd_expand.o: ../../include/vstring.h
+smtpd_expand.o: smtpd.h
+smtpd_expand.o: smtpd_expand.c
+smtpd_expand.o: smtpd_expand.h
 smtpd_milter.o: ../../include/argv.h
 smtpd_milter.o: ../../include/attr.h
 smtpd_milter.o: ../../include/mail_params.h
index 638cc95a00fc96eb3275cfc3afbecf11b825a91a..0026c25712784054dfd59899ea6206a11b57d0c3 100644 (file)
 /* .IP "\fBsmtpd_sasl_tls_security_options ($smtpd_sasl_security_options)\fR"
 /*     The SASL authentication security options that the Postfix SMTP
 /*     server uses for TLS encrypted SMTP sessions.
-/* .IP "\fBsmtpd_starttls_timeout (300s)\fR"
+/* .IP "\fBsmtpd_starttls_timeout (see 'postconf -d' output)\fR"
 /*     The time limit for Postfix SMTP server write and read operations
 /*     during TLS startup and shutdown handshake procedures.
 /* .IP "\fBsmtpd_tls_CAfile (empty)\fR"
 /*     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 "\fBsoft_bounce (no)\fR"
 /*     Safety net to keep mail queued that would otherwise be returned to
 /*     the sender.
 #include <valid_mailhost_addr.h>
 #include <dsn_mask.h>
 #include <xtext.h>
+#include <tls_proxy.h>
 
 /* Single-threaded server skeleton. */
 
 #include <smtpd_sasl_glue.h>
 #include <smtpd_proxy.h>
 #include <smtpd_milter.h>
+#include <smtpd_expand.h>
 
  /*
   * Tunable parameters. Make sure that there is some bound on the length of
@@ -1182,6 +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;
 
 #ifdef USE_TLS
 char   *var_smtpd_relay_ccerts;
@@ -1324,8 +1330,6 @@ static int ask_client_cert;
 
 #endif
 
-static int enforce_tls;
-
  /*
   * SMTP command mapping for broken clients.
   */
@@ -1640,7 +1644,7 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
        ENQUEUE_FIX_REPLY(state, reply_buf, SMTPD_CMD_ETRN);
 #ifdef USE_TLS
     if ((discard_mask & EHLO_MASK_STARTTLS) == 0)
-       if ((state->tls_use_tls || state->tls_enforce_tls) && (!state->tls_context))
+       if (var_smtpd_use_tls && (!state->tls_context))
            ENQUEUE_FIX_REPLY(state, reply_buf, SMTPD_CMD_STARTTLS);
 #endif
 #ifdef USE_SASL_AUTH
@@ -3958,11 +3962,11 @@ static void smtpd_start_tls(SMTPD_STATE *state)
     } while (0)
 
     if (cipher_grade == 0) {
-       cipher_grade =
-           enforce_tls ? var_smtpd_tls_mand_ciph : var_smtpd_tls_ciph;
+       cipher_grade = var_smtpd_enforce_tls ?
+           var_smtpd_tls_mand_ciph : var_smtpd_tls_ciph;
        cipher_exclusions = vstring_alloc(10);
        ADD_EXCLUDE(cipher_exclusions, var_smtpd_tls_excl_ciph);
-       if (enforce_tls)
+       if (var_smtpd_enforce_tls)
            ADD_EXCLUDE(cipher_exclusions, var_smtpd_tls_mand_excl);
        if (ask_client_cert)
            ADD_EXCLUDE(cipher_exclusions, "aNULL");
@@ -3979,7 +3983,7 @@ static void smtpd_start_tls(SMTPD_STATE *state)
                         log_level = var_smtpd_tls_loglevel,
                         timeout = var_smtpd_starttls_tmout,
                         requirecert = (var_smtpd_tls_req_ccert
-                                       && state->tls_enforce_tls),
+                                       && var_smtpd_enforce_tls),
                         serverid = state->service,
                         namaddr = state->namaddr,
                         cipher_grade = cipher_grade,
@@ -4079,6 +4083,11 @@ 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");
@@ -4102,18 +4111,20 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
        smtpd_chat_reply(state, "554 5.5.1 Error: TLS already active");
        return (-1);
     }
-    if (state->tls_use_tls == 0
+    if (var_smtpd_use_tls == 0
        || (state->ehlo_discard_mask & EHLO_MASK_STARTTLS)) {
        state->error_mask |= MAIL_ERROR_PROTOCOL;
        smtpd_chat_reply(state, "502 5.5.1 Error: command not implemented");
        return (-1);
     }
+#ifndef USE_TLS_PROXY
     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
 
     /*
      * Enforce TLS handshake rate limit when this client negotiated too many
@@ -4139,9 +4150,11 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
                         state->namaddr);
        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. */
     smtp_flush(state->client);
+    vstream_fpurge(state->client, VSTREAM_PURGE_READ); /* Yay! */
 
     /*
      * Reset all inputs to the initial state.
@@ -4159,6 +4172,73 @@ 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 */
@@ -4174,8 +4254,12 @@ 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
        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;
     }
 }
@@ -4294,6 +4378,9 @@ 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.");
+#else                                          /* USE_TLSPROXY */
            if (smtpd_tls_ctx == 0) {
                msg_warn("Wrapper-mode request dropped from %s for service %s."
                       " TLS context initialization failed. For details see"
@@ -4314,6 +4401,7 @@ static void smtpd_proto(SMTPD_STATE *state)
                break;
            }
            smtpd_start_tls(state);
+#endif                                         /* USE_TLSPROXY */
        }
 #endif
 
@@ -4473,7 +4561,7 @@ static void smtpd_proto(SMTPD_STATE *state)
 #ifdef USE_SASL_AUTH
        if (var_smtpd_sasl_enable && smtpd_sasl_is_active(state) == 0
 #ifdef USE_TLS
-           && state->tls_context == 0 && !state->tls_auth_only
+           && state->tls_context == 0 && !var_smtpd_tls_auth_only
 #else
            && var_smtpd_tls_auth_only == 0
 #endif
@@ -4558,7 +4646,7 @@ static void smtpd_proto(SMTPD_STATE *state)
                continue;
            }
 #ifdef USE_TLS
-           if (state->tls_enforce_tls &&
+           if (var_smtpd_enforce_tls &&
                !state->tls_context &&
                (cmdp->flags & SMTPD_CMD_FLAG_PRE_TLS) == 0) {
                smtpd_chat_reply(state,
@@ -4674,26 +4762,13 @@ static void smtpd_service(VSTREAM *stream, char *service, char **argv)
     msg_info("connect from %s", state.namaddr);
 
     /*
-     * With TLS wrapper mode, we run on a dedicated port and turn on TLS
-     * before actually speaking the SMTP protocol. This implies TLS enforce
-     * mode.
-     * 
-     * With non-wrapper mode, TLS enforce mode implies that we don't advertise
-     * AUTH before the client issues STARTTLS.
+     * Disable TLS when running in stand-alone mode via "sendmail -bs".
      */
-#ifdef USE_TLS
-    if (!SMTPD_STAND_ALONE((&state))) {
-       if (var_smtpd_tls_wrappermode) {
-           state.tls_use_tls = 1;
-           state.tls_enforce_tls = 1;
-       } else {
-           state.tls_use_tls = var_smtpd_use_tls | var_smtpd_enforce_tls;
-           state.tls_enforce_tls = var_smtpd_enforce_tls;
-       }
-       if (var_smtpd_tls_auth_only || state.tls_enforce_tls)
-           state.tls_auth_only = 1;
+    if (SMTPD_STAND_ALONE((&state))) {
+       var_smtpd_use_tls = 0;
+       var_smtpd_enforce_tls = 0;
+       var_smtpd_tls_auth_only = 0;
     }
-#endif
 
     /*
      * XCLIENT must not override its own access control.
@@ -4742,7 +4817,6 @@ static void pre_accept(char *unused_name, char **unused_argv)
 
 static void pre_jail_init(char *unused_name, char **unused_argv)
 {
-    int     use_tls;
 
     /*
      * Initialize blacklist/etc. patterns before entering the chroot jail, in
@@ -4767,6 +4841,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
      */
     if (getuid() == 0 || getuid() == var_owner_uid)
        smtpd_check_init();
+    smtpd_expand_init();
     debug_peer_init();
 
     if (var_smtpd_sasl_enable)
@@ -4818,8 +4893,18 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
            break;
        }
     }
-    enforce_tls = var_smtpd_tls_wrappermode || var_smtpd_enforce_tls;
-    use_tls = var_smtpd_use_tls || enforce_tls;
+
+    /*
+     * With TLS wrapper mode, we run on a dedicated port and turn on TLS
+     * before actually speaking the SMTP protocol. This implies TLS enforce
+     * mode.
+     * 
+     * With non-wrapper mode, TLS enforce mode implies that we don't advertise
+     * AUTH before the client issues STARTTLS.
+     */
+    var_smtpd_enforce_tls = var_smtpd_tls_wrappermode || var_smtpd_enforce_tls;
+    var_smtpd_tls_auth_only = var_smtpd_tls_auth_only || var_smtpd_enforce_tls;
+    var_smtpd_use_tls = var_smtpd_use_tls || var_smtpd_enforce_tls;
 
     /*
      * Keys can only be loaded when running with suitable permissions. When
@@ -4827,7 +4912,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
      * announce STARTTLS support.
      */
     if (getuid() == 0 || getuid() == var_owner_uid) {
-       if (use_tls) {
+       if (var_smtpd_use_tls) {
 #ifdef USE_TLS
            TLS_SERVER_INIT_PROPS props;
            const char *cert_file;
@@ -4843,7 +4928,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
             */
            ask_client_cert = require_server_cert =
                (var_smtpd_tls_ask_ccert
-                || (enforce_tls && var_smtpd_tls_req_ccert));
+                || (var_smtpd_enforce_tls && var_smtpd_tls_req_ccert));
            if (strcasecmp(var_smtpd_tls_cert_file, "none") == 0) {
                no_server_cert_ok = 1;
                cert_file = "";
@@ -4857,7 +4942,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
            /* Some TLS configuration errors are not show stoppers. */
            if (!have_server_cert && require_server_cert)
                msg_warn("Need a server cert to request client certs");
-           if (!enforce_tls && var_smtpd_tls_req_ccert)
+           if (!var_smtpd_enforce_tls && var_smtpd_tls_req_ccert)
                msg_warn("Can't require client certs unless TLS is required");
            /* After a show-stopper error, reply with 454 to STARTTLS. */
            if (have_server_cert || (no_server_cert_ok && !require_server_cert))
@@ -4888,7 +4973,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
                                    dh512_param_file
                                    = var_smtpd_tls_dh512_param_file,
                                    eecdh_grade = var_smtpd_tls_eecdh,
-                                   protocols = enforce_tls ?
+                                   protocols = var_smtpd_enforce_tls ?
                                    var_smtpd_tls_mand_proto :
                                    var_smtpd_tls_proto,
                                    ask_ccert = ask_client_cert,
@@ -5175,6 +5260,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,
        0,
     };
 
index 931dcbcfd4dd7b4b20582b154a48a19d0cb2a7c5..9b98ac7d3a05d2ffde5806f8eaa3e49f11fd7b31 100644 (file)
@@ -165,9 +165,6 @@ typedef struct {
      * TLS related state.
      */
 #ifdef USE_TLS
-    int     tls_use_tls;               /* can use TLS */
-    int     tls_enforce_tls;           /* must use TLS */
-    int     tls_auth_only;             /* use SASL over TLS only */
     TLS_SESS_STATE *tls_context;       /* TLS session state */
 #endif
 
index fac66d3d6fd9dc1289a9faf9e42dc1328c8a4f25..72f17fd431c892a00c014d379270d5e2d86ac24a 100644 (file)
 #include <mail_addr.h>
 #include <post_mail.h>
 #include <mail_error.h>
+#include <dsn_util.h>
 
 /* Application-specific. */
 
 #include "smtpd.h"
+#include "smtpd_expand.h"
 #include "smtpd_chat.h"
 
 #define STR    vstring_str
@@ -145,6 +147,7 @@ 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
@@ -153,9 +156,48 @@ 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;
+       }
+    }
     /* 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) {
@@ -168,6 +210,7 @@ void    smtpd_chat_reply(SMTPD_STATE *state, const char *format,...)
        /* This is why we use strlen() above instead of VSTRING_LEN(). */
        if ((next = strstr(cp, "\r\n")) != 0) {
            *next = 0;
+           cp[3] = '-';                        /* contact footer kludge */
        } else {
            next = end;
        }
index c1b2330bffb84aaa578cfd29da18732a80a27e8c..e381a36f3bddd9f418135b5c606abf45879f8c6e 100644 (file)
 #include "smtpd_check.h"
 #include "smtpd_dsn_fix.h"
 #include "smtpd_resolve.h"
+#include "smtpd_expand.h"
 
 #define RESTRICTION_SEPARATORS ", \t\r\n"
 
@@ -331,11 +332,6 @@ static HTABLE *policy_clnt_table;
 
 static ARGV *local_rewrite_clients;
 
- /*
-  * Pre-parsed expansion filter.
-  */
-static VSTRING *expand_filter;
-
  /*
   * The routine that recursively applies restrictions.
   */
@@ -704,12 +700,6 @@ void    smtpd_check_init(void)
        fail_required(VAR_RCPT_CHECKS, rcpt_required);
 #endif
 
-    /*
-     * Expand the expansion filter :-)
-     */
-    expand_filter = vstring_alloc(10);
-    unescape(expand_filter, var_smtpd_exp_filter);
-
     /*
      * Local rewrite policy.
      */
@@ -2828,123 +2818,6 @@ static int check_mail_access(SMTPD_STATE *state, const char *table,
     CHECK_MAIL_ACCESS_RETURN(SMTPD_CHECK_DUNNO);
 }
 
-/* smtpd_expand_unknown - report unknown macro name */
-
-static void smtpd_expand_unknown(const char *name)
-{
-    msg_warn("unknown macro name \"%s\" in expansion request", name);
-}
-
-/* smtpd_expand_addr - return address or substring thereof */
-
-static const char *smtpd_expand_addr(VSTRING *buf, const char *addr,
-                                          const char *name, int prefix_len)
-{
-    const char *p;
-    const char *suffix;
-
-    /*
-     * Return NULL only for unknown names in expansion requests.
-     */
-    if (addr == 0)
-       return ("");
-
-    suffix = name + prefix_len;
-
-    /*
-     * MAIL_ATTR_SENDER or MAIL_ATTR_RECIP.
-     */
-    if (*suffix == 0) {
-       if (*addr)
-           return (addr);
-       else
-           return ("<>");
-    }
-
-    /*
-     * "sender_name" or "recipient_name".
-     */
-#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
-
-    else if (STREQ(suffix, MAIL_ATTR_S_NAME)) {
-       if (*addr) {
-           if ((p = strrchr(addr, '@')) != 0) {
-               vstring_strncpy(buf, addr, p - addr);
-               return (STR(buf));
-           } else {
-               return (addr);
-           }
-       } else
-           return ("<>");
-    }
-
-    /*
-     * "sender_domain" or "recipient_domain".
-     */
-    else if (STREQ(suffix, MAIL_ATTR_S_DOMAIN)) {
-       if (*addr) {
-           if ((p = strrchr(addr, '@')) != 0) {
-               return (p + 1);
-           } else {
-               return ("");
-           }
-       } else
-           return ("");
-    }
-
-    /*
-     * Unknown. Return NULL to indicate an "unknown name" error.
-     */
-    else {
-       smtpd_expand_unknown(name);
-       return (0);
-    }
-}
-
-/* smtpd_expand_lookup - generic SMTP attribute $name expansion */
-
-static const char *smtpd_expand_lookup(const char *name, int unused_mode,
-                                              char *context)
-{
-    SMTPD_STATE *state = (SMTPD_STATE *) context;
-
-    if (state->expand_buf == 0)
-       state->expand_buf = vstring_alloc(10);
-
-    if (msg_verbose > 1)
-       msg_info("smtpd_expand_lookup: ${%s}", name);
-
-#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.
-     * 
-     * Return NULL only for non-existent names.
-     */
-    if (STREQ(name, MAIL_ATTR_ACT_CLIENT)) {
-       return (state->namaddr);
-    } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_ADDR)) {
-       return (state->addr);
-    } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_NAME)) {
-       return (state->name);
-    } else if (STREQ(name, MAIL_ATTR_ACT_REVERSE_CLIENT_NAME)) {
-       return (state->reverse_name);
-    } else if (STREQ(name, MAIL_ATTR_ACT_HELO_NAME)) {
-       return (state->helo_name ? state->helo_name : "");
-    } else if (STREQN(name, MAIL_ATTR_SENDER, CONST_LEN(MAIL_ATTR_SENDER))) {
-       return (smtpd_expand_addr(state->expand_buf, state->sender,
-                                 name, CONST_LEN(MAIL_ATTR_SENDER)));
-    } else if (STREQN(name, MAIL_ATTR_RECIP, CONST_LEN(MAIL_ATTR_RECIP))) {
-       return (smtpd_expand_addr(state->expand_buf, state->recipient,
-                                 name, CONST_LEN(MAIL_ATTR_RECIP)));
-    } else {
-       smtpd_expand_unknown(name);
-       return (0);
-    }
-}
-
 /* Support for different DNSXL lookup results. */
 
 static SMTPD_RBL_STATE dnsxl_stat_soft[1];
@@ -3061,6 +2934,8 @@ static const char *rbl_expand_lookup(const char *name, int mode,
     SMTPD_RBL_EXPAND_CONTEXT *rbl_exp = (SMTPD_RBL_EXPAND_CONTEXT *) context;
     SMTPD_STATE *state = rbl_exp->state;
 
+#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
+
     if (state->expand_buf == 0)
        state->expand_buf = vstring_alloc(10);
 
@@ -3121,7 +2996,7 @@ static int rbl_reject_reply(SMTPD_STATE *state, const SMTPD_RBL_STATE *rbl,
        if (template == 0)
            template = var_def_rbl_reply;
        if (mac_expand(why, template, MAC_EXP_FLAG_NONE,
-                      STR(expand_filter), rbl_expand_lookup,
+                      STR(smtpd_expand_filter), rbl_expand_lookup,
                       (char *) &rbl_exp) == 0)
            break;
        if (template == var_def_rbl_reply)
diff --git a/postfix/src/smtpd/smtpd_expand.c b/postfix/src/smtpd/smtpd_expand.c
new file mode 100644 (file)
index 0000000..6683f4e
--- /dev/null
@@ -0,0 +1,238 @@
+/*++
+/* NAME
+/*     smtpd_expand 3
+/* SUMMARY
+/*     SMTP server macro expansion
+/* SYNOPSIS
+/*     #include <smtpd.h>
+/*     #include <smtpd_expand.h>
+/*
+/*     void    smtpd_expand_init()
+/*
+/*     int     smtpd_expand(state, result, template, flags)
+/*     SMTPD_STATE *state;
+/*     VSTRING *result;
+/*     const char *template;
+/*     int     flags;
+/* LOW_LEVEL INTERFACE
+/*     VSTRING *smtpd_expand_filter;
+/*
+/*     const char *smtpd_expand_lookup(name, unused_mode, context)
+/*     const char *name;
+/*     int     unused_mode;
+/*     char    *context;
+/*     const char *template;
+/* DESCRIPTION
+/*     This module expands session-related macros.
+/*
+/*     smtpd_expand_init() performs one-time initialization.
+/*
+/*     smtpd_expand() expands macros in the template, using session
+/*     attributes in the state argument, and writes the result to
+/*     the result argument. The flags and result value are as with
+/*     mac_expand().
+/*
+/*     smtpd_expand_filter and smtpd_expand_lookup() provide access
+/*     to lower-level interfaces that are used by smtpd_expand().
+/*     smtpd_expand_lookup() returns null when a string is not
+/*     found (or when it is a null pointer).
+/* DIAGNOSTICS
+/*     Panic: interface violations. Fatal errors: out of memory.
+/*     internal protocol errors. smtpd_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 <mac_expand.h>
+#include <stringops.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+#include <mail_proto.h>
+
+/* Application-specific. */
+
+#include <smtpd.h>
+#include <smtpd_expand.h>
+
+ /*
+  * Pre-parsed expansion filter.
+  */
+VSTRING *smtpd_expand_filter;
+
+ /*
+  * SLMs.
+  */
+#define STR    vstring_str
+
+/* smtpd_expand_init - initialize once during process lifetime */
+
+void    smtpd_expand_init(void)
+{
+
+    /*
+     * Expand the expansion filter :-)
+     */
+    smtpd_expand_filter = vstring_alloc(10);
+    unescape(smtpd_expand_filter, var_smtpd_exp_filter);
+}
+
+/* smtpd_expand_unknown - report unknown macro name */
+
+static void smtpd_expand_unknown(const char *name)
+{
+    msg_warn("unknown macro name \"%s\" in expansion request", name);
+}
+
+/* smtpd_expand_addr - return address or substring thereof */
+
+static const char *smtpd_expand_addr(VSTRING *buf, const char *addr,
+                                          const char *name, int prefix_len)
+{
+    const char *p;
+    const char *suffix;
+
+    /*
+     * Return NULL only for unknown names in expansion requests.
+     */
+    if (addr == 0)
+       return ("");
+
+    suffix = name + prefix_len;
+
+    /*
+     * MAIL_ATTR_SENDER or MAIL_ATTR_RECIP.
+     */
+    if (*suffix == 0) {
+       if (*addr)
+           return (addr);
+       else
+           return ("<>");
+    }
+
+    /*
+     * "sender_name" or "recipient_name".
+     */
+#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0)
+
+    else if (STREQ(suffix, MAIL_ATTR_S_NAME)) {
+       if (*addr) {
+           if ((p = strrchr(addr, '@')) != 0) {
+               vstring_strncpy(buf, addr, p - addr);
+               return (STR(buf));
+           } else {
+               return (addr);
+           }
+       } else
+           return ("<>");
+    }
+
+    /*
+     * "sender_domain" or "recipient_domain".
+     */
+    else if (STREQ(suffix, MAIL_ATTR_S_DOMAIN)) {
+       if (*addr) {
+           if ((p = strrchr(addr, '@')) != 0) {
+               return (p + 1);
+           } else {
+               return ("");
+           }
+       } else
+           return ("");
+    }
+
+    /*
+     * Unknown. Return NULL to indicate an "unknown name" error.
+     */
+    else {
+       smtpd_expand_unknown(name);
+       return (0);
+    }
+}
+
+/* smtpd_expand_lookup - generic SMTP attribute $name expansion */
+
+const char *smtpd_expand_lookup(const char *name, int unused_mode,
+                                       char *context)
+{
+    SMTPD_STATE *state = (SMTPD_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("smtpd_expand_lookup: ${%s}", name);
+
+#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.
+     * 
+     * Return NULL only for non-existent names.
+     */
+    if (STREQ(name, MAIL_ATTR_ACT_CLIENT)) {
+       return (state->namaddr);
+    } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_PORT)) {
+       return (state->port);
+    } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_ADDR)) {
+       return (state->addr);
+    } else if (STREQ(name, MAIL_ATTR_ACT_CLIENT_NAME)) {
+       return (state->name);
+    } else if (STREQ(name, MAIL_ATTR_ACT_REVERSE_CLIENT_NAME)) {
+       return (state->reverse_name);
+    } else if (STREQ(name, MAIL_ATTR_ACT_HELO_NAME)) {
+       return (state->helo_name ? state->helo_name : "");
+    } else if (STREQN(name, MAIL_ATTR_SENDER, CONST_LEN(MAIL_ATTR_SENDER))) {
+       return (smtpd_expand_addr(state->expand_buf, state->sender,
+                                 name, CONST_LEN(MAIL_ATTR_SENDER)));
+    } else if (STREQN(name, MAIL_ATTR_RECIP, CONST_LEN(MAIL_ATTR_RECIP))) {
+       return (smtpd_expand_addr(state->expand_buf, state->recipient,
+                                 name, CONST_LEN(MAIL_ATTR_RECIP)));
+    } 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 {
+       smtpd_expand_unknown(name);
+       return (0);
+    }
+}
+
+/* smtpd_expand - expand session attributes in string */
+
+int     smtpd_expand(SMTPD_STATE *state, VSTRING *result,
+                            const char *template, int flags)
+{
+    return (mac_expand(result, template, flags, STR(smtpd_expand_filter),
+                      smtpd_expand_lookup, (char *) state));
+}
diff --git a/postfix/src/smtpd/smtpd_expand.h b/postfix/src/smtpd/smtpd_expand.h
new file mode 100644 (file)
index 0000000..7c0f838
--- /dev/null
@@ -0,0 +1,35 @@
+/*++
+/* NAME
+/*     smtpd_expand 3h
+/* SUMMARY
+/*     SMTP server macro expansion
+/* SYNOPSIS
+/*     #include <smtpd.h>
+/*     #include <smtpd_expand.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstring.h>
+#include <mac_expand.h>
+
+ /*
+  * External interface.
+  */
+VSTRING *smtpd_expand_filter;
+void    smtpd_expand_init(void);
+const char *smtpd_expand_lookup(const char *, int, char *);
+int     smtpd_expand(SMTPD_STATE *, VSTRING *, const char *, int);
+
+/* 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
+/*--*/
index 9fcdc1ed04d4e5c4a80b5cc90a6ece1fc4ff3c17..f419dc6bbcb8874f03d3fe9b0ecb8ffa96464944 100644 (file)
@@ -166,7 +166,7 @@ int     smtpd_sasl_auth_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
        }
     }
 #ifdef USE_TLS
-    if (state->tls_auth_only && !state->tls_context) {
+    if (var_smtpd_tls_auth_only && !state->tls_context) {
        state->error_mask |= MAIL_ERROR_PROTOCOL;
        /* RFC 4954, Section 4. */
        smtpd_chat_reply(state, "504 5.5.4 Encryption required for requested authentication mechanism");
index 24091fa610c4f1a634d2e615b16fe65931d2b242..8dc77a0b0fb07b58003e8a08ea790f357e3c3316 100644 (file)
@@ -138,9 +138,6 @@ 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
-    state->tls_use_tls = 0;
-    state->tls_enforce_tls = 0;
-    state->tls_auth_only = 0;
     state->tls_context = 0;
 #endif
 
index 74c04bcaa6e3b828c9f0fdc9bbdef366922bdd9b..f47ae4ec62522234ab86495c13dc604e900d6583 100644 (file)
@@ -3,13 +3,15 @@ SRCS  = tls_prng_dev.c tls_prng_egd.c tls_prng_file.c \
        tls_prng_exch.c tls_stream.c tls_bio_ops.c tls_misc.c tls_dh.c \
        tls_rsa.c tls_verify.c tls_certkey.c tls_session.c \
        tls_client.c tls_server.c tls_scache.c tls_mgr.c tls_seed.c \
-       tls_level.c
+       tls_level.c \
+       tls_proxy_clnt.c tls_proxy_print.c tls_proxy_scan.c
 OBJS   = tls_prng_dev.o tls_prng_egd.o tls_prng_file.o \
        tls_prng_exch.o tls_stream.o tls_bio_ops.o tls_misc.o tls_dh.o \
        tls_rsa.o tls_verify.o tls_certkey.o tls_session.o \
        tls_client.o tls_server.o tls_scache.o tls_mgr.o tls_seed.o \
-       tls_level.o
-HDRS   = tls.h tls_prng.h tls_scache.h tls_mgr.h
+       tls_level.o \
+       tls_proxy_clnt.o tls_proxy_print.o tls_proxy_scan.o
+HDRS   = tls.h tls_prng.h tls_scache.h tls_mgr.h tls_proxy.h
 TESTSRC        = 
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@@ -200,6 +202,49 @@ tls_prng_file.o: ../../include/mymalloc.h
 tls_prng_file.o: ../../include/sys_defs.h
 tls_prng_file.o: tls_prng.h
 tls_prng_file.o: tls_prng_file.c
+tls_proxy_clnt.o: ../../include/argv.h
+tls_proxy_clnt.o: ../../include/attr.h
+tls_proxy_clnt.o: ../../include/connect.h
+tls_proxy_clnt.o: ../../include/iostuff.h
+tls_proxy_clnt.o: ../../include/mail_proto.h
+tls_proxy_clnt.o: ../../include/msg.h
+tls_proxy_clnt.o: ../../include/mymalloc.h
+tls_proxy_clnt.o: ../../include/name_code.h
+tls_proxy_clnt.o: ../../include/name_mask.h
+tls_proxy_clnt.o: ../../include/stringops.h
+tls_proxy_clnt.o: ../../include/sys_defs.h
+tls_proxy_clnt.o: ../../include/vbuf.h
+tls_proxy_clnt.o: ../../include/vstream.h
+tls_proxy_clnt.o: ../../include/vstring.h
+tls_proxy_clnt.o: tls.h
+tls_proxy_clnt.o: tls_proxy.h
+tls_proxy_clnt.o: tls_proxy_clnt.c
+tls_proxy_print.o: ../../include/argv.h
+tls_proxy_print.o: ../../include/attr.h
+tls_proxy_print.o: ../../include/iostuff.h
+tls_proxy_print.o: ../../include/mail_proto.h
+tls_proxy_print.o: ../../include/name_code.h
+tls_proxy_print.o: ../../include/name_mask.h
+tls_proxy_print.o: ../../include/sys_defs.h
+tls_proxy_print.o: ../../include/vbuf.h
+tls_proxy_print.o: ../../include/vstream.h
+tls_proxy_print.o: ../../include/vstring.h
+tls_proxy_print.o: tls.h
+tls_proxy_print.o: tls_proxy.h
+tls_proxy_print.o: tls_proxy_print.c
+tls_proxy_scan.o: ../../include/argv.h
+tls_proxy_scan.o: ../../include/attr.h
+tls_proxy_scan.o: ../../include/iostuff.h
+tls_proxy_scan.o: ../../include/mail_proto.h
+tls_proxy_scan.o: ../../include/name_code.h
+tls_proxy_scan.o: ../../include/name_mask.h
+tls_proxy_scan.o: ../../include/sys_defs.h
+tls_proxy_scan.o: ../../include/vbuf.h
+tls_proxy_scan.o: ../../include/vstream.h
+tls_proxy_scan.o: ../../include/vstring.h
+tls_proxy_scan.o: tls.h
+tls_proxy_scan.o: tls_proxy.h
+tls_proxy_scan.o: tls_proxy_scan.c
 tls_rsa.o: ../../include/argv.h
 tls_rsa.o: ../../include/name_code.h
 tls_rsa.o: ../../include/name_mask.h
diff --git a/postfix/src/tls/tls_proxy.h b/postfix/src/tls/tls_proxy.h
new file mode 100644 (file)
index 0000000..3cf093a
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef _TLS_PROXY_H_INCLUDED_
+#define _TLS_PROXY_H_INCLUDED_
+
+/*++
+/* NAME
+/*     tls_proxy_clnt 3h
+/* SUMMARY
+/*     postscreen TLS proxy support
+/* SYNOPSIS
+/*     #include <tls_proxy_clnt.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <vstream.h>
+#include <attr.h>
+
+ /*
+  * TLS library.
+  */
+#include <tls.h>
+
+ /*
+  * External interface.
+  */
+#define TLSPROXY_SERVICE               "tlsproxy"
+
+#define TLS_PROXY_FLAG_ROLE_SERVER     (1<<0)  /* request server role */
+#define TLS_PROXY_FLAG_ROLE_CLIENT     (1<<1)  /* request client role */
+#define TLS_PROXY_FLAG_SEND_CONTEXT    (1<<2)  /* send TLS context */
+
+#ifdef USE_TLS
+
+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 *);
+
+#endif
+
+/* 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
diff --git a/postfix/src/tls/tls_proxy_clnt.c b/postfix/src/tls/tls_proxy_clnt.c
new file mode 100644 (file)
index 0000000..9f723d2
--- /dev/null
@@ -0,0 +1,226 @@
+/*++
+/* NAME
+/*     tlsproxy_clnt 3
+/* SUMMARY
+/*     postscreen TLS proxy support
+/* SYNOPSIS
+/*     #include <tlsproxy_clnt.h>
+/*
+/*     VSTREAM *tls_proxy_open(flags, peer_stream, peer_addr,
+/*                               peer_port, timeout)
+/*     int     flags;
+/*     VSTREAM *peer_stream;
+/*     const char *peer_addr;
+/*     const char *peer_port;
+/*     int     timeout;
+/*
+/*     TLS_SESS_STATE *tls_proxy_state_receive(proxy_stream)
+/*     VSTREAM *proxy_stream;
+/*
+/*     void    tls_proxy_state_free(tls_context)
+/*     TLS_SESS_STATE *tls_context;
+/* DESCRIPTION
+/*     tls_proxy_open() prepares for inserting the tlsproxy(8)
+/*     daemon between the current process and a remote peer (the
+/*     actual insert operation is described in the next paragraph).
+/*     The result value is a null pointer on failure. The peer_stream
+/*     is not closed.  The resulting proxy stream is single-buffered.
+/*
+/*     After this, it is a good idea to use the VSTREAM_CTL_SWAP_FD
+/*     request to swap the file descriptors between the plaintext
+/*     peer_stream and the proxy stream from tls_proxy_open().
+/*     This avoids the loss of application-configurable VSTREAM
+/*     attributes on the plaintext peer_stream (such as longjmp
+/*     buffer, timeout, etc.). Once the file descriptors are
+/*     swapped, the proxy stream should be closed.
+/*
+/*     tls_proxy_state_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.
+/*
+/*     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().
+/*
+/*     Arguments:
+/* .IP flags
+/*     Bit-wise OR of:
+/* .RS
+/* .IP TLS_PROXY_FLAG_ROLE_SERVER
+/*     Request the TLS server proxy role.
+/* .IP TLS_PROXY_FLAG_ROLE_CLIENT
+/*     Request the TLS client proxy role.
+/* .IP TLS_PROXY_FLAG_SEND_CONTEXT
+/*     Send the TLS context object.
+/* .RE
+/* .IP peer_stream
+/*     Stream that connects the current process to a remote peer.
+/* .IP peer_addr
+/*     Printable IP address of the remote peer_stream endpoint.
+/* .IP peer_port
+/*     Printable TCP port of the remote peer_stream endpoint.
+/* .IP timeout
+/*     Time limit that the tlsproxy(8) daemon should use.
+/* .IP proxy_stream
+/*     Stream from tls_proxy_open().
+/* .IP tls_context
+/*     TLS session object from tls_proxy_state_receive().
+/* 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
+/*--*/
+
+#ifdef USE_TLS
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <connect.h>
+#include <stringops.h>                 /* concatenate() */
+
+/* Global library. */
+
+#include <mail_proto.h>
+
+/* TLS library-specific. */
+
+#include <tls.h>
+#include <tls_proxy.h>
+
+#define TLSPROXY_INIT_TIMEOUT          10
+
+/* tls_proxy_open - open negotiations with TLS proxy */
+
+VSTREAM *tls_proxy_open(int flags, VSTREAM *peer_stream,
+                              const char *peer_addr,
+                              const char *peer_port,
+                              int timeout)
+{
+    VSTREAM *tlsproxy_stream;
+    char   *remote_endpt;
+    int     status;
+    int     fd;
+
+    /*
+     * Connect to the tlsproxy(8) daemon. We report all errors
+     * asynchronously, to avoid having to maintain multiple delivery paths.
+     */
+    if ((fd = LOCAL_CONNECT("private/" TLSPROXY_SERVICE, BLOCKING,
+                           TLSPROXY_INIT_TIMEOUT)) < 0) {
+       msg_warn("connect to %s service: %m", TLSPROXY_SERVICE);
+       return (0);
+    }
+
+    /*
+     * Initial handshake. Send the data attributes now, and send the client
+     * file descriptor in a later transaction.
+     * 
+     * XXX The formatted endpoint should be a state member. Then, we can
+     * simplify all the format strings throughout the program.
+     */
+    tlsproxy_stream = vstream_fdopen(fd, O_RDWR);
+    remote_endpt = concatenate("[", peer_addr, "]:",
+                              peer_port, (char *) 0);
+    attr_print(tlsproxy_stream, ATTR_FLAG_NONE,
+              ATTR_TYPE_STR, MAIL_ATTR_REMOTE_ENDPT, remote_endpt,
+              ATTR_TYPE_INT, MAIL_ATTR_FLAGS, flags,
+              ATTR_TYPE_INT, MAIL_ATTR_TIMEOUT, timeout,
+              ATTR_TYPE_END);
+    myfree(remote_endpt);
+    if (vstream_fflush(tlsproxy_stream) != 0) {
+       msg_warn("error sending request to %s service: %m", TLSPROXY_SERVICE);
+       vstream_fclose(tlsproxy_stream);
+       return (0);
+    }
+
+    /*
+     * Receive the "TLS is available" indication.
+     * 
+     * This may seem out of order, but we must have a read transaction between
+     * sending the request attributes and sending the SMTP client file
+     * descriptor. We can't assume UNIX-domain socket semantics here.
+     */
+    if (attr_scan(tlsproxy_stream, ATTR_FLAG_STRICT,
+                 ATTR_TYPE_INT, MAIL_ATTR_STATUS, &status,
+                 ATTR_TYPE_END) != 1 || status == 0) {
+
+       /*
+        * The TLS proxy reports that the TLS engine is not available (due to
+        * configuration error, or other causes).
+        */
+       msg_warn("%s service role \"%s\" is not available",
+                TLSPROXY_SERVICE,
+                (flags & TLS_PROXY_FLAG_ROLE_SERVER) ? "server" :
+                (flags & TLS_PROXY_FLAG_ROLE_CLIENT) ? "client" :
+                "bogus role");
+       vstream_fclose(tlsproxy_stream);
+       return (0);
+    }
+
+    /*
+     * Send the remote SMTP client file descriptor.
+     */
+    if (LOCAL_SEND_FD(vstream_fileno(tlsproxy_stream),
+                     vstream_fileno(peer_stream)) < 0) {
+
+       /*
+        * Some error: drop the TLS proxy stream.
+        */
+       msg_warn("sending file handle to %s service: %m", TLSPROXY_SERVICE);
+       vstream_fclose(tlsproxy_stream);
+       return (0);
+    }
+    return (tlsproxy_stream);
+}
+
+/* tls_proxy_state_receive - receive TLS session object from tlsproxy(8) */
+
+TLS_SESS_STATE *tls_proxy_state_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_END) != 1) {
+       tls_proxy_state_free(tls_context);
+       return (0);
+    } else {
+       return (tls_context);
+    }
+}
+
+/* tls_proxy_state_free - destroy object from tls_proxy_state_receive() */
+
+void tls_proxy_state_free(TLS_SESS_STATE *tls_context)
+{
+    if (tls_context->peer_CN)
+       myfree(tls_context->peer_CN);
+    if (tls_context->issuer_CN)
+       myfree(tls_context->issuer_CN);
+    if (tls_context->peer_fingerprint)
+       myfree(tls_context->peer_fingerprint);
+    if (tls_context->protocol)
+       myfree((char *) tls_context->protocol);
+    if (tls_context->cipher_name)
+       myfree((char *) tls_context->cipher_name);
+    myfree((char *) tls_context);
+}
+
+#endif
diff --git a/postfix/src/tls/tls_proxy_print.c b/postfix/src/tls/tls_proxy_print.c
new file mode 100644 (file)
index 0000000..da759fd
--- /dev/null
@@ -0,0 +1,84 @@
+/*++
+/* NAME
+/*     tls_proxy_print
+/* SUMMARY
+/*     write DSN structure to stream
+/* SYNOPSIS
+/*     #include <tls_proxy.h>
+/*
+/*     int     tls_proxy_print_state(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
+/*     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, ...
+/* DIAGNOSTICS
+/*     Fatal: out of memory.
+/* 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
+/*--*/
+
+#ifdef USE_TLS
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library */
+
+#include <attr.h>
+
+/* Global library. */
+
+#include <mail_proto.h>
+
+/* TLS library. */
+
+#include <tls.h>
+#include <tls_proxy.h>
+
+/* tls_proxy_print_state - send TLS session state over stream */
+
+int     tls_proxy_print_state(ATTR_PRINT_MASTER_FN print_fn, VSTREAM *fp,
+                                     int flags, void *ptr)
+{
+    TLS_SESS_STATE *tp = (TLS_SESS_STATE *) ptr;
+    int     ret;
+
+#define STRING_OR_EMPTY(s) ((s) ? (s) : "")
+
+    ret = print_fn(fp, flags | ATTR_FLAG_MORE,
+                  ATTR_TYPE_STR, MAIL_ATTR_PEER_CN,
+                  STRING_OR_EMPTY(tp->peer_CN),
+                  ATTR_TYPE_STR, MAIL_ATTR_ISSUER_CN,
+                  STRING_OR_EMPTY(tp->issuer_CN),
+                  ATTR_TYPE_STR, MAIL_ATTR_PEER_FPT,
+                  STRING_OR_EMPTY(tp->peer_fingerprint),
+                  ATTR_TYPE_INT, MAIL_ATTR_PEER_STATUS,
+                  tp->peer_status,
+                  ATTR_TYPE_STR, MAIL_ATTR_CIPHER_PROTOCOL,
+                  STRING_OR_EMPTY(tp->protocol),
+                  ATTR_TYPE_STR, MAIL_ATTR_CIPHER_NAME,
+                  STRING_OR_EMPTY(tp->cipher_name),
+                  ATTR_TYPE_INT, MAIL_ATTR_CIPHER_USEBITS,
+                  tp->cipher_usebits,
+                  ATTR_TYPE_INT, MAIL_ATTR_CIPHER_ALGBITS,
+                  tp->cipher_algbits,
+                  ATTR_TYPE_END);
+    return (ret);
+}
+
+#endif
diff --git a/postfix/src/tls/tls_proxy_scan.c b/postfix/src/tls/tls_proxy_scan.c
new file mode 100644 (file)
index 0000000..c684727
--- /dev/null
@@ -0,0 +1,91 @@
+/*++
+/* NAME
+/*     tls_proxy_scan
+/* SUMMARY
+/*     read TLS session state from stream
+/* SYNOPSIS
+/*     #include <tls_proxy.h>
+/*
+/*     int     tls_proxy_scan_state(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
+/*     from the named stream using the specified attribute scan
+/*     routine.  tls_proxy_scan_state() is meant to be passed as
+/*     a call-back to attr_scan(), thusly:
+/*
+/*     ... ATTR_TYPE_FUNC, tls_proxy_scan_state, (void *) tls_context, ...
+/* DIAGNOSTICS
+/*     Fatal: out of memory.
+/* 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
+/*--*/
+
+#ifdef USE_TLS
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library */
+
+#include <attr.h>
+
+/* Global library. */
+
+#include <mail_proto.h>
+
+/* TLS library. */
+
+#include <tls.h>
+#include <tls_proxy.h>
+
+/* tls_proxy_scan_state - receive TLS session state from stream */
+
+int     tls_proxy_scan_state(ATTR_SCAN_MASTER_FN scan_fn, VSTREAM *fp,
+                                    int flags, void *ptr)
+{
+    TLS_SESS_STATE *tls_context = (TLS_SESS_STATE *) ptr;
+    int     ret;
+    VSTRING *peer_CN = vstring_alloc(25);
+    VSTRING *issuer_CN = vstring_alloc(25);
+    VSTRING *peer_fingerprint = vstring_alloc(25);
+    VSTRING *protocol = vstring_alloc(25);
+    VSTRING *cipher_name = vstring_alloc(25);
+
+    /*
+     * Note: memset() is not a portable way to initialize non-integer types.
+     */
+    memset(ptr, 0, sizeof(TLS_SESS_STATE));
+    ret = scan_fn(fp, flags | ATTR_FLAG_MORE,
+                 ATTR_TYPE_STR, MAIL_ATTR_PEER_CN, peer_CN,
+                 ATTR_TYPE_STR, MAIL_ATTR_ISSUER_CN, issuer_CN,
+                 ATTR_TYPE_STR, MAIL_ATTR_PEER_FPT, peer_fingerprint,
+                 ATTR_TYPE_INT, MAIL_ATTR_PEER_STATUS,
+                 &tls_context->peer_status,
+                 ATTR_TYPE_STR, MAIL_ATTR_CIPHER_PROTOCOL, protocol,
+                 ATTR_TYPE_STR, MAIL_ATTR_CIPHER_NAME, cipher_name,
+                 ATTR_TYPE_INT, MAIL_ATTR_CIPHER_USEBITS,
+                 &tls_context->cipher_usebits,
+                 ATTR_TYPE_INT, MAIL_ATTR_CIPHER_ALGBITS,
+                 &tls_context->cipher_algbits,
+                 ATTR_TYPE_END);
+    tls_context->peer_CN = vstring_export(peer_CN);
+    tls_context->issuer_CN = vstring_export(issuer_CN);
+    tls_context->peer_fingerprint = vstring_export(peer_fingerprint);
+    tls_context->protocol = vstring_export(protocol);
+    tls_context->cipher_name = vstring_export(cipher_name);
+    return (ret == 8 ? 1 : -1);
+}
+
+#endif
index 9b21b01d92988b3475c21fc039efe0cf56f16587..eb75dc5b702bc5a30932213a8bec9b37dc0b5361 100644 (file)
@@ -74,6 +74,7 @@ tlsproxy.o: ../../include/name_mask.h
 tlsproxy.o: ../../include/nbbio.h
 tlsproxy.o: ../../include/sys_defs.h
 tlsproxy.o: ../../include/tls.h
+tlsproxy.o: ../../include/tls_proxy.h
 tlsproxy.o: ../../include/vbuf.h
 tlsproxy.o: ../../include/vstream.h
 tlsproxy.o: ../../include/vstring.h
index a7351e6a31d99b7a590c55474edaa07def6701cf..8786f29bfb88ec572a384ffc8b13bbddcec8d1f5 100644 (file)
 #ifdef USE_TLS
 #define TLS_INTERNAL                   /* XXX */
 #include <tls.h>
+#include <tls_proxy.h>
 
  /*
   * Application-specific.
@@ -292,8 +293,6 @@ int     var_tlsp_watchdog;
   */
 static TLS_APPL_STATE *tlsp_server_ctx;
 static int ask_client_cert;
-static int enforce_tls;
-static int tlsp_tls_enforce_tls;
 
  /*
   * SLMs.
@@ -468,6 +467,15 @@ static void tlsp_strategy(TLSP_STATE *state)
            tlsp_state_free(state);
            return;
        }
+       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,
+                          (char *) state->tls_context, ATTR_TYPE_END) != 0
+               || vstream_fflush(state->plaintext_stream) != 0)) {
+           msg_warn("cannot send TLS context: %m");
+           tlsp_state_free(state);
+           return;
+       }
        state->flags &= ~TLSP_FLAG_DO_HANDSHAKE;
     }
 
@@ -630,7 +638,7 @@ static void tlsp_ciphertext_event(int event, char *context)
            msg_warn("deadlock on plaintext stream for %s",
                     state->remote_endpt);
        else
-           msg_warn("read/write %s for %s",
+           msg_warn("ciphertext read/write %s for %s",
                     event == EVENT_TIME ? "timeout" : "error",
                     state->remote_endpt);
        tlsp_state_free(state);
@@ -668,10 +676,10 @@ static void tlsp_start_tls(TLSP_STATE *state)
 
     if (cipher_grade == 0) {
        cipher_grade =
-           enforce_tls ? var_tlsp_tls_mand_ciph : var_tlsp_tls_ciph;
+           var_tlsp_enforce_tls ? var_tlsp_tls_mand_ciph : var_tlsp_tls_ciph;
        cipher_exclusions = vstring_alloc(10);
        ADD_EXCLUDE(cipher_exclusions, var_tlsp_tls_excl_ciph);
-       if (enforce_tls)
+       if (var_tlsp_enforce_tls)
            ADD_EXCLUDE(cipher_exclusions, var_tlsp_tls_mand_excl);
        if (ask_client_cert)
            ADD_EXCLUDE(cipher_exclusions, "aNULL");
@@ -683,7 +691,7 @@ static void tlsp_start_tls(TLSP_STATE *state)
                         log_level = var_tlsp_tls_loglevel,
                         timeout = 0,           /* unused */
                         requirecert = (var_tlsp_tls_req_ccert
-                                       && tlsp_tls_enforce_tls),
+                                       && var_tlsp_enforce_tls),
                         serverid = state->service,
                         namaddr = state->remote_endpt,
                         cipher_grade = cipher_grade,
@@ -779,17 +787,15 @@ static void tlsp_get_request_event(int event, char *context)
     VSTREAM *plaintext_stream = state->plaintext_stream;
     int     plaintext_fd = vstream_fileno(plaintext_stream);
     static VSTRING *remote_endpt;
-    static VSTRING *role;
+    int     req_flags;
     int     timeout;
     int     ready;
 
     /*
      * One-time initialization.
      */
-    if (remote_endpt == 0) {
+    if (remote_endpt == 0)
        remote_endpt = vstring_alloc(10);
-       role = vstring_alloc(10);
-    }
 
     /*
      * At this point we still manually manage plaintext read/write/timeout
@@ -807,7 +813,7 @@ static void tlsp_get_request_event(int event, char *context)
     if (event != EVENT_READ
        || attr_scan(plaintext_stream, ATTR_FLAG_STRICT,
                     ATTR_TYPE_STR, MAIL_ATTR_REMOTE_ENDPT, remote_endpt,
-                    ATTR_TYPE_STR, MAIL_ATTR_ROLE, role,
+                    ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &req_flags,
                     ATTR_TYPE_INT, MAIL_ATTR_TIMEOUT, &timeout,
                     ATTR_TYPE_END) != 3) {
        msg_warn("%s: receive request attributes: %m", myname);
@@ -820,7 +826,7 @@ static void tlsp_get_request_event(int event, char *context)
      * If the requested TLS engine is unavailable, hang up after making sure
      * that the plaintext peer has received our "sorry" indication.
      */
-    ready = (strcmp(STR(role), MAIL_ATTR_ROLE_SERVER) == 0
+    ready = ((req_flags & TLS_PROXY_FLAG_ROLE_SERVER) != 0
             && tlsp_server_ctx != 0);
     if (attr_print(plaintext_stream, ATTR_FLAG_NONE,
                   ATTR_TYPE_INT, MAIL_ATTR_STATUS, ready,
@@ -841,7 +847,11 @@ static void tlsp_get_request_event(int event, char *context)
      */
     else {
        state->remote_endpt = mystrdup(STR(remote_endpt));
-       msg_info("CONNECT %s", state->remote_endpt);
+       msg_info("CONNECT %s %s",
+                (req_flags & TLS_PROXY_FLAG_ROLE_SERVER) ? "from" :
+                (req_flags & TLS_PROXY_FLAG_ROLE_CLIENT) ? "to" :
+                "(bogus direction)", state->remote_endpt);
+       state->req_flags = req_flags;
        state->timeout = timeout + 10;          /* XXX */
        event_enable_read(plaintext_fd, tlsp_get_fd_event, (char *) state);
        event_request_timer(tlsp_get_fd_event, (char *) state,
@@ -868,10 +878,13 @@ static void tlsp_service(VSTREAM *plaintext_stream,
     /*
      * This program handles multiple connections, so it must not block. We
      * use event-driven code for all operations that introduce latency.
+     * Except that attribute lists are sent/received synchronously, once the
+     * socket is found to be ready for transmission.
      */
     non_blocking(plaintext_fd, NON_BLOCKING);
     vstream_control(plaintext_stream,
                    VSTREAM_CTL_PATH, "plaintext",
+                   VSTREAM_CTL_TIMEOUT, 5,
                    VSTREAM_CTL_END);
 
     /*
@@ -922,8 +935,8 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
            break;
        }
     }
-    tlsp_tls_enforce_tls = var_tlsp_enforce_tls;
-    if (!(var_tlsp_use_tls || var_tlsp_enforce_tls)) {
+    var_tlsp_use_tls = var_tlsp_use_tls || var_tlsp_enforce_tls;
+    if (!var_tlsp_use_tls) {
        msg_warn("TLS service is requested, but disabled with %s or %s",
                 VAR_TLSP_TLS_LEVEL, VAR_TLSP_USE_TLS);
        return;
@@ -937,7 +950,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
      */
     ask_client_cert = require_server_cert =
        (var_tlsp_tls_ask_ccert
-        || (enforce_tls && var_tlsp_tls_req_ccert));
+        || (var_tlsp_enforce_tls && var_tlsp_tls_req_ccert));
     if (strcasecmp(var_tlsp_tls_cert_file, "none") == 0) {
        no_server_cert_ok = 1;
        cert_file = "";
@@ -951,7 +964,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
     /* Some TLS configuration errors are not show stoppers. */
     if (!have_server_cert && require_server_cert)
        msg_warn("Need a server cert to request client certs");
-    if (!enforce_tls && var_tlsp_tls_req_ccert)
+    if (!var_tlsp_enforce_tls && var_tlsp_tls_req_ccert)
        msg_warn("Can't require client certs unless TLS is required");
     /* After a show-stopper error, log a warning. */
     if (have_server_cert || (no_server_cert_ok && !require_server_cert))
@@ -980,7 +993,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
                            dh512_param_file
                            = var_tlsp_tls_dh512_param_file,
                            eecdh_grade = var_tlsp_tls_eecdh,
-                           protocols = enforce_tls ?
+                           protocols = var_tlsp_enforce_tls ?
                            var_tlsp_tls_mand_proto :
                            var_tlsp_tls_proto,
                            ask_ccert = ask_client_cert,
index 0c4d129c7a7361634c3c197036bc714f58f35ad5..340e02fffc43b43b4ca65a9451ca6eea8d031495 100644 (file)
@@ -24,6 +24,7 @@
   */
 typedef struct {
     int     flags;                     /* see below */
+    int     req_flags;                 /* request flags, see tls_proxy.h */
     char   *service;                   /* argv[0] */
     VSTREAM *plaintext_stream;         /* local peer: postscreen(8), etc. */
     NBBIO  *plaintext_buf;             /* plaintext buffer */
index 3bd304616fec18dd7d96ecb4e339651920b82e01..049d7c6ee34a1c85cf90626469bce65ca2473ade 100644 (file)
@@ -47,6 +47,8 @@
 /* .IP MAC_EXP_FLAG_RECURSE
 /*     Expand macros in lookup results. This should never be done with
 /*     data whose origin is untrusted.
+/* .IP MAC_EXP_FLAG_APPEND
+/*     Append text to the result buffer.
 /* .PP
 /*     The constant MAC_EXP_FLAG_NONE specifies a manifest null value.
 /* .RE
@@ -231,7 +233,8 @@ int     mac_expand(VSTRING *result, const char *pattern, int flags,
     mc.context = context;
     mc.status = 0;
     mc.level = 0;
-    VSTRING_RESET(result);
+    if ((flags & MAC_EXP_FLAG_APPEND) == 0)
+       VSTRING_RESET(result);
     status = mac_parse(pattern, mac_expand_callback, (char *) &mc);
     VSTRING_TERMINATE(result);
 
index 5ae6b5b99ab41d372b8620cad5dab96f0f38459c..6cd375a39039e0a6cd1eb08902f82287fdcfea5e 100644 (file)
@@ -22,6 +22,7 @@
   */
 #define MAC_EXP_FLAG_NONE      (0)
 #define MAC_EXP_FLAG_RECURSE   (1<<0)
+#define MAC_EXP_FLAG_APPEND    (1<<1)
 
  /*
   * Real lookup or just a test?
index 28e4c0a873e584cfff6d864ee5830f4964367ad8..ba3e842b1e37a4c1a937ebdd0ddc8cabbb6e33c9 100644 (file)
 /*     The argument specifies the file descriptor to be used for writing.
 /*     This feature is limited to double-buffered streams, and makes the
 /*     stream non-seekable.
+/* .IP "VSTREAM_CTL_SWAP_FD (VSTREAM *)"
+/*     The argument specifies a VSTREAM pointer; the request swaps the
+/*     file descriptor members of the two streams. This feature is limited
+/*     to streams that are both double-buffered or both single-buffered.
 /* .IP "VSTREAM_CTL_DUPFD (int)"
 /*     The argument specifies a minimum file descriptor value. If
 /*     the actual stream's file descriptors are below the minimum,
@@ -1222,6 +1226,9 @@ void    vstream_control(VSTREAM *stream, int name,...)
     int     floor;
     int     old_fd;
     ssize_t req_bufsize = 0;
+    VSTREAM *stream2;
+
+#define SWAP(type,a,b) do { type temp = (a); (a) = (b); (b) = (temp); } while (0)
 
     for (va_start(ap, name); name != VSTREAM_CTL_END; name = va_arg(ap, int)) {
        switch (name) {
@@ -1263,8 +1270,20 @@ void    vstream_control(VSTREAM *stream, int name,...)
            stream->write_fd = va_arg(ap, int);
            stream->buf.flags |= VSTREAM_FLAG_NSEEK;
            break;
-       case VSTREAM_CTL_WAITPID_FN:
-           stream->waitpid_fn = va_arg(ap, VSTREAM_WAITPID_FN);
+       case VSTREAM_CTL_SWAP_FD:
+           stream2 = va_arg(ap, VSTREAM *);
+           if ((stream->buf.flags & VSTREAM_FLAG_DOUBLE)
+               != (stream2->buf.flags & VSTREAM_FLAG_DOUBLE))
+               msg_panic("VSTREAM_CTL_SWAP_FD can't swap descriptors between "
+                         "single-buffered and double-buffered streams");
+           if (stream->buf.flags & VSTREAM_FLAG_DOUBLE) {
+               SWAP(int, stream->read_fd, stream2->read_fd);
+               SWAP(int, stream->write_fd, stream2->write_fd);
+               stream->fd = ((stream->buf.flags & VSTREAM_FLAG_WRITE) ?
+                             stream->write_fd : stream->read_fd);
+           } else {
+               SWAP(int, stream->fd, stream2->fd);
+           }
            break;
        case VSTREAM_CTL_TIMEOUT:
            if (stream->timeout == 0)
index 943953f6787fa3751f990d52d662ab9dd5c065d0..3c6c16aeaa7b5b8d7cf19cbbc0a48d44b5baf6f6 100644 (file)
@@ -132,6 +132,7 @@ extern void vstream_control(VSTREAM *, int,...);
 #define VSTREAM_CTL_DUPFD      11
 #endif
 #define VSTREAM_CTL_BUFSIZE    12
+#define VSTREAM_CTL_SWAP_FD    13
 
 extern VSTREAM *PRINTFLIKE(1, 2) vstream_printf(const char *,...);
 extern VSTREAM *PRINTFLIKE(2, 3) vstream_fprintf(VSTREAM *, const char *,...);
index 56dd1d637a96e7f2796a290f6e406521d017123e..0a46cbc641c3f7cafcf883a8b58df182b4dd7e6a 100644 (file)
@@ -132,6 +132,7 @@ xsasl_dovecot_server.o: ../../include/connect.h
 xsasl_dovecot_server.o: ../../include/iostuff.h
 xsasl_dovecot_server.o: ../../include/mail_params.h
 xsasl_dovecot_server.o: ../../include/msg.h
+xsasl_dovecot_server.o: ../../include/myaddrinfo.h
 xsasl_dovecot_server.o: ../../include/mymalloc.h
 xsasl_dovecot_server.o: ../../include/name_mask.h
 xsasl_dovecot_server.o: ../../include/split_at.h