hello,

smtpd improperly displays inet6 addresses as reported by semarie@:

      address=smtps://IPv6:2a01:e0c:1::25:465

fact is, helo response and Received headers display inet6 addresses
as IPv6:2a01:e0c:1::25 which initially led me to use this format in
smtpd instead of the proper one which is [2a01:e0c:1::25]

this diff ensures the proper format is used internally while having
a specialized ss_to_helo_text() function in smtp_session to use the
alternate format in the two places that actually need it.

special care taken in envelope.c to temporarily accept both formats
in disk envelopes for the transition phase.

diff tested and ok semarie@ who suggested I show it to a broader
audience.


Index: envelope.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/envelope.c,v
retrieving revision 1.43
diff -u -p -r1.43 envelope.c
--- envelope.c  3 Jul 2019 03:24:03 -0000       1.43
+++ envelope.c  11 Aug 2019 12:57:33 -0000
@@ -297,7 +297,16 @@ ascii_load_sockaddr(struct sockaddr_stor
                ss->ss_family = AF_LOCAL;
        }
        else if (strncasecmp("IPv6:", buf, 5) == 0) {
+               /* XXX - remove this after 6.6 release */
                if (inet_pton(AF_INET6, buf + 5, &ssin6.sin6_addr) != 1)
+                       return 0;
+               ssin6.sin6_family = AF_INET6;
+               memcpy(ss, &ssin6, sizeof(ssin6));
+               ss->ss_len = sizeof(struct sockaddr_in6);
+       }
+       else if (buf[0] == '[' && buf[strlen(buf)-1] == ']') {
+               buf[strlen(buf)-1] = '\0';
+               if (inet_pton(AF_INET6, buf+1, &ssin6.sin6_addr) != 1)
                        return 0;
                ssin6.sin6_family = AF_INET6;
                memcpy(ss, &ssin6, sizeof(ssin6));
Index: smtp_session.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/smtp_session.c,v
retrieving revision 1.404
diff -u -p -r1.404 smtp_session.c
--- smtp_session.c      10 Aug 2019 16:07:01 -0000      1.404
+++ smtp_session.c      11 Aug 2019 12:57:34 -0000
@@ -283,6 +283,22 @@ static struct tree wait_ssl_verify;
 static struct tree wait_filters;
 static struct tree wait_filter_fd;
 
+static const char *
+ss_to_helo_text(const struct sockaddr_storage *ss)
+{
+       static char      buf[NI_MAXHOST + 5];
+       static char      helobuf[NI_MAXHOST + 5];
+
+       (void)strlcpy(buf, ss_to_text(ss), sizeof buf);
+
+       if (buf[0] != '[')
+               return buf;
+       buf[strlen(buf)-1] = '\0';
+
+       (void)snprintf(helobuf, sizeof helobuf, "IPv6:%s", buf+1);
+       return helobuf;
+}
+
 static void
 header_append_domain_buffer(char *buffer, char *domain, size_t len)
 {
@@ -1739,7 +1755,7 @@ smtp_proceed_helo(struct smtp_session *s
        smtp_reply(s, "250 %s Hello %s [%s], pleased to meet you",
            s->smtpname,
            s->helo,
-           ss_to_text(&s->ss));
+           ss_to_helo_text(&s->ss));
 }
 
 static void
@@ -1756,7 +1772,7 @@ smtp_proceed_ehlo(struct smtp_session *s
        smtp_reply(s, "250-%s Hello %s [%s], pleased to meet you",
            s->smtpname,
            s->helo,
-           ss_to_text(&s->ss));
+           ss_to_helo_text(&s->ss));
 
        smtp_reply(s, "250-8BITMIME");
        smtp_reply(s, "250-ENHANCEDSTATUSCODES");
@@ -2805,7 +2821,7 @@ smtp_message_begin(struct smtp_tx *tx)
                m_printf(tx, "from %s (%s [%s])",
                    s->helo,
                    s->rdns,
-                   ss_to_text(&s->ss));
+                   ss_to_helo_text(&s->ss));
        }
        m_printf(tx, "\n\tby %s (%s) with %sSMTP%s%s id %08x",
            s->smtpname,
Index: to.c
===================================================================
RCS file: /cvs/src/usr.sbin/smtpd/to.c,v
retrieving revision 1.38
diff -u -p -r1.38 to.c
--- to.c        11 Aug 2019 10:54:44 -0000      1.38
+++ to.c        11 Aug 2019 12:57:34 -0000
@@ -169,10 +169,9 @@ sa_to_text(const struct sockaddr *sa)
                const struct in6_addr   *in6_addr;
 
                in6 = (const struct sockaddr_in6 *)sa;
-               (void)strlcpy(buf, "IPv6:", sizeof(buf));
-               p = buf + 5;
+               p = buf;
                in6_addr = &in6->sin6_addr;
-               (void)bsnprintf(p, NI_MAXHOST, "%s", in6addr_to_text(in6_addr));
+               (void)bsnprintf(p, NI_MAXHOST, "[%s]", 
in6addr_to_text(in6_addr));
        }
 
        return (buf);

-- 
Gilles Chehade                                                 @poolpOrg

https://www.poolp.org            patreon: https://www.patreon.com/gilles

Reply via email to