[Exim] IP parser doesn't recognise link-local addresses

Kezdőlap
Üzenet törlése
Válasz az üzenetre
Szerző: Lionel Elie Mamane
Dátum:  
Címzett: exim-users
Tárgy: [Exim] IP parser doesn't recognise link-local addresses
--
Hi,

The exim IP address parser doesn't recognise IPv6 link-local
addresses, like fe80::210:5aff:fe45:9b17%eth0.

This would be of use mainly for the local_interfaces directive, to
allow connection only from localhost and hosts connected directly to
the same network as the server.

I have written a patch for exim 3.36, tested on Debian GNU/Linux that
addresses this. It does two things:

- add recognition of the '%' separator in the string_is_ip function
- Uses getaddrinfo instead of inet_pton for string to address
conversion.

Here's the patch (the if(res0==NULL) is maybe paranoid):

diff -u --recursive exim-3.36.debian-4/src/daemon.c exim-3.36.lionel/src/daemon.c
--- exim-3.36.debian-4/src/daemon.c    2002-04-04 14:56:16.000000000 +0200
+++ exim-3.36.lionel/src/daemon.c    2003-01-31 09:16:54.000000000 +0100
@@ -830,19 +830,30 @@
     #if HAVE_IPV6
     if (af == AF_INET6)
       {
-      sin.v6.sin6_family = AF_INET6;
-      sin.v6.sin6_port = net_port;
       if (ipa->address[0] == ':' && ipa->address[1] == 0)
         {
+        sin.v6.sin6_family = AF_INET6;
         sin.v6.sin6_addr = anyaddr6;
         DEBUG(9) debug_printf("listening on all interfaces (IPv6)\n");
         }
       else
         {
-        if (inet_pton(AF_INET6, ipa->address, &sin.v6.sin6_addr) != 1)
+        struct addrinfo hints, *res0;
+        memset(&hints, 0, sizeof(hints));
+        hints.ai_family = AF_INET6;
+        hints.ai_socktype = SOCK_STREAM;
+        hints.ai_flags = AI_NUMERICHOST;
+
+        if(getaddrinfo(ipa->address, NULL, &hints, &res0))
+          log_write(0, LOG_PANIC_DIE, "unable to parse \"%s\"", ipa->address);
+        if(res0==NULL)
           log_write(0, LOG_PANIC_DIE, "unable to parse \"%s\"", ipa->address);
         DEBUG(9) debug_printf("listening on %s\n", ipa->address);
+
+        memcpy(&sin.v6, res0->ai_addr, res0->ai_addrlen);
+        freeaddrinfo(res0);
         }
+      sin.v6.sin6_port = net_port;
       }
     else
     #endif  /* HAVE_IPV6 */
diff -u --recursive exim-3.36.debian-4/src/string.c exim-3.36.lionel/src/string.c
--- exim-3.36.debian-4/src/string.c    2002-04-04 14:56:20.000000000 +0200
+++ exim-3.36.lionel/src/string.c    2003-01-31 09:18:22.000000000 +0100
@@ -86,6 +86,12 @@


     if (*s == 0) return had_double_colon? yield : 0;


+    /* If the left of the current position is a valid IPv6 address
+       and we encounter a '%' the right of the current position
+       is the interface specifier (scope id) of a link-local address. */
+
+    if (*s == '%') return had_double_colon? yield : 0;
+
     /* If a component starts with an additional colon, we have hit a double
     colon. This is permitted to appear once only, and counts as at least
     one component. The final component may be of this form. */


--
Lionel
--
[ Content of type application/pgp-signature deleted ]
--