Re: Kerberos behavior in the presence of multiple PTR records

2013-03-15 Thread Will Fiveash
On Thu, Mar 14, 2013 at 09:39:56PM -0400, Greg Hudson wrote:
> On 03/14/2013 07:08 PM, Yury Sulsky wrote:
> > I'm not sure I understand. The function [krb5_sname_to_principal] takes
> > a candidate hostname (or calls [gethostname] if that argument is NULL),
> > and performs a forward lookup using [getaddrinfo]. It then takes the
> > canonical name and IP address stored in the first addrinfo record and
> > checks that that DNS has a reverse mapping from that IP address to that
> > canonical name, otherwise it fails.
> 
> krb5_sname_to_principal takes whatever answer it gets from the reverse
> lookup and uses that as the canonical hostname (after converting it to
> lowercase and chopping off any trailing dot).  There is no check to see
> if that result is the same as the forward lookup.  Take a look at what
> happens to the remote_host variable after the getnameinfo call.

Note that Solaris krb has never used reverse lookup in
krb5_sname_to_principal() and in the current source:

#if !defined(DEFAULT_RDNS_LOOKUP)
/* Solaris Kerberos */
#define DEFAULT_RDNS_LOOKUP 0
#endif

-- 
Will Fiveash
Oracle Solaris Software Engineer

Kerberos mailing list   Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos


Re: Kerberos behavior in the presence of multiple PTR records

2013-03-15 Thread Tom Yu
Nico Williams  writes:

> On Fri, Mar 15, 2013 at 9:04 AM, Yury Sulsky  wrote:

>> Right, thanks. I should have read more carefully. Still, wouldn't it make
>> sense to iterate through all PTR records and search for one that matches the
>> canonical name returned from the forward lookup? If a record like that does
>> exist, returning that one would allow the user to specify a host that has
>> other canonical names (and multiple PTR records).

> The code here isn't seeing the PTR records.  Instead MIT Kerberos is
> calling system library functions (getnameinfo(3)) that do that, and
> those functions, as I've explained, only look at one PTR RR.

Adapting the code to iterate over multiple PTR records would add
complexity and require calling out to a lower-level DNS resolver API.
In addition, any nsswitch-based hostname information that is not in
DNS would be ignored (unless getnameinfo() were also consulted).

I would prefer to not do this without a really good reason, especially
because we are trying to eventually eliminate the use of hostname
canonicalization for principal name construction in our
implementation.

Kerberos mailing list   Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos


Re: Kerberos behavior in the presence of multiple PTR records

2013-03-15 Thread Nico Williams
On Fri, Mar 15, 2013 at 9:04 AM, Yury Sulsky  wrote:
> On Thu, Mar 14, 2013 at 8:55 PM, Nico Williams 
> wrote:
>>
>> So... there should be just one canonical name (see definition of
>> CNAME) and PTRs (pointers) should point to the primary (canonical)
>> name of the thing.  So why does RFC2181 say that this does not imply
>> that there should only be one PTR RR in any PTR RRSet?!  I don't know.
>>  It seems wrong to me.
>
>
> Nico, thanks for the pointer ( :-) ) to that RFC. This part clears it up for
> me:
>
> 10. Naming issues
>
>It has sometimes been inferred from some sections of the DNS
>specification [RFC1034, RFC1035] that a host, or perhaps an interface
>of a host, is permitted exactly one authoritative, or official, name,
>called the canonical name.  There is no such requirement in the DNS.
>
> It seems that an IP address may belong to multiple canonical names (i.e.
> there may be multiple A and PTR records referring to a single IP), but an
> alias may only point to one of these names (i.e. there can only be one CNAME
> record for a given alias).

Yes, but it doesn't follow that in one case "canonical" means "one"
and in the other it means "many".  And the APIs have resolved this
problem anyways.  This is a case where what the RFCs say is irrelevant
because what got deployed wins.

> On Thu, Mar 14, 2013 at 9:39 PM, Greg Hudson  wrote:
>>
>> There is no check to see if that result is the same as the forward lookup.
>> Take a  look at what happens to the remote_host variable after the
>> getnameinfo call.
>
>
> Right, thanks. I should have read more carefully. Still, wouldn't it make
> sense to iterate through all PTR records and search for one that matches the
> canonical name returned from the forward lookup? If a record like that does
> exist, returning that one would allow the user to specify a host that has
> other canonical names (and multiple PTR records).

The code here isn't seeing the PTR records.  Instead MIT Kerberos is
calling system library functions (getnameinfo(3)) that do that, and
those functions, as I've explained, only look at one PTR RR.

Nico
--

Kerberos mailing list   Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos


Re: Kerberos behavior in the presence of multiple PTR records

2013-03-15 Thread Yury Sulsky
On Thu, Mar 14, 2013 at 8:55 PM, Nico Williams 
 wrote:
>
> So... there should be just one canonical name (see definition of
> CNAME) and PTRs (pointers) should point to the primary (canonical)
> name of the thing.  So why does RFC2181 say that this does not imply
> that there should only be one PTR RR in any PTR RRSet?!  I don't know.
>  It seems wrong to me.
>

Nico, thanks for the pointer ( :-) ) to that RFC. This part clears it up
for me:

10. Naming issues

   It has sometimes been inferred from some sections of the DNS
   specification [RFC1034, RFC1035] that a host, or perhaps an interface
   of a host, is permitted exactly one authoritative, or official, name,
   called the canonical name.  There is no such requirement in the DNS.

It seems that an IP address may belong to multiple canonical names (i.e.
there may be multiple A and PTR records referring to a single IP), but an
alias may only point to one of these names (i.e. there can only be one
CNAME record for a given alias).

On Thu, Mar 14, 2013 at 9:39 PM, Greg Hudson  wrote:

> There is no check to see if that result is the same as the forward
> lookup.  Take a  look at what happens to the remote_host variable after
> the getnameinfo call.
>

Right, thanks. I should have read more carefully. Still, wouldn't it make
sense to iterate through all PTR records and search for one that matches
the canonical name returned from the forward lookup? If a record like that
does exist, returning that one would allow the user to specify a host that
has other canonical names (and multiple PTR records).

Kerberos mailing list   Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos


Re: Kerberos behavior in the presence of multiple PTR records

2013-03-14 Thread Greg Hudson
On 03/14/2013 07:08 PM, Yury Sulsky wrote:
> I'm not sure I understand. The function [krb5_sname_to_principal] takes
> a candidate hostname (or calls [gethostname] if that argument is NULL),
> and performs a forward lookup using [getaddrinfo]. It then takes the
> canonical name and IP address stored in the first addrinfo record and
> checks that that DNS has a reverse mapping from that IP address to that
> canonical name, otherwise it fails.

krb5_sname_to_principal takes whatever answer it gets from the reverse
lookup and uses that as the canonical hostname (after converting it to
lowercase and chopping off any trailing dot).  There is no check to see
if that result is the same as the forward lookup.  Take a look at what
happens to the remote_host variable after the getnameinfo call.


Kerberos mailing list   Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos


Re: Kerberos behavior in the presence of multiple PTR records

2013-03-14 Thread Yury Sulsky
On Thu, Mar 14, 2013 at 4:20 PM, Nico Williams wrote:

> To my knowledge no RFC says that only one PTR RR may exist in any
> given PTR RRSet.  In practice all implementations of getnameinfo(),
> gethostbyaddr(), and the like, use only the first PTR RR in the PTR
> RRSet for obvious semantic reasons: such code is looking for a
> canonical name for an IP address, and more than one name means there's
> no canonical name, thus either failure or "pick one" are the only
> options.
>

Does that mean it's just always a mistake for there to exist more than one
PTR record for a given IP address? I just assumed it's a set operation,
just like you might have multiple A records pointing to the same IP
address, you might have multiple PTR records pointing back at those names.

In any case, you should never want to use PTR RR lookups for principal
> name canonicalization.  (Not unless you are using DNSSEC, which you're
> almost certainly not.)
>

I think this code only uses the reverse lookup as a sanity check, which
fails in an inconsistent manner if there is more than a single PTR record
(depending on which one is returned first).



> Nico
> --
>

Kerberos mailing list   Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos


Re: Kerberos behavior in the presence of multiple PTR records

2013-03-14 Thread Yury Sulsky
On Thu, Mar 14, 2013 at 4:02 PM, Greg Hudson  wrote:

> On 03/14/2013 11:25 AM, Yury Sulsky wrote
> The sname-to-principal code isn't performing a pass-or-fail check; it's
> trying to determine the canonical name of a host.  So if we considered
> multiple PTR records or did PTR lookups for multiple addresses, we would
> have to somehow decide which one to use.
>

I'm not sure I understand. The function [krb5_sname_to_principal] takes a
candidate hostname (or calls [gethostname] if that argument is NULL), and
performs a forward lookup using [getaddrinfo]. It then takes the canonical
name and IP address stored in the first addrinfo record and checks that
that DNS has a reverse mapping from that IP address to that canonical name,
otherwise it fails.

This check is performed using [getnameinfo], so only a single PTR record is
examined (probably the first one, though I guess that depends on the libc
implementation). Would it be incorrect (or somehow insecure) to search
through all PTR records for the canonical name rather than just the one
that's returned by [getnameinfo]?

Kerberos mailing list   Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos


Re: Kerberos behavior in the presence of multiple PTR records

2013-03-14 Thread Nico Williams
On Thu, Mar 14, 2013 at 6:19 PM, Yury Sulsky  wrote:
> On Thu, Mar 14, 2013 at 4:20 PM, Nico Williams 
> wrote:
>> To my knowledge no RFC says that only one PTR RR may exist in any
>> given PTR RRSet.  In practice all implementations of getnameinfo(),
>> gethostbyaddr(), and the like, use only the first PTR RR in the PTR
>> RRSet for obvious semantic reasons: such code is looking for a
>> canonical name for an IP address, and more than one name means there's
>> no canonical name, thus either failure or "pick one" are the only
>> options.
>
> Does that mean it's just always a mistake for there to exist more than one
> PTR record for a given IP address? I just assumed it's a set operation, just
> like you might have multiple A records pointing to the same IP address, you
> might have multiple PTR records pointing back at those names.

In practice yes, it's a mistake.

As for what the RFCs say... it's a bit confusing.  RFC2181 says:

10.2. PTR records

   Confusion about canonical names has lead to a belief that a PTR
   record should have exactly one RR in its RRSet.  This is incorrect,
   the relevant section of RFC1034 (section 3.6.2) indicates that the
   value of a PTR record should be a canonical name.  That is, it should
   not be an alias.  There is no implication in that section that only
   one PTR record is permitted for a name.  No such restriction should
   be inferred.

But "canonical name" in practice, that is, the way APIs are
formulated, means "the one true name", not "the one or more true
names", because a "true name" implies "only one".  Indeed, the
definition of CNAME in RFC1034 is identifies the canonical name of an
alias", which very much says "there's only one canonical name".
Meanwhile what RFC1035 says is:

   Domain names in RRs which point at another name should always point at
   the primary name and not the alias.  This avoids extra indirections in
   accessing information.

So... there should be just one canonical name (see definition of
CNAME) and PTRs (pointers) should point to the primary (canonical)
name of the thing.  So why does RFC2181 say that this does not imply
that there should only be one PTR RR in any PTR RRSet?!  I don't know.
 It seems wrong to me.

In any case, if you were looking for a way to find all of a host's
_aliases_, PTR RRs are not what you're looking for, and indeed,
there's no RR type in DNS for that operation.  Even if there was, it
could only tell you about aliases known / desired-to-be-listed by the
owner of the RRSet name.

>> In any case, you should never want to use PTR RR lookups for principal
>> name canonicalization.  (Not unless you are using DNSSEC, which you're
>> almost certainly not.)
>
> I think this code only uses the reverse lookup as a sanity check, which
> fails in an inconsistent manner if there is more than a single PTR record
> (depending on which one is returned first).

There's no defined order for RRs in an RRSet (they are unordered
sets), therefore having multiple PTR RRs technically results in
non-deterministic behavior by code that picks the first PTR in the
RRset.

Nico
--

Kerberos mailing list   Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos


Re: Kerberos behavior in the presence of multiple PTR records

2013-03-14 Thread Nico Williams
To my knowledge no RFC says that only one PTR RR may exist in any
given PTR RRSet.  In practice all implementations of getnameinfo(),
gethostbyaddr(), and the like, use only the first PTR RR in the PTR
RRSet for obvious semantic reasons: such code is looking for a
canonical name for an IP address, and more than one name means there's
no canonical name, thus either failure or "pick one" are the only
options.

In any case, you should never want to use PTR RR lookups for principal
name canonicalization.  (Not unless you are using DNSSEC, which you're
almost certainly not.)

Nico
--

Kerberos mailing list   Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos


Re: Kerberos behavior in the presence of multiple PTR records

2013-03-14 Thread Greg Hudson
On 03/14/2013 11:25 AM, Yury Sulsky wrote:
> This may be just me misunderstanding PTR records, but it looks like the
> Kerberos library doesn't support multiple records when checking that a
> hostname maps to an ip address that maps back to the same hostname (I think
> this check only takes place if the "rdns" option is set).

The sname-to-principal code isn't performing a pass-or-fail check; it's
trying to determine the canonical name of a host.  So if we considered
multiple PTR records or did PTR lookups for multiple addresses, we would
have to somehow decide which one to use.


Kerberos mailing list   Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos


Kerberos behavior in the presence of multiple PTR records

2013-03-14 Thread Yury Sulsky
Hi guys,

This may be just me misunderstanding PTR records, but it looks like the
Kerberos library doesn't support multiple records when checking that a
hostname maps to an ip address that maps back to the same hostname (I think
this check only takes place if the "rdns" option is set).

My (uninformed) expectation is that the check would make sure that
hostname is a member of one of the sets returned by:

(reverse(ip) for all ips in forward(hostname))

This may be the relevant piece of code (in src/lib/krb5/os/sn2princ.c):

  /*
 * Do a reverse resolution to get the full name, just in
 * case there's some funny business going on.  If there
 * isn't an in-addr record, give up.
 */
/* XXX: This is *so* bogus.  There are several cases where
   this won't get us the canonical name of the host, but
   this is what we've trained people to expect.  We'll
   probably fix it at some point, but let's try to
   preserve the current behavior and only shake things up
   once when it comes time to fix this lossage.  */
err = getnameinfo(ai->ai_addr, ai->ai_addrlen,
  hnamebuf, sizeof(hnamebuf), 0, 0,
NI_NAMEREQD);
freeaddrinfo(ai);
if (err == 0) {
free(remote_host);
remote_host = strdup(hnamebuf);
if (!remote_host)
return ENOMEM;
}

The effect of this is that if the DNS server returns the "wrong" PTR record
first, the check fails. Additionally, there is a call to [getaddrinfo]
above which only examines the first address returned.

Is there a reason it's not secure to consider all forward and reverse
records, or does the "XXX: This is *so* bogus" comment refer to this
behavior? If so, wouldn't changing that behavior only increase the number
of times this check passes? (i.e. how would it break people's expectations?)

Thanks,
Yury

Kerberos mailing list   Kerberos@mit.edu
https://mailman.mit.edu/mailman/listinfo/kerberos