Handle a v4mapped sender address given us by a proxy. Bug 2855
[exim.git] / src / exim_monitor / em_main.c
index 69de8dc4d37055ea9d82890243a16dc839e4fc5b..5714b999caad38dd4b8b071b4a5f6dd8cab20d15 100644 (file)
@@ -197,19 +197,47 @@ Returns:     0 if there is no port, else the port number.
 */
 
 int
-host_address_extract_port(uschar *address)
+host_address_extract_port(uschar * address)
 {
-int skip = -3;                     /* Skip 3 dots in IPv4 addresses */
-address--;
-while (*(++address) != 0)
+int port = 0;
+uschar *endptr;
+
+/* Handle the "bracketed with colon on the end" format */
+
+if (*address == '[')
+  {
+  uschar *rb = address + 1;
+  while (*rb != 0 && *rb != ']') rb++;
+  if (*rb++ == 0) return 0;            /* Missing ]; leave invalid address */
+  if (*rb == ':')
+    {
+    port = Ustrtol(rb + 1, &endptr, 10);
+    if (*endptr != 0) return 0;                /* Invalid port; leave invalid address */
+    }
+  else if (*rb != 0) return 0;         /* Bad syntax; leave invalid address */
+  memmove(address, address + 1, rb - address - 2);
+  rb[-2] = 0;
+  }
+
+/* Handle the "dot on the end" format */
+
+else
   {
-  int ch = *address;
-  if (ch == ':') skip = 0;         /* Skip 0 dots in IPv6 addresses */
-    else if (ch == '.' && skip++ >= 0) break;
+  int skip = -3;                       /* Skip 3 dots in IPv4 addresses */
+  address--;
+  while (*(++address) != 0)
+    {
+    int ch = *address;
+    if (ch == ':') skip = 0;           /* Skip 0 dots in IPv6 addresses */
+      else if (ch == '.' && skip++ >= 0) break;
+    }
+  if (*address == 0) return 0;
+  port = Ustrtol(address + 1, &endptr, 10);
+  if (*endptr != 0) return 0;          /* Invalid port; leave invalid address */
+  *address = 0;
   }
-if (*address == 0) return 0;
-*address++ = 0;
-return Uatoi(address);
+
+return port;
 }