[EXIM] Bug in check_host()? Either that or in linux libc

Top Page
Delete this message
Reply to this message
Author: Mark Baker
Date:  
To: exim-users
Subject: [EXIM] Bug in check_host()? Either that or in linux libc
I had problems with a machine on the local network not being allowed to
relay, when it definitely should have been allowed to (it matches
10.0.0.0/8, which was in host_accept_relay).

I traced the problem to a line in check_host() where it converts the textual
form of the IP address back into binary to test it. It does:

insize = host_aton(host_address, incoming);

All the documentation I can find for host_aton suggests that it isn't
supposed to return a length, but merely any positive value on success, and
that it only works for IPv4 addresses. With linux (glibc 2.1.1) it does
appear to return a length, and to work with proper IPv6 addresses, but fails
to cope (fills in incoming with garbage) with IPv4 compatibility addresses
(like ::ffff:10.0.0.3) which, in a world where most people still use IPv4,
makes a copy of exim compiled with IPv6 support unusable.

I replaced that line with:

  if (strchr(host_address, ':') != NULL)
  {
    inet_pton(AF_INET6, host_address, incoming); 
    incoming[0] = ntohl(incoming[0]);
    incoming[1] = ntohl(incoming[1]);
    incoming[2] = ntohl(incoming[2]);
    incoming[3] = ntohl(incoming[3]);    
    insize = 4;
  }
  else
  {
    inet_pton(AF_INET, host_address, incoming);
    incoming[0] = ntohl(incoming[0]);
    insize = 1;
  }


which seems to work fine.

This will work fine on IPv4-only systems too, but most of them won't support
the inet_pton() API call (since IPv6 was the main reason it was introduced),
so you probably want to make this dependent on HAVE_IPV6 being defined.

I can't explain why the output of inet_pton() needs to be swapped while that
of host_aton() doesn't.

--
*** Exim information can be found at http://www.exim.org/ ***