Merge branch 'debian'
[hcoop/debian/exim4.git] / debian / patches / 75_08-Logging-fix-initial-listening-on-log-line.patch
diff --git a/debian/patches/75_08-Logging-fix-initial-listening-on-log-line.patch b/debian/patches/75_08-Logging-fix-initial-listening-on-log-line.patch
new file mode 100644 (file)
index 0000000..4af2972
--- /dev/null
@@ -0,0 +1,206 @@
+From e5be948a65fe601024e5d4256f64efbfed3dd72e Mon Sep 17 00:00:00 2001
+From: Jeremy Harris <jgh146exb@wizmail.org>
+Date: Mon, 18 Mar 2019 00:31:43 +0000
+Subject: [PATCH 4/5] Logging: fix initial listening-on log line
+
+(cherry picked from commit 254f38d1c5ada5e4df0bccb385dc466549620c71)
+---
+ doc/ChangeLog |  4 +++
+ src/daemon.c      | 73 +++++++++++++++++++++++++++----------------
+ src/host.c        |  1 +
+ src/structs.h     |  1 +
+ test/confs/0282       |  2 +-
+ test/log/0282         |  2 +-
+ 6 files changed, 54 insertions(+), 29 deletions(-)
+
+diff --git a/doc/ChangeLog b/doc/ChangeLog
+index 0f8d05b2..3c0ffbf0 100644
+--- a/doc/ChangeLog
++++ b/doc/ChangeLog
+@@ -23,10 +23,14 @@ JB/01 Bug 2375: fix expansions of 822 addresses having comments in local-part
+ JH/08 Add hardening against SRV & TLSA lookups the hit CNAMEs (a nonvalid
+       configuration).  If a CNAME target was not a wellformed name pattern, a
+       crash could result.
++JH/09 Logging: Fix initial listening-on line for multiple ports for an IP when
++      the OS reports them interleaved with other addresses.
++
++
+ Exim version 4.92
+ -----------------
+ JH/01 Remove code calling the customisable local_scan function, unless a new
+diff --git a/src/daemon.c b/src/daemon.c
+index a852192e..01da3936 100644
+--- a/src/daemon.c
++++ b/src/daemon.c
+@@ -1625,12 +1625,12 @@ if (f.inetd_wait_mode)
+ else if (f.daemon_listen)
+   {
+   int i, j;
+   int smtp_ports = 0;
+   int smtps_ports = 0;
+-  ip_address_item * ipa, * i2;
+-  uschar * p = big_buffer;
++  ip_address_item * ipa;
++  uschar * p;
+   uschar * qinfo = queue_interval > 0
+     ? string_sprintf("-q%s", readconf_printtime(queue_interval))
+     : US"no queue runs";
+   /* Build a list of listening addresses in big_buffer, but limit it to 10
+@@ -1638,73 +1638,92 @@ else if (f.daemon_listen)
+   It is now possible to have some ports listening for SMTPS (the old,
+   deprecated protocol that starts TLS without using STARTTLS), and others
+   listening for standard SMTP. Keep their listings separate. */
+-  for (j = 0; j < 2; j++)
++  for (int j = 0, i; j < 2; j++)
+     {
+     for (i = 0, ipa = addresses; i < 10 && ipa; i++, ipa = ipa->next)
+       {
+       /* First time round, look for SMTP ports; second time round, look for
+-      SMTPS ports. For the first one of each, insert leading text. */
++      SMTPS ports. Build IP+port strings. */
+       if (host_is_tls_on_connect_port(ipa->port) == (j > 0))
+       {
+       if (j == 0)
+-        {
+-        if (smtp_ports++ == 0)
+-          {
+-          memcpy(p, "SMTP on", 8);
+-          p += 7;
+-          }
+-        }
++        smtp_ports++;
+       else
+-        if (smtps_ports++ == 0)
+-          p += sprintf(CS p, "%sSMTPS on",
+-            smtp_ports == 0 ? "" : " and for ");
++        smtps_ports++;
+       /* Now the information about the port (and sometimes interface) */
+       if (ipa->address[0] == ':' && ipa->address[1] == 0)
+         {                                             /* v6 wildcard */
+         if (ipa->next && ipa->next->address[0] == 0 &&
+             ipa->next->port == ipa->port)
+           {
+-          p += sprintf(CS p, " port %d (IPv6 and IPv4)", ipa->port);
+-          ipa = ipa->next;
++          ipa->log = string_sprintf(" port %d (IPv6 and IPv4)", ipa->port);
++          (ipa = ipa->next)->log = NULL;
+           }
+         else if (ipa->v6_include_v4)
+-          p += sprintf(CS p, " port %d (IPv6 with IPv4)", ipa->port);
++          ipa->log = string_sprintf(" port %d (IPv6 with IPv4)", ipa->port);
+         else
+-          p += sprintf(CS p, " port %d (IPv6)", ipa->port);
++          ipa->log = string_sprintf(" port %d (IPv6)", ipa->port);
+         }
+       else if (ipa->address[0] == 0)                  /* v4 wildcard */
+-        p += sprintf(CS p, " port %d (IPv4)", ipa->port);
++        ipa->log = string_sprintf(" port %d (IPv4)", ipa->port);
+       else                            /* check for previously-seen IP */
+         {
++        ip_address_item * i2;
+         for (i2 = addresses; i2 != ipa; i2 = i2->next)
+           if (  host_is_tls_on_connect_port(i2->port) == (j > 0)
+              && Ustrcmp(ipa->address, i2->address) == 0
+              )
+             {                         /* found; append port to list */
+-            if (p[-1] == '}') p--;
+-            while (isdigit(*--p)) ;
+-            p +=  1 + sprintf(CS p+1, "%s%d,%d}", *p == ',' ? "" : "{",
+-              i2->port, ipa->port);
++            for (p = i2->log; *p; ) p++;      /* end of existing string */
++            if (*--p == '}') *p = '\0';       /* drop EOL */
++            while (isdigit(*--p)) ;           /* char before port */
++
++            i2->log = *p == ':'               /* no list yet? */
++              ? string_sprintf("%.*s{%s,%d}",
++                (int)(p - i2->log + 1), i2->log, p+1, ipa->port)
++              : string_sprintf("%s,%d}", i2->log, ipa->port);
++            ipa->log = NULL;
+             break;
+             }
+         if (i2 == ipa)                /* first-time IP */
+-          p += sprintf(CS p, " [%s]:%d", ipa->address, ipa->port);
++          ipa->log = string_sprintf(" [%s]:%d", ipa->address, ipa->port);
+         }
+       }
+       }
++    }
+-    if (ipa)
++  p = big_buffer;
++  for (int j = 0, i; j < 2; j++)
++    {
++    /* First time round, look for SMTP ports; second time round, look for
++    SMTPS ports. For the first one of each, insert leading text. */
++
++    if (j == 0)
+       {
+-      memcpy(p, " ...", 5);
+-      p += 4;
++      if (smtp_ports > 0)
++      p += sprintf(CS p, "SMTP on");
+       }
++    else
++      if (smtps_ports > 0)
++      p += sprintf(CS p, "%sSMTPS on",
++        smtp_ports == 0 ? "" : " and for ");
++
++    /* Now the information about the port (and sometimes interface) */
++
++    for (i = 0, ipa = addresses; i < 10 && ipa; i++, ipa = ipa->next)
++      if (host_is_tls_on_connect_port(ipa->port) == (j > 0))
++      if (ipa->log)
++        p += sprintf(CS p, "%s",  ipa->log);
++
++    if (ipa)
++      p += sprintf(CS p, " ...");
+     }
+   log_write(0, LOG_MAIN,
+     "exim %s daemon started: pid=%d, %s, listening for %s",
+     version_string, getpid(), qinfo, big_buffer);
+diff --git a/src/host.c b/src/host.c
+index 29c977fe..a3b0977b 100644
+--- a/src/host.c
++++ b/src/host.c
+@@ -757,10 +757,11 @@ while ((s = string_nextinlist(&list, &sep, NULL, 0)))
+   next = store_get(sizeof(ip_address_item));
+   next->next = NULL;
+   Ustrcpy(next->address, s);
+   next->port = port;
+   next->v6_include_v4 = FALSE;
++  next->log = NULL;
+   if (!yield)
+     yield = last = next;
+   else
+     {
+diff --git a/src/structs.h b/src/structs.h
+index 20db0e5f..1e63d752 100644
+--- a/src/structs.h
++++ b/src/structs.h
+@@ -442,10 +442,11 @@ hold an IPv6 address. */
+ typedef struct ip_address_item {
+   struct ip_address_item *next;
+   int    port;
+   BOOL   v6_include_v4;            /* Used in the daemon */
+   uschar address[46];
++  uschar * log;                          /* portion of "listening on" log line */
+ } ip_address_item;
+ /* Structure for chaining together arbitrary strings. */
+ typedef struct string_item {
+-- 
+2.20.1
+