]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-1.1.9-20020509
authorWietse Venema <wietse@porcupine.org>
Thu, 9 May 2002 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:27:55 +0000 (06:27 +0000)
25 files changed:
postfix/HISTORY
postfix/README_FILES/FILTER_README
postfix/RELEASE_NOTES
postfix/html/cleanup.8.html
postfix/src/cleanup/cleanup_map1n.c
postfix/src/global/Makefile.in
postfix/src/global/domain_list.c
postfix/src/global/dot_lockfile.c
postfix/src/global/mail_date.c
postfix/src/global/mail_version.h
postfix/src/global/maps.c
postfix/src/global/namadr_list.c
postfix/src/global/quote_821_local.c
postfix/src/global/quote_822_local.c
postfix/src/global/quote_flags.h
postfix/src/global/rec2stream.c
postfix/src/global/resolve_clnt.c
postfix/src/global/rewrite_clnt.c
postfix/src/global/stream2rec.c
postfix/src/global/string_list.c
postfix/src/global/tok822_parse.c
postfix/src/global/tok822_parse.ref
postfix/src/qmqpd/qmqpd.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c

index 1e41483b4e1c850d6a5a529c0b3f0989db305ccb..6f3bce6f15ba8ee2e6fc04d5733c58081c39c2c4 100644 (file)
@@ -6353,9 +6353,10 @@ Apologies for any names omitted.
 
 20020508
 
-       Bugfix: close an obscure source routing relaying loophole
-       involving postfix-style virtual domains. Problem reported
-       by Victor Duchovny. File: smtpd/smtpd_check.c.
+       Bugfix: close user@domain@postfix-style.virtual.domain
+       source routing relaying loophole involving postfix-style
+       virtual domains with @virtual.domain catch-all patterns.
+       Problem reported by Victor Duchovny. File:  smtpd/smtpd_check.c.
 
        Bugfix: mail_addr_map() used the "wrong" @ character in
        addresses with multiple @. Victor Duchovny. File:
@@ -6367,8 +6368,31 @@ Apologies for any names omitted.
        not even in SMTP commands.  Files:  global/quote_82[12]_local.c
        and clients.
 
+20020509
+
+       Safety: don't allow an OK access rule lookup result for
+       user@domain@postfix-style.virtual.domain. Suggested by
+       Victor Duchovny, Morgan Stanley. File: smtpd/smtpd_check.c.
+
+       Bugfix: quote unquoted address localparts that need quoting.
+       Files: global/tok822_parse.c, global/quote_82[12]_local.c.
+
+       Documentation: simplified the advanced content filtering
+       example, and included a more advanced example for those
+       who want to squeeze out more performance without running
+       multiple Postfix instances.  Text by Victor Duchovny, Morgan
+       Stanley. File:  README_FILES/FILTER_README.
+
 Open problems:
 
+       Low: smtpd should reply with the original recipient address,
+       or it should at least externalize it.
+
+       Low: all table lookups should consistently use internalized
+       (unquoted) or externalized (quoted) forms as lookup keys.
+       smtpd, qmgr, local, etc. use internalized forms as keys.
+       cleanup uses externalized forms.
+
        Low: sendmail does not store null command-line recipients.
 
        Low: have a configurable list of errno values for mailbox
index d1bc3b08528b478995c01bba8769c1b8f84491c8..71db5573bc4682b23caa6a13921541184aa2d24c 100644 (file)
@@ -137,24 +137,22 @@ We will set up a content filtering program that receives SMTP mail
 via localhost port 10025, and that submits SMTP mail back into
 Postfix via localhost port 10026.
 
-      ...................................
-      :            Postfix              :
-   ----->smtpd \                        :
-      :         -cleanup-\       /local---->
-   ---->pickup /          -queue-       :
-      :          cleanup2/   |   \smtp----->
-      :             ^        v          :
-      :             |        v          :
-      :           smtpd     smtp        :
-      :           10026      |          :
-      .......................|...........
-                    ^        |
-                    |        v
-                ....|.............
-                :   |      10025 :
-                :   filter       :
-                :                :
-                ..................
+      ..................................
+      :            Postfix             :
+   ----->smtpd \                /local---->
+      :         -cleanup->queue-       :
+   ---->pickup /    ^       |   \smtp----->
+      :             |       v          :
+      :           smtpd    smtp        :
+      :           10026     |          :
+      ......................|...........
+                    ^       |
+                    |       v
+                ....|............
+                :   |     10025 :
+                :   filter      :
+                :               :
+                .................
 
 To enable content filtering in this manner, specify in main.cf a
 new parameter:
@@ -216,11 +214,11 @@ a dedicated listener on port localhost 10026:
            -o content_filter= 
            -o local_recipient_maps=
            -o myhostname=localhost.domain.name
-           -o disable_dns_lookups=yes
-           -o cleanup_service=cleanup2 
-        cleanup2            unix  n      -      n      -       0      cleanup
-           -o header_checks=
-           -o body_checks=
+           -o smtpd_helo_restrictions=
+           -o smtpd_client_restrictions=
+           -o smtpd_sender_restrictions=
+           -o smtpd_recipient_restrictions=permit_mynetworks,reject
+           -o mynetworks=127.0.0.0/8
 
 This is just another SMTP server. The "-o content_filter=" requests
 no content filtering for incoming mail. The server has the same
@@ -234,13 +232,164 @@ The "-o myhostname=localhost.domain.name" avoids a possible problem
 if the content filter is picky about the hostname that Postfix
 sends in SMTP server replies.
 
-The "-o disable_dns_lookups=yes" turns off unnecessary DNS lookups
-that would only slow things down.
+The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8"
+turn off UCE controls that would only waste time here.
+
+Squeezing out more performance
+==============================
+
+Many refinements are possible, such as running a specially-configured
+smtp delivery agent for feeding mail into the content filter, and
+turning off address rewriting before or after content filtering.
+
+As the example below shows, things quickly become very complex,
+because a lot of main.cf like information gets listed in the
+master.cf file. This makes the system hard to understand.
+
+If you need to squeeze out more performance, it is probably simpler
+to run multiple Postfix instances, one before and one after the
+content filter. That way, each instance can have simple main.cf
+and master.cf files, and the system will be easier to understand.
+
+As before, we will set up a content filtering program that receives
+SMTP mail via localhost port 10025, and that submits SMTP mail back
+into Postfix via localhost port 10026.
+
+      ...................................
+      :            Postfix              :
+   ----->smtpd \                        :
+      :         -cleanup-\       /local---->
+   ---->pickup /          -queue-       :
+      :          cleanup2/   |   \smtp----->
+      :             ^        v          :
+      :             |        v          :
+      :           smtpd     smtp        :
+      :           10026      |          :
+      .......................|...........
+                    ^        |
+                    |        v
+                ....|.............
+                :   |      10025 :
+                :   filter       :
+                :                :
+                ..................
+
+To enable content filtering in this manner, specify in main.cf a
+new parameter:
+
+/etc/postfix/main.cf:
+    content_filter = scan:localhost:10025
+
+/etc/postfix/master.cf:
+#
+# This is the usual input "smtpd" already present in master.cf
+#
+smtp                inet  n      -      n      -       -      smtpd
+#
+# This is the cleanup daemon that handles messages in front of
+# the content filter, it does header_checks and body_checks (if
+# any), but does not do any address rewriting.
+#
+# The address rewriting happens in the second cleanup phase after
+# the content filter. This gives the content_filter access to
+# *largely* unmodified addresses for maximum flexibility.
+#
+# The trivial-rewrite daemon handles the logic of append_myorigin
+# and append_dot_mydomain, turning these off requires two
+# trivial-rewrite services, by which point (if you are not
+# already) you are much better off with two complete Postfix
+# instances one in front of and one behind the content filter.
+#
+# Note that some sites may specifically want to do the opposite:
+# perform rewrites in front of the content_filter which would
+# then see only cleaned up addresses, in this case the parameter
+# settings below should be moved to the second "cleanup"
+# instance.
+#
+cleanup             unix  n      -      n      -       0      cleanup
+       -o canonical_maps=
+       -o sender_canonical_maps=
+       -o recipient_canonical_maps=
+       -o masquerade_domains=
+       -o virtual_maps=
+#
+# This is the delivery agent that injects mail into the content
+# filter.  It is tuned for low latency and low concurrency, most
+# content filters burn CPU and high concurrency causes thrashing.
+# The process limit of 10 reenforces the effect of
+# $default_destination_concurrency_limit, even without an
+# explicit process limit, the concurrency is bounded because all
+# messages heading into the content filter have the same
+# destination. The "disable_dns_lookups" setting prevents the
+# delivery agent from consuming precious "bandwidth" in the
+# narrow deliver channel waiting for slow DNS responses. It also
+# ensures that the original envelope recipient is seen by the
+# content filter.
+#
+scan                unix  n      -      n      -      10      smtp
+    -o disable_dns_lookups=yes
+#
+# This is the SMTP listener that receives filtered messages from
+# the content filter. It *MUST* clear the content_filter
+# parameter to avoid loops, and use a different hostname to avoid
+# triggering the Postfix SMTP loop detection code.
+#
+#
+# Since all recipients have been validated by the first "smtpd",
+# clear local_recipient_maps, virtual_maps and
+# virtual_mailbox_maps.
+#
+# This "smtpd" uses a separate cleanup that does no header or
+# body checks, but does do the various address rewrites disabled
+# in the first cleanup.
+#
+# The parameters from mynetworks onward disable all access
+# control other than insisting on connections from one of the IP
+# addresses of the host. This is typically overkill, but can
+# reduce resource usage, if the default restrictions use lots of
+# tables.
+#
+localhost:10026     inet  n      -      n      -       -      smtpd
+    -o content_filter= 
+    -o myhostname=localhost.domain.name
+    -o local_recipient_maps=
+    -o virtual_maps=
+    -o virtual_mailbox_maps=
+    -o cleanup_service=cleanup2 
+    -o mynetworks=127.0.0.0/8
+    -o mynetworks_style=host
+    -o smtpd_restriction_classes=
+    -o smtpd_client_restrictions=
+    -o smtpd_helo_restrictions=
+    -o smtpd_sender_restrictions=
+    -o smtpd_recipient_restrictions=permit_mynetworks,reject
+#
+# This is the second cleanup daemon. No header or body checks.
+# If preferable, enable rewrites in the first cleanup daemon, and
+# disable them here.
+#
+cleanup2            unix  n      -      n      -       0      cleanup
+    -o header_checks=
+    -o body_checks=
+#
+# The normal "smtp" delivery agent for contrast with "scan".
+# Definitely do not set "disable_dns_lookups = yes" here if you
+# send mail to the Internet.
+#
+smtp                unix  n      -      n      -      -       smtp
+
+This causes Postfix to add one extra content filtering record to
+each incoming mail message, with content scan:localhost:10025.
+You can use the same syntax as in the right-hand side of a Postfix
+transport table.  The content filtering records are added by the
+smtpd and pickup servers.
 
-The "-o cleanup_service=cleanup2" specifies that mail received via
-the secondary SMTP server should be send into the cleanup2 service.
+The "scan" transport is a dedicated instance of the "smtp" delivery
+agent for injecting messages into the SMTP content filter. Using
+a dedicated "smtp" transport allows one to tune it for the specific
+task of delivering mail to a local content filter (low latency,
+low concurrency, throughput dependent on predictably low latency).
 
-As the master.cf entry above shows, the cleanup2 service is like
-the normal cleanup server, but with some features turned off:  no
-processing of header patterns, and no processing of body message
-patterns. This can save you some precious CPU cycles.
+See the previous example for setting up the content filter with
+the Postfix spawn service; you can of course use any server that
+can be run stand-alone outside the Postfix environment.
index 8964d11bd3d0bb88796d194d1078fcab5611a3ea..69e7921d246e096260b5fbd3fbcd16a8ce064796 100644 (file)
@@ -12,6 +12,30 @@ 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.
 
+Incompatible changes with Postfix snapshot 1.1.9-20020509
+=========================================================
+
+The Postfix SMTP server no longer honors OK access rules for
+user@domain@postfix-style.virtual.domain, to close a relaying
+loophole with postfix-style virtual domains that have @domain.name
+catch-all patterns.
+
+The appearance of user@domain1@domain2 addresses has changed.  In
+mail headers, such addresses are now properly quoted as
+"user@domain1"@domain2. This quoted form is now also expected on
+the left-hand side of virtual and canonical lookup tables, but only
+by some of the Postfix components. For now, it is better not to
+use user@domain1@domain2 address forms on the left-hand side of
+lookup tables.
+
+Incompatible changes with Postfix snapshot 1.1.8-20020508
+=========================================================
+
+The Postfix SMTP server by default no longer accepts mail for
+user@domain@postfix-style.virtual.domain, to close a relaying
+loophole with postfix-style virtual domains that have @domain.name
+catch-all patterns.
+
 Incompatible changes with Postfix snapshot 1.1.8-20020505
 =========================================================
 
index f1ce6052662bd521f62d2ce1d822d2bffd8f8912..d4680563845832cc9979f16077eb61bb04945856 100644 (file)
@@ -1,5 +1,4 @@
 <html> <head> </head> <body> <pre>
-
 CLEANUP(8)                                             CLEANUP(8)
 
 <b>NAME</b>
@@ -169,6 +168,5 @@ CLEANUP(8)                                             CLEANUP(8)
        P.O. Box 704
        Yorktown Heights, NY 10598, USA
 
-                                                                1
-
+                                                       CLEANUP(8)
 </pre> </body> </html>
index 51f5be9c012f8960cfad9fc4bbe0dccbb584d61d..0a181e4637d4779035f4bf1889125ac1ab52ce4d 100644 (file)
@@ -10,6 +10,7 @@
 /*     char    *addr;
 /* DESCRIPTION
 /*     This module implements one-to-many table mapping via table lookup.
+/*     Table lookups are done with quoted (externalized) address forms.
 /*     The process is recursive. The recursion terminates when the
 /*     left-hand side appears in its own expansion, or when a maximal
 /*     nesting level is reached.
index f1ce8a9f62cd0251b6a100c98679955fe67a081a..a267086ded1b390ff58601020e9ab238b9323af7 100644 (file)
@@ -1047,6 +1047,8 @@ tok822_parse.o: ../../include/sys_defs.h
 tok822_parse.o: ../../include/vstring.h
 tok822_parse.o: ../../include/vbuf.h
 tok822_parse.o: ../../include/msg.h
+tok822_parse.o: quote_822_local.h
+tok822_parse.o: quote_flags.h
 tok822_parse.o: tok822.h
 tok822_parse.o: resolve_clnt.h
 tok822_resolve.o: tok822_resolve.c
index d4ea536b29f27516598b01ac0b2930f1f5f63b0b..b067fb895359dfb995f44005dbcd1b8e16df4085 100644 (file)
@@ -82,6 +82,7 @@
 
 #include <msg.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <vstream.h>
 #include <msg_vstream.h>
 
@@ -90,7 +91,7 @@ static void usage(char *progname)
     msg_fatal("usage: %s [-v] patterns hostname", progname);
 }
 
-main(int argc, char **argv)
+int     main(int argc, char **argv)
 {
     DOMAIN_LIST *list;
     char   *host;
index 9d0a2bef31ce26a1e59e6203525a059813861bb3..94681bf00b7d67d9258ed05b5dee88659eb7296e 100644 (file)
@@ -154,7 +154,7 @@ void    dot_unlockfile(const char *path)
 #include <msg_vstream.h>
 #include <mail_conf.h>
 
-main(int argc, char **argv)
+int     main(int argc, char **argv)
 {
     VSTRING *why = vstring_alloc(100);
 
index ca20f99a155ea803b1fd04f10d1ab0ad275ce46a..93edfe9c20e47f3273789c1cdd0d0280ee305aec 100644 (file)
@@ -131,7 +131,7 @@ const char *mail_date(time_t when)
 
 #include <vstream.h>
 
-main(void)
+int     main(void)
 {
     vstream_printf("%s\n", mail_date(time((time_t *) 0)));
     vstream_fflush(VSTREAM_OUT);
index 0fb33c85a268b3561041ac8ef27ead62d5d1cdd1..051405c8c3f791ec4c1032264557124237972a5d 100644 (file)
   * 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      "20020508"
+#define MAIL_RELEASE_DATE      "20020509"
 
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "1.1.8-" MAIL_RELEASE_DATE
+#define DEF_MAIL_VERSION       "1.1.9-" MAIL_RELEASE_DATE
 extern char *var_mail_version;
 
  /*
index 7fd51ff57df2efdc68f6a73b5f3554190abccb68..98979e142cad68b67ed6bf01845d180b8f1c50f1 100644 (file)
@@ -217,7 +217,7 @@ MAPS   *maps_free(MAPS *maps)
 #include <vstream.h>
 #include <vstring_vstream.h>
 
-main(int argc, char **argv)
+int     main(int argc, char **argv)
 {
     VSTRING *buf = vstring_alloc(100);
     MAPS   *maps;
index c5169d87e59fb5b852d398e99a94d3d0e9422567..3388023b3172c666ead7fc8da595187996f916e3 100644 (file)
@@ -88,6 +88,7 @@
 
 #include <msg.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <vstream.h>
 #include <msg_vstream.h>
 
@@ -96,7 +97,7 @@ static void usage(char *progname)
     msg_fatal("usage: %s [-v] pattern_list hostname address", progname);
 }
 
-main(int argc, char **argv)
+int     main(int argc, char **argv)
 {
     NAMADR_LIST *list;
     char   *host;
index d91d1897e44abb6190e02374134af51cf92cb427..2fa6bd526ff95ac2b7cb5757b69213fa751dcdb7 100644 (file)
@@ -27,6 +27,8 @@
 /*     In violation with RFCs, treat 8-bit text as ordinary text.
 /* .IP QUOTE_FLAG_EXPOSE_AT
 /*     In violation with RFCs, treat `@' as an ordinary character.
+/* .IP QUOTE_FLAG_APPEND
+/*     Append to the result buffer, instead of overwriting it.
 /* .RE
 /* STANDARDS
 /*     RFC 821 (SMTP protocol)
@@ -100,7 +102,8 @@ static int is_821_dot_string(char *local_part, char *end, int flags)
 
 /* make_821_quoted_string - make quoted-string from local-part */
 
-static VSTRING *make_821_quoted_string(VSTRING *dst, char *local_part, char *end)
+static VSTRING *make_821_quoted_string(VSTRING *dst, char *local_part,
+                                              char *end, int flags)
 {
     char   *cp;
     int     ch;
@@ -109,10 +112,10 @@ static VSTRING *make_821_quoted_string(VSTRING *dst, char *local_part, char *end
      * Put quotes around the result, and prepend a backslash to characters
      * that need quoting when they occur in a quoted-string.
      */
-    VSTRING_RESET(dst);
     VSTRING_ADDCH(dst, '"');
     for (cp = local_part; cp < end && (ch = *cp) != 0; cp++) {
-       if (ch > 127 || ch == '\r' || ch == '\n' || ch == '"' || ch == '\\')
+       if ((ch > 127 && !(flags & QUOTE_FLAG_8BITCLEAN))
+           || ch == '\r' || ch == '\n' || ch == '"' || ch == '\\')
            VSTRING_ADDCH(dst, '\\');
        VSTRING_ADDCH(dst, ch);
     }
@@ -134,10 +137,12 @@ VSTRING *quote_821_local(VSTRING *dst, char *addr, int flags)
      */
     if ((at = strrchr(addr, '@')) == 0)                /* just in case */
        at = addr + strlen(addr);               /* should not happen */
+    if ((flags & QUOTE_FLAG_APPEND) == 0)
+       VSTRING_RESET(dst);
     if (is_821_dot_string(addr, at, flags)) {
-       return (vstring_strcpy(dst, addr));
+       return (vstring_strcat(dst, addr));
     } else {
-       make_821_quoted_string(dst, addr, at);
+       make_821_quoted_string(dst, addr, at, flags & QUOTE_FLAG_8BITCLEAN);
        return (vstring_strcat(dst, at));
     }
 }
@@ -152,14 +157,15 @@ VSTRING *quote_821_local(VSTRING *dst, char *addr, int flags)
 #include <vstring_vstream.h>
 #include "quote_821_local.h"
 
-main(void)
+int     main(void)
 {
     VSTRING *src = vstring_alloc(100);
     VSTRING *dst = vstring_alloc(100);
 
     while (vstring_fgets_nonl(src, VSTREAM_IN)) {
        vstream_fprintf(VSTREAM_OUT, "%s\n",
-                       vstring_str(quote_821_local(dst, vstring_str(src))));
+                       vstring_str(quote_821_local(dst, vstring_str(src),
+                                                   QUOTE_FLAG_8BITCLEAN)));
        vstream_fflush(VSTREAM_OUT);
     }
     exit(0);
index 93607feb2493070990d1c7fdd5e1d9e4f725599d..54392805d2171183c9498261792a8d392cdca1d5 100644 (file)
@@ -35,6 +35,8 @@
 /*     In violation with RFCs, treat 8-bit text as ordinary text.
 /* .IP QUOTE_FLAG_EXPOSE_AT
 /*     In violation with RFCs, treat `@' as an ordinary character.
+/* .IP QUOTE_FLAG_APPEND
+/*     Append to the result buffer, instead of overwriting it.
 /* .RE
 /* STANDARDS
 /*     RFC 822 (ARPA Internet Text Messages)
@@ -114,7 +116,7 @@ static int is_822_dot_string(const char *local_part, const char *end, int flags)
 /* make_822_quoted_string - make quoted-string from local-part */
 
 static VSTRING *make_822_quoted_string(VSTRING *dst, const char *local_part,
-                                                const char *end)
+                                              const char *end, int flags)
 {
     const char *cp;
     int     ch;
@@ -125,7 +127,8 @@ static VSTRING *make_822_quoted_string(VSTRING *dst, const char *local_part,
      */
     VSTRING_ADDCH(dst, '"');
     for (cp = local_part; cp < end && (ch = *cp) != 0; cp++) {
-       if ( /* ch > 127 || */ ch == '"' || ch == '\\' || ch == '\r')
+       if ((ch > 127 && !(flags & QUOTE_FLAG_8BITCLEAN))
+           || ch == '"' || ch == '\\' || ch == '\r')
            VSTRING_ADDCH(dst, '\\');
        VSTRING_ADDCH(dst, ch);
     }
@@ -153,11 +156,13 @@ VSTRING *quote_822_local(VSTRING *dst, const char *mbox, int flags)
        start = mbox;
     if ((end = strrchr(start, '@')) == 0)
        end = start + strlen(start);
+    if ((flags & QUOTE_FLAG_APPEND) == 0)
+       VSTRING_RESET(dst);
     if (is_822_dot_string(start, end, flags)) {
-       return (vstring_strcpy(dst, mbox));
+       return (vstring_strcat(dst, mbox));
     } else {
-       vstring_strncpy(dst, mbox, start - mbox);
-       make_822_quoted_string(dst, start, end);
+       vstring_strncat(dst, mbox, start - mbox);
+       make_822_quoted_string(dst, start, end, flags & QUOTE_FLAG_8BITCLEAN);
        return (vstring_strcat(dst, end));
     }
 }
@@ -215,7 +220,7 @@ int     main(int unused_argc, char **unused_argv)
     VSTRING *unquoted = vstring_alloc(100);
 
     while (vstring_fgets_nonl(raw, VSTREAM_IN)) {
-       quote_822_local(quoted, STR(raw));
+       quote_822_local(quoted, STR(raw), QUOTE_FLAG_8BITCLEAN);
        vstream_printf("quoted:         %s\n", STR(quoted));
        unquote_822_local(unquoted, STR(quoted));
        vstream_printf("unquoted:       %s\n", STR(unquoted));
index 2c62cf0d8bb7ae8efaedd4b189d6faa7db9c72af..df0e0b8376a13e96da28f27066dac7cdf3d30736 100644 (file)
@@ -13,6 +13,7 @@
   */
 #define QUOTE_FLAG_8BITCLEAN   (1<<0)  /* be 8-bit clean */
 #define QUOTE_FLAG_EXPOSE_AT   (1<<1)  /* @ is ordinary text */
+#define QUOTE_FLAG_APPEND      (1<<2)  /* append, not overwrite */
 
 /* LICENSE
 /* .ad
index 0e392cf0ba5b0f64987641d463d471ac9f0c18b0..8188f1f6e431309ea3680e8fcd75884f0f765cd1 100644 (file)
@@ -35,7 +35,7 @@
 #include <record.h>
 #include <rec_streamlf.h>
 
-main(void)
+int     main(void)
 {
     VSTRING *buf = vstring_alloc(100);
     int     type;
index 4c884309fe0047d6c3814f34d784c2d6571729a7..c506f4939a71966d4c460e767df20eab8382d345 100644 (file)
@@ -230,7 +230,7 @@ static void resolve(char *addr, RESOLVE_REPLY *reply)
     vstream_fflush(VSTREAM_OUT);
 }
 
-main(int argc, char **argv)
+int     main(int argc, char **argv)
 {
     RESOLVE_REPLY reply;
     int     ch;
index 5b1285a14850292a9103e0649baf94e33dfedb22..5cff7e0ba3f7dde3304d60557fabd17eb31e891a 100644 (file)
@@ -197,7 +197,7 @@ static void rewrite(char *rule, char *addr, VSTRING *reply)
     vstream_fflush(VSTREAM_OUT);
 }
 
-main(int argc, char **argv)
+int     main(int argc, char **argv)
 {
     VSTRING *reply;
     int     ch;
index 99f40eef27fb9eca1ad48228f03809075953f9b3..a7da5c5eaab6a5b8dde897f62f5416fa3c9cd928 100644 (file)
@@ -35,7 +35,7 @@
 #include <record.h>
 #include <rec_streamlf.h>
 
-main(void)
+int     main(void)
 {
     VSTRING *buf = vstring_alloc(150);
     int     type;
index 522ff26a1df5c6fda3dab21516fdcf3826fa85f3..bed30deabf54ff169b5abb307195e169b29734c0 100644 (file)
@@ -70,6 +70,7 @@
 
 #include <msg.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include <vstream.h>
 #include <vstring.h>
 #include <msg_vstream.h>
@@ -79,7 +80,7 @@ static void usage(char *progname)
     msg_fatal("usage: %s [-v] patterns string", progname);
 }
 
-main(int argc, char **argv)
+int     main(int argc, char **argv)
 {
     STRING_LIST *list;
     char   *string;
index 997a0355425a84bdfb4960d93d7d54194a52a5ed..097b4c351b723bc3b78118ae64c75879d30a2ff5 100644 (file)
 
 /* Global library. */
 
+#include "quote_822_local.h"
 #include "tok822.h"
 
  /*
@@ -221,6 +222,7 @@ VSTRING *tok822_internalize(VSTRING *vp, TOK822 *tree, int flags)
 
 VSTRING *tok822_externalize(VSTRING *vp, TOK822 *tree, int flags)
 {
+    VSTRING *tmp;
     TOK822 *tp;
 
     if (flags & TOK822_STR_WIPE)
@@ -235,8 +237,20 @@ VSTRING *tok822_externalize(VSTRING *vp, TOK822 *tree, int flags)
                continue;
            }
            break;
+
+           /*
+            * XXX In order to correctly externalize an address, it is not
+            * sufficient to quote individual atoms. There are higher-level
+            * rules that say when an address localpart needs to be quoted.
+            * We wing it with the quote_822_local() routine, which ignores
+            * the issue of atoms in the domain part that would need quoting.
+            */
        case TOK822_ADDR:
-           tok822_externalize(vp, tp->head, TOK822_STR_NONE);
+           tmp = vstring_alloc(100);
+           tok822_internalize(tmp, tp->head, TOK822_STR_NONE);
+           quote_822_local(vp, vstring_str(tmp),
+                           QUOTE_FLAG_8BITCLEAN | QUOTE_FLAG_APPEND);
+           vstring_free(tmp);
            break;
        case TOK822_ATOM:
        case TOK822_COMMENT:
index 169957ac40e1798dc9cef581f35f5b1d7703e9a4..53521f3b558870f7cfb1894603f45455acf25213 100644 (file)
@@ -259,26 +259,21 @@ Externalized, newlines inserted:
 named group: foo@bar,
 baz@barf;
 
->>>wietse@foo (wietse
-       venema)<<<
+>>>wietse@foo (wietse  venema)<<<
 
 Parse tree:
  address
    atom "wietse"
    OP "@"
    atom "foo"
- comment "(wietse
-       venema)"
+ comment "(wietse      venema)"
 
 Internalized:
-wietse@foo (wietse
-       venema)
+wietse@foo (wietse     venema)
 
 Externalized, no newlines inserted:
-wietse@foo (wietse
-       venema)
+wietse@foo (wietse     venema)
 
 Externalized, newlines inserted:
-wietse@foo (wietse
-       venema)
+wietse@foo (wietse     venema)
 
index e53157fc1fb1d65e1b9fa2ca081bdbfb6ab230e9..9ccd01eeb634aca198b033a97fe4b8857c3c78e4 100644 (file)
@@ -339,7 +339,7 @@ static void qmqpd_write_content(QMQPD_STATE *state)
                    "\tid %s; %s", state->queue_id, mail_date(state->time));
     }
 #ifdef RECEIVED_ENVELOPE_FROM
-    quote_822_local(state->buf, state->sender);
+    quote_822_local(state->buf, state->sender, QUOTE_FLAG_8BITCLEAN);
     rec_fprintf(state->cleanup, REC_TYPE_NORM,
                "\t(envelope-from <%s>)", STR(state->buf));
 #endif
index 497907ea84c16f9998f80c0b23875dec0798618e..fdd063caffe590ac52d8d8ae53a64f8371dbab98 100644 (file)
 #include <tok822.h>
 #include <verp_sender.h>
 #include <string_list.h>
+#include <quote_822_local.h>
 
 /* Single-threaded server skeleton. */
 
@@ -939,9 +940,9 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
                    "\tby %s (%s) with %s id %s",
                    var_myhostname, var_mail_name,
                    state->protocol, state->queue_id);
-       /* XXX Should RFC 822 externalize recipient address */
+       quote_822_local(state->buffer, state->recipient, QUOTE_FLAG_8BITCLEAN);
        rec_fprintf(state->cleanup, REC_TYPE_NORM,
-               "\tfor <%s>; %s", state->recipient, mail_date(state->time));
+               "\tfor <%s>; %s", STR(state->buffer), mail_date(state->time));
     } else {
        rec_fprintf(state->cleanup, REC_TYPE_NORM,
                    "\tby %s (%s) with %s",
@@ -950,9 +951,9 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
                    "\tid %s; %s", state->queue_id, mail_date(state->time));
     }
 #ifdef RECEIVED_ENVELOPE_FROM
-    /* XXX Should RFC 822 externalize sender address */
+    quote_822_local(state->buffer, state->sender, QUOTE_FLAG_8BITCLEAN);
     rec_fprintf(state->cleanup, REC_TYPE_NORM,
-               "\t(envelope-from %s)", state->sender);
+               "\t(envelope-from %s)", STR(state->buffer));
 #endif
     smtpd_chat_reply(state, "354 End data with <CR><LF>.<CR><LF>");
 
index 8e85d57237303cd3ac8d112dcf89ccc731b9e0b3..19bcf4adeab4f6e733ac963438a0dc70d2de12db 100644 (file)
@@ -1760,16 +1760,15 @@ static int check_mail_access(SMTPD_STATE *state, const char *table,
        { if (bare_addr) myfree(bare_addr); return(x); }
 
     /*
-     * Source-routed, non-local, recipient addresses are too suspicious for
-     * returning an "OK" result. The complicated expression below was brought
-     * to you by the keyboard of Victor Duchovni, Morgan Stanley and hacked
-     * up a bit by Wietse.
+     * Source-routed (non-local or virtual) recipient addresses are too
+     * suspicious for returning an "OK" result. The complicated expression
+     * below was brought to you by the keyboard of Victor Duchovni, Morgan
+     * Stanley and hacked up a bit by Wietse.
      */
 #define SUSPICIOUS(domain, reply, state, reply_name, reply_class) \
        (var_allow_untrust_route == 0 \
        && (reply->flags & RESOLVE_FLAG_ROUTED) \
-       && strcmp(reply_class, SMTPD_NAME_RECIPIENT) == 0 \
-       && !resolve_final(state, reply_name, domain))
+       && strcmp(reply_class, SMTPD_NAME_RECIPIENT) == 0)
 
     /*
      * Look up user+foo@domain if the address has an extension, user@domain