]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.0.14-20030715
authorWietse Venema <wietse@porcupine.org>
Tue, 15 Jul 2003 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:29:03 +0000 (06:29 +0000)
12 files changed:
postfix/README_FILES/ADDRESS_VERIFICATION_README
postfix/README_FILES/SMTPD_POLICY_README
postfix/RELEASE_NOTES
postfix/conf/sample-smtpd.cf
postfix/examples/smtpd-policy/smtpd-policy.pl
postfix/html/uce.html
postfix/src/global/mail_version.h
postfix/src/smtpd/smtpd_check.c
postfix/src/util/attr_clnt.c
postfix/src/util/attr_print_plain [deleted file]
postfix/src/util/attr_scan_plain [deleted file]
postfix/src/util/auto_clnt.c

index d2cc1129c4d8448b1145b60005f1f80bcd1a7665..4abd3bba5ae4fd806ef8818538edc0b679367c61 100644 (file)
@@ -143,7 +143,7 @@ the address verification cache quickly, and generate unnecessary
 sender verification probes.
 
 /etc/postfix/sender_access
-    securityfocus.com
+    securityfocus.com OK
     ...
 
 The "reject_unknown_sender_domain" restriction blocks mail from
index 9951633d8cb5c781a1020f8581f5499e173fcf97..b5eee81c11ece85153d7eaf4759bcae2d017306b 100644 (file)
@@ -1,25 +1,30 @@
-SMTPD POLICY DELEGATION PROTOCOL
-================================
+POLICY DELEGATION PROTOCOL
+==========================
 
 The Postfix SMTP server has a number of built-in mechanisms to
-block or accept mail at the SMTP protocol stage. Optionally, it
-can delegate policy decisions to an external server.
+block or accept mail at specific SMTP protocol stages. Optionally,
+it can be configured to delegate policy decisions to an external
+server that runs outside Postfix. A simple greylist policy can be
+implemented with only a dozen lines of PERL.
 
 This document describes the following:
 
-- The SMTPD policy delegation protocol.
+- The Postfix policy delegation protocol.
 
 - Using the example greylist policy server.
 
 PROTOCOL DESCRIPTION
 ====================
 
-The SMTPD policy delegation protocol is really simple. The client
+The Postfix policy delegation protocol is really simple. The client
 request is a sequence of name=value attributes separated by newline,
-and is terminated by an empty line.  Here is an example of all the
-attributes that the Postfix SMTP server sends in a delegated policy
-request:
+and is terminated by an empty line. The server reply is one name=value
+attribute and it, too, is terminated by an empty line.
 
+Here is an example of all the attributes that the Postfix SMTP
+server sends in a delegated SMTPD access policy request:
+
+    request=smtpd_access_policy
     protocol_state=RCPT
     protocol_name=SMTP
     helo_name=some.domain.tld
@@ -30,25 +35,36 @@ request:
     client_name=another.domain.tld
     [empty line]
 
-The order of the attributes does not matter, and the server ignores
-any attributes that it does not recognize. Protocol names are ESMTP
-or SMTP; protocol states are CONNECT, EHLO, HELO, MAIL, RCPT, or
-DATA. Other attributes speak for themselves. When the same attribute
-name is sent more than once, the server may keep the first or the
-last attribute value. An attribute name does not contain "=", null
-or newline, and an attribute value does not contain null or newline.
+- The "request" attribute is required. In this example the request
+  type is "smtpd_access_policy".
+- The order of the attributes does not matter. The policy server
+  should ignore any attributes that it does not care about.
+- When the same attribute name is sent more than once, the server
+  may keep the first value or the last attribute value.
+- An attribute name must not contain "=", null or newline, and an
+  attribute value must not contain null or newline.
+
+The following is specific to SMTPD delegated policy requests:
+
+- Protocol names are ESMTP or SMTP.
+- Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT, or DATA;
+  these are all the SMTP protocol states where the Postfix SMTP
+  server makes an OK/REJECT/HOLD/etc. decision.
 
-The policy server replies in the same style, with any action that
-is allowed in a Postfix SMTPD access table. Example:
+The policy server replies with any action that is allowed in a
+Postfix SMTPD access table. Example:
 
-    action=450 You are greylisted
+    action=450 Service temporarily unavailable
     [empty line]
 
+In case of trouble the server must log a warning and disconnect.
+Postfix will retry the request at some later time.
+
 CLIENT SIDE CONFIGURATION
 =========================
 
-The SMTPD delegated policy client can connect to a TCP socket or
-to a UNIX-domain socket. Examples:
+The delegated policy client can connect to a TCP socket or to a
+UNIX-domain socket. Examples:
 
     inet:localhost:9998
     unix:/some/where/policy
@@ -60,54 +76,147 @@ pathname of a UNIX-domain socket. The third example specifies a
 pathname relative to the Postfix queue directory; use this for
 policy servers that are spawned by the Postfix master daemon.
 
-To use the delegated policy service, specify "check_policy_service"
-anywhere in the list of smtpd_recipient_restrictions:
+To use the delegated policy service for SMTPD access control,
+specify "check_policy_service" anywhere in the list of
+smtpd_recipient_restrictions:
 
 /etc/postfix/main.cf:
     smtpd_recipient_restrictions =
-       ... 
-       reject_unauth_destination 
-       check_policy_service unix:private/policy 
-       ...
+        ... 
+        reject_unauth_destination 
+        check_policy_service unix:private/policy 
+        ...
 
 NOTE: specify "check_policy_service" AFTER "reject_unauth_destination"
 or else your system could become an open relay.
 
+NOTE: Solaris UNIX-domain sockets do not work very well. Use TCP
+sockets instead:
+
+/etc/postfix/main.cf:
+    smtpd_recipient_restrictions =
+        ... 
+        reject_unauth_destination 
+        check_policy_service inet:localhost:9998
+        ...
+
+Other client-side configuration parmeters:
+
+- smtpd_policy_service_max_idle (default: 300s): the amount of time
+  before Postfix closes an unused policy connection. The socket is
+  closed while the SMTP server waits for new a SMTP client.
+
+- smtpd_policy_service_max_ttl (default: 1000s): the amount of time
+  before Postfix closes an active policy connection.  The socket
+  is closed while the SMTP server waits for new a SMTP client.
+
+- smtpd_policy_service_timeout (default: 100s): the time limit to
+  connect to, send to or receive from a policy service.
+
 EXAMPLE: GREYLIST POLICY SERVER
 ===============================
 
 The file examples/smtpd-policy/smtpd-policy.pl in the Postfix source
 tree implements an example greylist policy server. This server
 stores a time stamp for every (client, sender, recipient) triple.
-Mail is not accepted until a triple's time stamp is more than 3600
-seconds old. This stops junk mail with random sender addresses,
-and mail from randomly selected open proxies. It also stops junk
-mail from spammers that change IP address frequently.
+By default, mail is not accepted until a triple's time stamp is
+more than 3600 seconds old. This stops junk mail with randomly
+selected sender addresses, and mail that is sent through randomly
+selected open proxies. It also stops junk mail from spammers that
+change their IP address frequently.
+
+Copy examples/smtpd-policy/smtpd-policy.pl to /usr/libexec/postfix
+or whatever location is appropriate for your system.
+
+In the smtpd-policy.pl PERL script you need to specify the location
+of the greylist database file. The default location is:
+
+    $database_name="/var/mta/smtpd-policy.db";
+
+The /var/mta directory (or whatever you choose) should be writable
+by "nobody", or by whatever username you configure below in master.cf
+for the policy service.
+
+Example:
 
-The example greylist policy server is a PERL script that runs under
-control by the Postfix master daemon:
+    # mkdir /var/mta
+    # chown nobody /var/mta
+
+Note: DO NOT create the greylist database in a world-writable
+directory such as /tmp or /var/tmp, and DO NOT create the greylist
+database in a file system that can run out of space easily. If the
+file becomes corrupted you will not be able to receive mail until
+you delete the file by hand.
+
+The smtpd-policy.pl PERL script can be run under control by the
+Postfix master daemon.  For example, to run the script as user
+"nobody", using a UNIX-domain socket that is accessible by Postfix
+processes only:
 
 /etc/postfix/master.cf:
     policy  unix  -       n       n       -       -       spawn
       user=nobody argv=/usr/bin/perl /usr/libexec/postfix/smtpd-policy.pl
 
+Specify "...postfix/smtpd-policy.pl -v" for verbose logging of each
+request and reply.
+
+Greylisting mail from frequently forged domains
+-----------------------------------------------
+
+It is relatively safe to turn on greylisting for specific domains
+that often appear in forged email.
+
 /etc/postfix/main.cf:
     smtpd_recipient_restrictions =
-        permit_mynetworks
+        ...
         reject_unauth_destination 
-        check_policy_service unix:private/policy unix:private/policy
+        check_sender_access hash:/etc/postfix/sender_access
         ...
+    restriction_classes = greylist
+    greylist = check_policy_service unix:private/policy
 
-There are other delegated policy client configuration parameters
-that control timeouts etc.  but you should never have to change
-those.
+/etc/postfix/sender_access:
+    aol.com     greylist
+    hotmail.com greylist
+    bigfoot.com greylist
+    ... etcetera ...
 
-In the smtpd-policy.pl PERL script you need to specify the location
-of the greylist database file. DO NOT create the greylist database
-in a world-writable directory such as /tmp or /var/tmp, and DO NOT
-create the greylist database in a file system that can run out of
-space easily. If the file becomes corrupted you will not be able
-to receive mail until you delete the file by hand.
+Be sure to specify check_sender_access AFTER reject_unauth_destination
+or else your system could become an open mail relay.
+
+A list of frequently forged MAIL FROM domains can be found at
+http://www.monkeys.com/anti-spam/filtering/sender-domain-validate.in
+
+Greylisting all your mail
+-------------------------
+
+If you turn on greylisting for all mail you will almost certainly
+want to make exceptions for mailing lists that use one-time sender
+addresses, because such mailing lists can pollute your greylist
+database relatively quickly.
+
+/etc/postfix/main.cf:
+    smtpd_recipient_restrictions =
+        ...
+        reject_unauth_destination 
+        check_sender_access hash:/etc/postfix/sender_access
+        check_policy_service unix:private/policy
+        ...
+
+/etc/postfix/sender_access:
+    securityfocus.com OK
+    ...
+
+Be sure to specify check_sender_access and check_policy_service
+AFTER reject_unauth_destination or else your system could become
+an open mail relay.
+
+ROUTINE MAINTENANCE
+===================
+
+The greylist database grows over time, because the greylist server
+never removes database entries. If left unattended, the greylist
+database will eventually run your file system out of space.
 
 When the status file exceeds some reasonable size you can simply
 delete the file without adverse effects. In the worst case, new
@@ -129,20 +238,19 @@ $database_name="/var/mta/smtpd-policy.db";
 $greylist_delay=3600;
 
 #
-# Demo policy routine. The result is an action just like it would
-# be specified on the right-hand side of a Postfix access table.
-# Request attributes are passed in via the %attr hash.
+# Demo SMTPD access policy routine. The result is an action just like
+# it would be specified on the right-hand side of a Postfix access
+# table.  Request attributes are available via the %attr hash.
 #
-sub policy {
-    local(*attr) = @_;
+sub smtpd_access_policy {
     my($key, $time_stamp, $now);
 
     # Open the database on the fly.
     open_database() unless $database_obj;
-    
+
     # Lookup the time stamp for this client/sender/recipient.
     $key = $attr{"client_address"}."/".$attr{"sender"}."/".$attr{"recipient"};
-    $time_stamp = read_database($key); 
+    $time_stamp = read_database($key);
     $now = time();
 
     # If new request, add this client/sender/recipient to the database.
@@ -152,9 +260,9 @@ sub policy {
     }
 
     syslog $syslog_priority, "request age %d", $now - $time_stamp if $verbose;
-    if ($time_stamp + $greylist_delay < $now) {
+    if ($now - $time_stamp > $greylist_delay) {
         return "ok";
     } else {
-        return "450 request is greylisted";
+        return "450 Service is unavailable";
     }
 }
index 9c816160c69e9da376c663049bfcbfc084704fab..217c2de861cbde1ec2e451aa10ae246ce3bf378b 100644 (file)
@@ -22,6 +22,17 @@ snapshot release).  Patches change the patchlevel and the release
 date. Snapshots change only the release date, unless they include
 the same bugfixes as a patch release.
 
+Major changes with Postfix snapshot 2.0.13-20030715
+===================================================
+
+Support for SMTP access policy delegation to an external server.
+Greylisting is used as an example.  See the SMTPD_POLICY_README
+file for further information.
+
+Support for multi-valued RBL lookup results. For example, specify
+"reject_rbl_client foo.bar.tld=127.0.0.3" to reject clients that
+are listed with a "127.0.0.3" address record.
+
 Major changes with Postfix snapshot 2.0.13-20030706
 ===================================================
 
index d3ff079dd91e5a9332a4e045992cd8accef9e058..2fa27b6f034b06d8dce7d45d43fa9f58f0b9ee2e 100644 (file)
@@ -142,8 +142,12 @@ smtpd_banner = $myhostname ESMTP $mail_name
 #      Permit the ETRN command if the result is OK or all numerical.
 #   reject_rbl_client domain.tld: reject if the reverse client network
 #      address is listed in an A record under domain.tld.
+#      Append e.g., "=127.0.0.2" to the RBL domain name to select a specific
+#      address record when an RBL server provides multi-valued results.
 #   reject_rhsbl_client domain.tld: reject if the client hostname is listed
 #      in an A record under domain.tld.
+#      Append e.g., "=127.0.0.2" to the RBL domain name to select a specific
+#      address record when an RBL server provides multi-valued results.
 #   reject: reject the request. Place this at the end of a restriction.
 #   permit: permit the request. Place this at the end of a restriction.
 #   warn_if_reject: next restriction logs a warning instead of rejecting.
@@ -316,8 +320,12 @@ mynetworks_style = subnet
 #      Permit the SMTP client if the result is OK or all numerical.
 #   reject_rbl_client domain.tld: reject if the reversed client IP address
 #      is listed in an A record under domain.tld.
+#      Append e.g., "=127.0.0.2" to the RBL domain name to select a specific
+#      address record when an RBL server provides multi-valued results.
 #   reject_rhsbl_client domain.tld: reject if the client hostname is listed
 #      in an A record under domain.tld.
+#      Append e.g., "=127.0.0.2" to the RBL domain name to select a specific
+#      address record when an RBL server provides multi-valued results.
 #   reject: reject the request. Place this at the end of a restriction.
 #   permit: permit the request. Place this at the end of a restriction.
 #   warn_if_reject: next restriction logs a warning instead of rejecting.
index 0d374aaa6f4028793b47b88e6c1d1f70817225a0..b9f60efbb9011866e1d2b7dbc1921b44aad19f19 100755 (executable)
@@ -39,6 +39,7 @@ use Sys::Syslog qw(:DEFAULT setlogsock);
 # Each query is a bunch of attributes. Order does not matter, and
 # the demo script uses only a few of all the attributes shown below:
 #
+#    request=smtpd_access_policy
 #    protocol_state=RCPT
 #    protocol_name=SMTP
 #    helo_name=some.domain.tld
@@ -76,12 +77,11 @@ $syslog_options="pid";
 $syslog_priority="info";
 
 #
-# Demo policy routine. The result is an action just like it would
-# be specified on the right-hand side of a Postfix access table.
-# Request attributes are passed in via the %attr hash.
+# Demo SMTPD access policy routine. The result is an action just like
+# it would be specified on the right-hand side of a Postfix access
+# table.  Request attributes are available via the %attr hash.
 #
-sub policy {
-    local(*attr) = @_;
+sub smtpd_access_policy {
     my($key, $time_stamp, $now);
 
     # Open the database on the fly.
@@ -99,10 +99,10 @@ sub policy {
     }
 
     syslog $syslog_priority, "request age %d", $now - $time_stamp if $verbose;
-    if ($time_stamp + $greylist_delay < $now) {
+    if ($now - $time_stamp > $greylist_delay) {
        return "ok";
     } else {
-       return "450 request is greylisted";
+       return "450 Service is unavailable";
     }
 }
 
@@ -118,7 +118,8 @@ sub LOCK_UN { 8 };  # Release lock.
 # Log an error and abort.
 #
 sub fatal_exit {
-    syslog "err", @_;
+    my($first) = shift(@_);
+    syslog "err", "fatal: $first", @_;
     exit 1;
 }
 
@@ -128,6 +129,7 @@ sub fatal_exit {
 sub open_database {
     my($database_fd);
 
+    # Use tied database to make complex manipulations easier to express.
     $database_obj = tie(%db_hash, 'DB_File', $database_name, 
                            O_CREAT|O_RDWR, 0644) ||
        fatal_exit "Cannot open database %s: $!", $database_name;
@@ -201,16 +203,21 @@ select((select(STDOUT), $| = 1)[0]);
 #
 while (<STDIN>) {
     if (/([^=]+)=(.*)\n/) {
-       $attr{$1} = $2;
-    } else {
+       $attr{substr($1, 0, 512)} = substr($2, 0, 512);
+    } elsif ($_ eq "\n") {
        if ($verbose) {
            for (keys %attr) {
                syslog $syslog_priority, "Attribute: %s=%s", $_, $attr{$_};
            }
        }
-       $action = &policy(*attr);
+       fatal_exit "unrecognized request type: '%s'", $attr{request}
+           unless $attr{"request"} eq "smtpd_access_policy";
+       $action = smtpd_access_policy();
        syslog $syslog_priority, "Action: %s", $action if $verbose;
        print STDOUT "action=$action\n\n";
        %attr = ();
+    } else {
+       chop;
+       syslog $syslog_priority, "warning: ignoring garbage: %.100s", $_;
     }
 }
index 6d0a25c7949460cadb6f8608951d803045546bbb..fb7f8207ddae326331d2afd300dd6579e429ace4 100644 (file)
@@ -388,9 +388,14 @@ href="basic.html#mynetworks"> $mynetworks</a>.
 
 <a name="reject_rbl_client">
 
+<dt> <b>reject_rbl_client</b> <i>domain.tld=127.0.0.2</i>
+
 <dt> <b>reject_rbl_client</b> <i>domain.tld</i> <dd> Reject the
 request when the reversed client network address is listed with an
-A record under <i>domain.tld</i>.  
+A record under <i>domain.tld</i>.   
+
+Append the address to the RBL server's domain name to select a
+specific address from a multi-valued result.
 
 The <b> maps_rbl_reject_code</b> parameter specifies the response
 code for rejected requests (default:  <b>554</b>), the <b><a
@@ -403,11 +408,16 @@ indexed by RBL domain.
 
 <a name="reject_rhsbl_client">
 
+<dt> <b>reject_rhsbl_client</b> <i>domain.tld=127.0.0.2</i>
+
 <dt> <b>reject_rhsbl_client</b> <i>domain.tld</i> <dd> Reject the
 request when the client hostname is listed with an A record under
 <i>domain.tld</i>.  See above for additional RBL related configuration
 parameters.
 
+Append the address to the RBL server's domain name to select a
+specific address from a multi-valued result.
+
 <p>
 
 <a name="check_client_access">
index bf39f9746a55f7b73ad931ca0859e5a8b171f0cf..bf6cfd56f84670b73929c6cf43881d2656ac7c41 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change the patchlevel and the release date. Snapshots change the
   * release date only, unless they include the same bugfix as a patch release.
   */
-#define MAIL_RELEASE_DATE      "20030714"
+#define MAIL_RELEASE_DATE      "20030715"
 
 #define VAR_MAIL_VERSION       "mail_version"
 #define DEF_MAIL_VERSION       "2.0.14-" MAIL_RELEASE_DATE
index 102ddbbc820d872ae5a0b794dc8123b218d09e74..b23c5f170566cb79267453d6e700d59ffea4390e 100644 (file)
@@ -2741,8 +2741,10 @@ static int check_policy_service(SMTPD_STATE *state, const char *server,
      */
     if (action == 0)
        action = vstring_alloc(10);
+
     if (attr_clnt_request(policy_clnt,
                          ATTR_FLAG_NONE,       /* Query attributes. */
+                         ATTR_TYPE_STR, MAIL_ATTR_REQ, "smtpd_access_policy",
                          ATTR_TYPE_STR, MAIL_ATTR_PROTO_STATE, state->where,
                       ATTR_TYPE_STR, MAIL_ATTR_PROTO_NAME, state->protocol,
                          ATTR_TYPE_STR, MAIL_ATTR_CLIENT_ADDR, state->addr,
index e12644a1ecb1bfd24c5c56514558ecd15a7c973a..5b5eea3288f6b36f182504787034e5960b7b7107 100644 (file)
@@ -39,9 +39,8 @@
 /*
 /*     attr_clnt_request() sends the specified request attributes and
 /*     receives a reply. The reply argument specifies a name-value table.
-/*     The other arguments are as described in attr_print0(3) and in
-/*     attr_print64(3). The result is the number of attributes received
-/*     or -1 in case of trouble.
+/*     The other arguments are as described in attr_print_plain(3). The
+/*     result is the number of attributes received or -1 in case of trouble.
 /*
 /*     attr_clnt_free() destroys a client handle and closes its connection.
 /* DIAGNOSTICS
@@ -136,8 +135,7 @@ ATTR_CLNT *attr_clnt_create(const char *service, int timeout,
 
     if ((endpoint = split_at(transport, ':')) == 0
        || *endpoint == 0 || *transport == 0)
-       msg_fatal("service \"%s\" should be specified as transport:endpoint",
-                 service);
+       msg_fatal("need service transport:endpoint instead of \"%s\"", service);
     if (msg_verbose)
        msg_info("%s: transport=%s endpoint=%s", myname, transport, endpoint);
 
diff --git a/postfix/src/util/attr_print_plain b/postfix/src/util/attr_print_plain
deleted file mode 100755 (executable)
index b94f004..0000000
Binary files a/postfix/src/util/attr_print_plain and /dev/null differ
diff --git a/postfix/src/util/attr_scan_plain b/postfix/src/util/attr_scan_plain
deleted file mode 100755 (executable)
index 8293c4c..0000000
Binary files a/postfix/src/util/attr_scan_plain and /dev/null differ
index 1a487aad1bc57e8c9cd7abc7638edb486eca9c3e..093d0a95e501b84859906a859abfac06dd36ae65 100644 (file)
 /*     void    auto_clnt_free(auto_clnt)
 /*     AUTO_CLNT *auto_clnt;
 /* DESCRIPTION
-/*     This module maintains local IPC client endpoints that automatically
+/*     This module maintains IPC client endpoints that automatically
 /*     disconnect after a being idle for a configurable amount of time,
 /*     that disconnect after a configurable time to live,
 /*     and that transparently handle most server-initiated disconnects.
-/*     Server disconnect is detected by read-selecting the client endpoint.
-/*     The code assumes that the server has disconnected when the endpoint
-/*     becomes readable.
 /*
 /*     auto_clnt_create() instantiates a client endpoint.
 /*