RT RT/krbdev.mit.edu: Ticket #7124 krb5_sname_to_principal canonicalization should work with IPv6-only hosts Signed in as guest.
[Logout]

[Home] [Search] [Configuration]

[Display] [History] [Basics] [Dates] [People] [Links] [Jumbo]

 
 

 The Basics  
Id
7124
Status
resolved
Worked
0 min
Priority
0/0
Queue
krb5
 

 Keyword Selections  
Component
Version_reported
Version_Fixed
  • 1.10.2
Target_Version
  • 1.10.2
Tags
  • pullup
 

 Relationships  
Depends on:
Depended on by:
Parents:
Children:

Refers to:
  • 6922: (ghudson) Work around glibc getaddrinfo PTR lookups [review]
Referred to by:
  • 6534: (ghudson) getaddrinfo in src/util/support/fake-addrinfo.c causes leak [resolved]
  • 7164: (tlyu) Work around glibc getaddrinfo PTR lookups [resolved]
  • 7184: (tlyu) Work around glibc getaddrinfo PTR lookups [resolved]
 
 Dates  
Created: Thu May 3 11:15:53 2012
Starts: Not set
Started: Thu May 3 11:15:54 2012
Last Contact: Wed May 16 14:37:52 2012
Due: Not set
Updated: Thu Oct 17 11:23:49 2013 by ghudson
 

 People  
Owner
 ghudson
Requestors
 ghudson@mit.edu, jimc@math.ucla.edu
Cc
 
AdminCc
 
 

 More about Greg Hudson  
Comments about this user:
No comment entered about this user
This user's 25 highest priority tickets:
 
 More about Jim Carter  
Comments about this user:
No comment entered about this user
This user's 25 highest priority tickets:
 

History   Display mode: [Brief headers] [Full headers]
      Thu May  3 11:15:54 2012  ghudson - Ticket created    
     
From: ghudson@mit.edu
Subject: SVN Commit

In sn2princ, getaddrinfo without AI_ADDRCONFIG

When canonicalizing a principal, use AI_CANONNAME alone in the hint
flags for getaddrinfo, for two reasons.  First, it works around a gnu
libc bug where getaddrinfo does a PTR lookup for the canonical name
(we tried to work around this in r24977 bug the addition of
AI_ADDRCONFIG caused the same problem as the use of AF_INET).  Second,
an IPv4-only host should be able create a principal for an IPv6-only
host even if it can't contact the host.

This does result in extra AAAA queries in the common case (IPv4-only
host contacting IPv4-only service), which is unfortunate.  But we need
to leave that optimization up to the platform at this point.

http://src.mit.edu/fisheye/changelog/krb5/?cs=25844
Commit By: ghudson
Revision: 25844
Changed Files:
U   trunk/src/lib/krb5/os/sn2princ.c


Download (untitled) 836b
      Thu May  3 11:15:54 2012  ghudson - Requestor ghudson@mit.edu added    
      Thu May  3 11:15:54 2012  ghudson - Status changed from new to review    
      Thu May  3 11:21:17 2012  ghudson - Ticket 7124 RefersTo ticket 6922.    
      Thu May  3 12:28:59 2012  ghudson - Subject changed from [no subject] to krb5_sname_to_principal canonicalization should work with IPv6-only hosts    
      Tue May 15 23:12:22 2012  jimc@math.ucla.edu - Ticket 7132: Ticket created    
     
Date: Tue, 15 May 2012 17:55:56 -0700 (PDT)
From: Jim Carter <jimc@math.ucla.edu>
To: krb5-bugs@mit.edu
Subject: Reverse DNS happens despite rdns=false

Distro: OpenSuSE 11.4
Version: krb5-1.8.3-16.19.2.x86_64
Library: /usr/lib64/libkrb5.so.3.3
Subroutine: sn2princ()

I have a server whose wild side is on a residential DSL line.  Its IP
address changes randomly and the "A" record for its wild-side name is
updated by dynamic DNS (dyndns.com).  The ISP has PTR records for the
DHCP addresses, which are not under my control.  I want to use Kerberos
for outside clients (my work machine and laptop) to authenticate, using
the dyndns "A" record as the server name.  The current services are
XMPP/GSSAPI (Prosody) and HTTPS/SPNEGO (Apache proxy for SOGo).

Other use-cases for rdns=false are where the clients use a CNAME for the
server, and where there are multiple "A" records with the same name, for
load sharing among multiple servers.

I've set /etc/krb5.conf [libdefaults] rdns=false on both the server and
the client, but even so, both the server and the client are seen to
retrieve the PTR record for the IP address, and fail to do Kerberos
authentication (GSSAPI).  If I hijack the ISP's realm and create a
principal for the wild-side canonical name (PTR value), they can
authenticate, but obviously this is not a satsifactory solution.

The reason RDNS is still happening is that getaddrinfo is being asked
(with the AI_CANONNAME flag) to determine the server's canonical name,
and the subroutine uses it unconditionally.  The included patch makes
that behavior conditional on the rdns configuration variable.

With the patched library (client and server) the client gets a service
ticket for the correct wild-side name, the server knows its correct name
and finds its key in the keytab, the server believes in my service
ticket, and it lets me on.  The Prosody XMPP server had to be hacked to
use a configured name rather than inferring it from gethostname() which
gives the name on the local LAN.  I think Apache's mod_kerb needs the
same treatment but I haven't finished the hack yet.

The existing conditionalized reverse lookup may actually not be needed,
since getaddrinfo has already done it (per AI_CANONNAME if given), but I
didn't mess with code that wasn't actually broken.

If a string representation of a numeric IP address is passed in, we want
to always get the canonical name.  The test I used to recognize a
numeric address is kind of lameass; it would consider deadbeef.adb.be
to be numeric.  (As well as fe80::210:60ff:fe15:85f4 as it should.)  If
someone knows a neat test for a numeric IP, this is where it's needed.

James F. Carter          Voice 310 825 2897    FAX 310 206 6673
UCLA-Mathnet;  6115 MSA; 405 Hilgard Ave.; Los Angeles, CA, USA 90095-1555
Email: jimc@math.ucla.edu  http://www.math.ucla.edu/~jimc (q.v. for PGP key)

The patch:

If rdns (reverse DNS lookup) is false, use the caller-provided server
name and head off getaddrinfo() from looking up the PTR record to get
the server's canonical name.  Except if given a numerical IP address.

Index: src/lib/krb5/os/sn2princ.c
===================================================================
--- src/lib/krb5/os/sn2princ.c.orig	2012-05-10 19:47:03.177952712 -0700
+++ src/lib/krb5/os/sn2princ.c	2012-05-14 13:08:19.954180561 -0700
@@ -67,6 +67,7 @@
  {
      char **hrealms, *realm, *remote_host;
      krb5_error_code retval;
+    int use_rdns, numeric_ip;
      register char *cp;
      char localname[MAXHOSTNAMELEN];

@@ -95,6 +96,12 @@
              struct addrinfo *ai, hints;
              int err;
              char hnamebuf[NI_MAXHOST];
+                /* Always use RDNS if hostname is numeric.  Will getaddrinfo
+                   return AI_NUMERICHOST, so this lameass test is not needed?
+                   The man page doesn't say so.  (Example: deadbeef.aed.be) */
+            use_rdns = maybe_use_reverse_dns(context, DEFAULT_RDNS_LOOKUP) ||
+                (strspn(hostname, "0123456789.:abcdefABCDEF") ==
+                strlen(hostname));

              /* Note that the old code would accept numeric addresses,
                 and if the gethostbyaddr step could convert them to
@@ -108,7 +115,12 @@

              memset(&hints, 0, sizeof(hints));
              hints.ai_family = AF_INET;
-            hints.ai_flags = AI_CANONNAME|AI_ADDRCONFIG;
+                /*
+                 * In DNS, the canonical name is what the PTR record says.
+                 * If we suppress RDNS, we want to see our CNAME, not the
+                 * canonical name, and can do without an unwanted PTR lookup.
+                 */
+            hints.ai_flags = AI_ADDRCONFIG | (use_rdns ? AI_CANONNAME : 0);
          try_getaddrinfo_again:
              err = getaddrinfo(hostname, 0, &hints, &ai);
              if (err) {
@@ -122,13 +134,13 @@
                  }
                  return KRB5_ERR_BAD_HOSTNAME;
              }
-            remote_host = strdup(ai->ai_canonname ? ai->ai_canonname : hostname);
+            remote_host = strdup((use_rdns && ai->ai_canonname) ? ai->ai_canonname :
hostname);
              if (!remote_host) {
                  freeaddrinfo(ai);
                  return ENOMEM;
              }

-            if (maybe_use_reverse_dns(context, DEFAULT_RDNS_LOOKUP)) {
+            if (use_rdns) {
                  /*
                   * Do a reverse resolution to get the full name, just in
                   * case there's some funny business going on.  If there


Download (untitled) 5.2k
      Wed May 16 00:12:59 2012  ghudson - Ticket 7132: Correspondence added    
     
This is a gnu libc bug.  AI_CANONNAME is not supposed to do a PTR lookup,
and in fact doesn't do so in most circumstances.  The trunk code works
around this bug as of May 3 (issue #7124); we thought we had worked around
the bug in 1.10 (issue #6922) but it turns out that AI_ADDRCONFIG triggers
the bug as does AF_INET4.

The suggested patch turns off too much canonicalization.  The desired
behavior with rdns=false is that the search domain is appended and CNAMES
are resolved, but no PTR lookup is performed.


Download (untitled) 517b
      Wed May 16 00:18:50 2012  ghudson - Ticket 7132: Ticket 7132 MergedInto ticket 7124.    
      Wed May 16 14:06:56 2012  tlyu - Target_Version 1.10.2 added    
      Wed May 16 14:06:56 2012  tlyu - Tags pullup added    
      Wed May 16 14:37:51 2012  tlyu - Status changed from review to resolved    
      Wed May 16 14:37:51 2012  tlyu - Version_Fixed 1.10.2 added    
      Wed May 16 14:37:51 2012  tlyu - Correspondence added    
     
From: tlyu@mit.edu
Subject: SVN Commit


In sn2princ, getaddrinfo without AI_ADDRCONFIG

When canonicalizing a principal, use AI_CANONNAME alone in the hint
flags for getaddrinfo, for two reasons.  First, it works around a gnu
libc bug where getaddrinfo does a PTR lookup for the canonical name
(we tried to work around this in r24977 bug the addition of
AI_ADDRCONFIG caused the same problem as the use of AF_INET).  Second,
an IPv4-only host should be able create a principal for an IPv6-only
host even if it can't contact the host.

This does result in extra AAAA queries in the common case (IPv4-only
host contacting IPv4-only service), which is unfortunate.  But we need
to leave that optimization up to the platform at this point.

(cherry picked from commit c3ab5fe0b01a68b14d5657740006488721b48b7b)

https://github.com/krb5/krb5/commit/57738b357e8b03bcb7af2f147c97cb84d0ce96e2
Author: Greg Hudson <ghudson@mit.edu>
Committer: Tom Yu <tlyu@mit.edu>
Commit: 57738b357e8b03bcb7af2f147c97cb84d0ce96e2
Branch: krb5-1.10
 src/lib/krb5/os/sn2princ.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)


Download (untitled) 1k
      Fri Mar  1 01:29:37 2013  ghudson - Comments added    
     
 

     
Some more information on the underlying getaddrinfo issue:

* The attached test program can be used to demonstrate the issue.

* On Ubuntu 12.04 or 12.10, getaddrinfo appears to do a PTR lookup for
ai_canonname if given either the AI_ADDRCONFIG flag is specified or an
address family is given in the hint.  On test versions of Ubuntu 13.04,
the AI_ADDRCONFIG flag doesn't appear to cause the PTR lookup, but an
address family still does.

* Unmodified glibc master sources (as of today) match the Ubuntu 13.04
behavior.  This is not surprising as 13.04 is based on eglibc 2.17.

* Unmodified glibc 2.15 sources *also* match the Ubuntu 13.04 behavior.
This is surprising to me, because Ubuntu 12.04 and 12.10 are based on
eglibc 2.15, and I haven't been able to find a relevant change in either
eglibc or in the Ubuntu package's patches.

* I reported the AF_INET part of the problem upstream:
http://sourceware.org/bugzilla/show_bug.cgi?id=15218

Download (untitled) 954b
     
 
Download addrtest.c 974b
      Sat Mar  2 02:36:30 2013  ghudson - Comments added    
     
Distribution bugs for the underlying getaddrinfo bug:

Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=550428
Ubuntu: https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/1057526
RHEL: https://bugzilla.redhat.com/show_bug.cgi?id=714823


Download (untitled) 245b
      Thu Oct 17 11:23:49 2013  ghudson - Comments added    
     
The upstream problem should be fixed in glibc 2.19 by this commit:

commit b957ced8890a4438c8efe2c15e5abf4e327f25cf
Author: Andreas Schwab <schwab@suse.de>
Date:   Tue Oct 15 10:21:13 2013 +0200

    Don't use gethostbyaddr to determine canonical name


Download (untitled) 251b