Bug#573596: libnet-ldap-perl: Net::LDAP passes the wrong remote server identity to SASL
Russ Allbery
rra at debian.org
Fri Mar 12 19:01:30 UTC 2010
Package: libnet-ldap-perl
Version: 1:0.39-1
Severity: normal
The following code in Net::LDAP, introduced in version 0.37 of perl-ldap,
is unfortunately not correct:
# If we're talking to a round-robin, the canonical name of
# the host we are talking to might not match the name we
# requested
my $connected_name = $ldap->{net_ldap_socket}->peerhost;
$connected_name ||= $ldap->{net_ldap_host};
I understand the concern, but this code doesn't accomplish what the author
intended. Rather than pass in the canonical hostname of the server to
which the client actually connected, it's passing in the IP address of the
remote server.
A SASL authentication mechanism that cares about the identity of the remote
server, such as a Kerberos GSSAPI authentication, will now no longer work
correctly. Kerberos, for instance, sees an attempt to authenticate to the
"hostname" of an IP address, takes off the first octet, and then attempts
to do cross-realm authentication to a realm named after the remainder of the
IP address, which of course fails.
This is not horribly clearly documented, but Authen::SASL in the description
of client_new() does note that the second argument is a HOST, which in this
case shouldn't be an IP address.
There are two possible solutions. The most correct solution, in my opinion,
is to simply revert this change and pass in the original host name as given
to Net::LDAP. In general, authentication should be done to the original
host name as specified by the client, not to a canonicalized host name, as
this provides some protection against DNS spoofing. The server should
accept authentications to its canonical advertised LDAP server name, even
if it's one of a series of round-robin systems. If the user really wants
GSSAPI to canonicalize the hostname, there's generally a way to configure
the underlying Kerberos library to do that in krb5.conf.
However, and I suspect this is what the author ran into, doing this properly
requires either accepting only the canonical advertised hostname on the
LDAP server and not, say, the individual server name, or patching Cyrus SASL
so that it properly accepts multiple authentication identities. Hence, it
may be somewhat more reliable to canonicalize before connecting. In that
case, what's missing is a reverse DNS lookup of the resulting IP address to
get back to a hostname. The code should instead look something like:
# If we're talking to a round-robin, the canonical name of
# the host we are talking to might not match the name we
# requested
my $connected_ip = $ldap->{net_ldap_socket}->peeraddr;
my $connected_domain = $ldap->{net_ldap_socket}->sockdomain;
my $connected_name = gethostbyaddr($connected_ip, $connected_domain);
$connected_name ||= $ldap->{net_ldap_host};
(untested) which I think will also work with IPv6.
-- System Information:
Debian Release: squeeze/sid
APT prefers testing
APT policy: (990, 'testing'), (500, 'unstable'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.32-trunk-686-bigmem (SMP w/4 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages libnet-ldap-perl depends on:
ii libconvert-asn1-perl 0.22-1 Perl module for encoding and decod
ii libwww-perl 5.834-1 Perl HTTP/WWW client/server librar
ii perl [libmime-base64-perl] 5.10.1-11 Larry Wall's Practical Extraction
libnet-ldap-perl recommends no packages.
Versions of packages libnet-ldap-perl suggests:
ii libauthen-sasl-perl 2.13-1 Authen::SASL - SASL Authentication
ii libio-socket-ssl-perl 1.31-1 Perl module implementing object or
ii liburi-perl 1.52-1 module to manipulate and access UR
ii libxml-parser-perl 2.36-1.1+b1 Perl module for parsing XML files
ii libxml-sax-perl 0.96+dfsg-2 Perl module for using and building
ii perl [libdigest-md5-perl] 5.10.1-11 Larry Wall's Practical Extraction
-- no debconf information
More information about the pkg-perl-maintainers
mailing list