From: "Jason A. Donenfeld" <[email protected]>

This adds two options to the listen on directive.

hide-received prevents a received line from being added for ingress from
that listener.

mask-received prevents the IP address of the sender from leaking into
the received lines.

The former is useful for avoiding dkimproxy cluttering up the message.
The latter is useful for privacy reasons, and would be used to hide the
IP address of authenticated senders on submission the listener.

Please note that I've sort of blindly changed some flag structs from
uint8_t to uint16_t, and I'm sure I changed too many, so you might want
to look at this, and also make sure it actually compiles and whanot.
---
 smtpd/control.c      |  2 +-
 smtpd/parse.y        | 36 ++++++++++++++++++++++--------------
 smtpd/smtp_session.c | 37 +++++++++++++++++++++++++------------
 smtpd/smtpd.h        |  6 ++++--
 smtpd/ssl.c          |  2 +-
 smtpd/ssl.h          |  2 +-
 smtpd/to.c           |  2 +-
 7 files changed, 55 insertions(+), 32 deletions(-)

diff --git a/smtpd/control.c b/smtpd/control.c
index 17e7757..55320b4 100644
--- a/smtpd/control.c
+++ b/smtpd/control.c
@@ -48,7 +48,7 @@
 
 struct ctl_conn {
        uint32_t                 id;
-       uint8_t                  flags;
+       uint16_t                 flags;
 #define CTL_CONN_NOTIFY                 0x01
        struct mproc             mproc;
        uid_t                    euid;
diff --git a/smtpd/parse.y b/smtpd/parse.y
index 775d85a..71c15cc 100644
--- a/smtpd/parse.y
+++ b/smtpd/parse.y
@@ -128,11 +128,11 @@ typedef struct {
 %token  RELAY BACKUP VIA DELIVER TO LMTP MAILDIR MBOX HOSTNAME HELO
 %token ACCEPT REJECT INCLUDE ERROR MDA FROM FOR SOURCE
 %token ARROW AUTH TLS LOCAL VIRTUAL TAG TAGGED ALIAS FILTER KEY
-%token AUTH_OPTIONAL TLS_REQUIRE USERBASE SENDER
+%token AUTH_OPTIONAL TLS_REQUIRE USERBASE SENDER HIDERECEIVED MASKRECEIVED
 %token <v.string>      STRING
 %token  <v.number>     NUMBER
 %type  <v.table>       table
-%type  <v.number>      port auth ssl size expire
+%type  <v.number>      port auth ssl size expire received
 %type  <v.table>       tables tablenew tableref destination alias virtual 
usermapping userbase credentials from sender
 %type  <v.maddr>       relay_as
 %type  <v.string>      certificate tag tagged relay_source listen_helo 
relay_helo relay_backup
@@ -245,6 +245,11 @@ ssl                : SMTPS                         { $$ = 
F_SMTPS; }
                | /* Empty */                   { $$ = 0; }
                ;
 
+received       : HIDERECEIVED                  { $$ = F_HIDE_RECEIVED; }
+               | MASKRECEIVED                  { $$ = F_MASK_RECEIVED; }
+               | /* Empty */                   { $$ = 0; }
+               ;
+
 auth           : AUTH                          {
                        $$ = F_AUTH|F_AUTH_REQUIRE;
                }
@@ -358,14 +363,15 @@ main              : BOUNCEWARN {
                }
                | LISTEN {
                        bzero(&l, sizeof l);
-               } ON STRING port ssl certificate auth tag listen_helo {
+               } ON STRING port ssl certificate auth tag listen_helo received {
                        char           *ifx  = $4;
                        in_port_t       port = $5;
-                       uint8_t         ssl  = $6;
+                       uint16_t        ssl  = $6;
                        char           *cert = $7;
-                       uint8_t         auth = $8;
+                       uint16_t        auth = $8;
                        char           *tag  = $9;
                        char           *helo = $10;
+                       uint16_t       *received = $11;
 
                        if (port != 0 && ssl == F_SSL) {
                                yyerror("invalid listen option: tls/smtps on 
same port");
@@ -380,9 +386,9 @@ main                : BOUNCEWARN {
                        if (port == 0) {
                                if (ssl & F_SMTPS) {
                                        if (! interface(ifx, tag, cert, 
conf->sc_listeners,
-                                               MAX_LISTEN, 465, l.authtable, 
F_SMTPS|auth, helo)) {
+                                               MAX_LISTEN, 465, l.authtable, 
F_SMTPS|auth|received, helo)) {
                                                if (host(ifx, tag, cert, 
conf->sc_listeners,
-                                                       MAX_LISTEN, 465, 
l.authtable, ssl|auth, helo) <= 0) {
+                                                       MAX_LISTEN, 465, 
l.authtable, ssl|auth|received, helo) <= 0) {
                                                        yyerror("invalid 
virtual ip or interface: %s", ifx);
                                                        YYERROR;
                                                }
@@ -390,9 +396,9 @@ main                : BOUNCEWARN {
                                }
                                if (! ssl || (ssl & ~F_SMTPS)) {
                                        if (! interface(ifx, tag, cert, 
conf->sc_listeners,
-                                               MAX_LISTEN, 25, l.authtable, 
(ssl&~F_SMTPS)|auth, helo)) {
+                                               MAX_LISTEN, 25, l.authtable, 
(ssl&~F_SMTPS)|auth|received, helo)) {
                                                if (host(ifx, tag, cert, 
conf->sc_listeners,
-                                                       MAX_LISTEN, 25, 
l.authtable, ssl|auth, helo) <= 0) {
+                                                       MAX_LISTEN, 25, 
l.authtable, ssl|auth|received, helo) <= 0) {
                                                        yyerror("invalid 
virtual ip or interface: %s", ifx);
                                                        YYERROR;
                                                }
@@ -401,9 +407,9 @@ main                : BOUNCEWARN {
                        }
                        else {
                                if (! interface(ifx, tag, cert, 
conf->sc_listeners,
-                                       MAX_LISTEN, port, l.authtable, 
ssl|auth, helo)) {
+                                       MAX_LISTEN, port, l.authtable, 
ssl|auth|received, helo)) {
                                        if (host(ifx, tag, cert, 
conf->sc_listeners,
-                                               MAX_LISTEN, port, l.authtable, 
ssl|auth, helo) <= 0) {
+                                               MAX_LISTEN, port, l.authtable, 
ssl|auth|received, helo) <= 0) {
                                                yyerror("invalid virtual ip or 
interface: %s", ifx);
                                                YYERROR;
                                        }
@@ -978,6 +984,7 @@ lookup(char *s)
                { "for",                FOR },
                { "from",               FROM },
                { "helo",               HELO },
+               { "hide-received",      HIDERECEIVED },
                { "hostname",           HOSTNAME },
                { "include",            INCLUDE },
                { "key",                KEY },
@@ -985,6 +992,7 @@ lookup(char *s)
                { "lmtp",               LMTP },
                { "local",              LOCAL },
                { "maildir",            MAILDIR },
+               { "mask-received",      MASKRECEIVED },
                { "max-message-size",   MAXMESSAGESIZE },
                { "mbox",               MBOX },
                { "mda",                MDA },
@@ -1567,7 +1575,7 @@ host_v6(const char *s, in_port_t port)
 
 int
 host_dns(const char *s, const char *tag, const char *cert,
-    struct listenerlist *al, int max, in_port_t port, uint8_t flags)
+    struct listenerlist *al, int max, in_port_t port, uint16_t flags)
 {
        struct addrinfo          hints, *res0, *res;
        int                      error, cnt = 0;
@@ -1634,7 +1642,7 @@ host_dns(const char *s, const char *tag, const char *cert,
 
 int
 host(const char *s, const char *tag, const char *cert, struct listenerlist *al,
-    int max, in_port_t port, const char *authtable, uint8_t flags,
+    int max, in_port_t port, const char *authtable, uint16_t flags,
     const char *helo)
 {
        struct listener *h;
@@ -1673,7 +1681,7 @@ host(const char *s, const char *tag, const char *cert, 
struct listenerlist *al,
 
 int
 interface(const char *s, const char *tag, const char *cert,
-    struct listenerlist *al, int max, in_port_t port, const char *authtable, 
uint8_t flags,
+    struct listenerlist *al, int max, in_port_t port, const char *authtable, 
uint16_t flags,
     const char *helo)
 {
        struct ifaddrs *ifap, *p;
diff --git a/smtpd/smtp_session.c b/smtpd/smtp_session.c
index f53c83f..3a4ff29 100644
--- a/smtpd/smtp_session.c
+++ b/smtpd/smtp_session.c
@@ -367,19 +367,31 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
                        io_reload(&s->io);
                        return;
                }
+               if (s->listener->flags & F_HIDE_RECEIVED)
+                       goto skip_received;
 
-               fprintf(s->ofile,
-                   "Received: from %s (%s [%s]);\n"
-                   "\tby %s (%s) with %sSMTP%s%s id %08x;\n",
-                   s->evp.helo,
-                   s->hostname,
-                   ss_to_text(&s->ss),
-                   s->listener->helo[0] ? s->listener->helo : env->sc_hostname,
-                   SMTPD_NAME,
-                   s->flags & SF_EHLO ? "E" : "",
-                   s->flags & SF_SECURE ? "S" : "",
-                   s->flags & SF_AUTHENTICATED ? "A" : "",
-                   evpid_to_msgid(s->evp.id));
+               if (s->listener->flags & F_MASK_RECEIVED)
+                       fprintf(s->ofile,
+                           "Received: by %s (%s) with %sSMTP%s%s id %08x;\n",
+                           s->listener->helo[0] ? s->listener->helo : 
env->sc_hostname,
+                           SMTPD_NAME,
+                           s->flags & SF_EHLO ? "E" : "",
+                           s->flags & SF_SECURE ? "S" : "",
+                           s->flags & SF_AUTHENTICATED ? "A" : "",
+                           evpid_to_msgid(s->evp.id));
+               else
+                       fprintf(s->ofile,
+                           "Received: from %s (%s [%s]);\n"
+                           "\tby %s (%s) with %sSMTP%s%s id %08x;\n",
+                           s->evp.helo,
+                           s->hostname,
+                           ss_to_text(&s->ss),
+                           s->listener->helo[0] ? s->listener->helo : 
env->sc_hostname,
+                           SMTPD_NAME,
+                           s->flags & SF_EHLO ? "E" : "",
+                           s->flags & SF_SECURE ? "S" : "",
+                           s->flags & SF_AUTHENTICATED ? "A" : "",
+                           evpid_to_msgid(s->evp.id));
 
                if (s->flags & SF_SECURE) {
                        fprintf(s->ofile,
@@ -403,6 +415,7 @@ smtp_session_imsg(struct mproc *p, struct imsg *imsg)
 
                fprintf(s->ofile, "\t%s\n", time_to_text(time(NULL)));
 
+       skip_received:
                smtp_enter_state(s, STATE_BODY);
                smtp_reply(s, "354 Enter mail, end with \".\""
                    " on a line by itself");
diff --git a/smtpd/smtpd.h b/smtpd/smtpd.h
index 5f794f8..7fd78cc 100644
--- a/smtpd/smtpd.h
+++ b/smtpd/smtpd.h
@@ -109,6 +109,8 @@
 #define        F_STARTTLS_REQUIRE      0x20
 #define        F_AUTH_REQUIRE          0x40
 #define        F_LMTP                  0x80
+#define        F_HIDE_RECEIVED         0x100
+#define        F_MASK_RECEIVED         0x200
 
 #define F_SCERT                        0x01
 #define F_CCERT                        0x02
@@ -136,7 +138,7 @@ struct netaddr {
 };
 
 struct relayhost {
-       uint8_t flags;
+       uint16_t flags;
        char hostname[SMTPD_MAXHOSTNAMELEN];
        uint16_t port;
        char cert[SMTPD_MAXPATHLEN];
@@ -532,7 +534,7 @@ enum envelope_field {
 };
 
 struct listener {
-       uint8_t                  flags;
+       uint16_t                 flags;
        int                      fd;
        struct sockaddr_storage  ss;
        in_port_t                port;
diff --git a/smtpd/ssl.c b/smtpd/ssl.c
index 2f14157..4ae60d7 100644
--- a/smtpd/ssl.c
+++ b/smtpd/ssl.c
@@ -240,7 +240,7 @@ ssl_ctx_create(void)
 }
 
 int
-ssl_load_certfile(struct ssl **sp, const char *path, const char *name, uint8_t 
flags)
+ssl_load_certfile(struct ssl **sp, const char *path, const char *name, 
uint16_t flags)
 {
        struct ssl     *s;
        char            pathname[PATH_MAX];
diff --git a/smtpd/ssl.h b/smtpd/ssl.h
index 640dc63..59e6951 100644
--- a/smtpd/ssl.h
+++ b/smtpd/ssl.h
@@ -28,7 +28,7 @@ struct ssl {
        off_t                    ssl_key_len;
        char                    *ssl_dhparams;
        off_t                    ssl_dhparams_len;
-       uint8_t                  flags;
+       uint16_t                 flags;
 };
 
 /* ssl.c */
diff --git a/smtpd/to.c b/smtpd/to.c
index 1c6219c..b703dee 100644
--- a/smtpd/to.c
+++ b/smtpd/to.c
@@ -347,7 +347,7 @@ text_to_relayhost(struct relayhost *relay, const char *s)
 {
        static const struct schema {
                const char      *name;
-               uint8_t          flags;
+               uint16_t         flags;
        } schemas [] = {
                { "smtp://",            0                               },
                { "lmtp://",            F_LMTP                          },
-- 
1.8.2.1


-- 
You received this email because you are subscribed to mailing list: 
[email protected]
To unsubscribe, send mail with subject:
        [[email protected]] unregister

Reply via email to