Thread: BUG #5559: Full SSL verification fails when hostaddr provided

BUG #5559: Full SSL verification fails when hostaddr provided

From
"Christopher Head"
Date:
The following bug has been logged online:

Bug reference:      5559
Logged by:          Christopher Head
Email address:      chris2k01@hotmail.com
PostgreSQL version: 8.4.4
Operating system:   Gentoo Linux i386, kernel 2.6.34
Description:        Full SSL verification fails when hostaddr provided
Details:

When establishing a connection to a PostgreSQL server using a connection
string, there are two parameters that can be provided to specify where to
connect to: "host" and "hostaddr". If both are provided, the documentation
states that "hostaddr" is used to actually establish the socket (thus
avoiding
a potentially-expensive DNS lookup), while "host" is used for doing some
Kerberos stuff.

It makes sense that in the case of an SSL connection with
"sslmode=verify-full" (check that the server's certificate is signed by a
trusted CA and has the
correct hostname), if both parameters are provided, that "host" also be used
for certificate checking. Unfortunately, as per line 536 of the file
fe-secure.c in the PostgreSQL sources, if hostaddr is specified, SSL full
verification just plain fails without trying at all. I suspect this line
should be "if (!conn->pghost)" instead of "if (conn->pghostaddr)".

There is no security vulnerability here, since "host" is a configuration
slot intended to hold some kind of semantic name for the host as understood
by the
user (which is precisely what you want to verify a certificate
against—that you are connecting to the semantically-correct server, not
simply the one that
happens to have the right IP address), while "hostaddr" is merely a
network-level implementation detail which should be essentially meaningless
to
the user.

Although it's easy enough to avoid the issue when using psql (just don't
include "hostaddr" at all), this unfortunately causes all connections to
fail
when using pgAdmin3, as that program apparently does its own DNS lookups and
always attaches a hostaddr (thus causing the confusing message "verified
SSL
connections are only supported when connecting to a host name" even if one
*does* in fact specify a host*name* in the appropriate place!)

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Tom Lane
Date:
"Christopher Head" <chris2k01@hotmail.com> writes:
> When establishing a connection to a PostgreSQL server using a connection
> string, there are two parameters that can be provided to specify where to
> connect to: "host" and "hostaddr". If both are provided, the documentation
> states that "hostaddr" is used to actually establish the socket (thus
> avoiding
> a potentially-expensive DNS lookup), while "host" is used for doing some
> Kerberos stuff.

> It makes sense that in the case of an SSL connection with
> "sslmode=verify-full" (check that the server's certificate is signed by a
> trusted CA and has the
> correct hostname), if both parameters are provided, that "host" also be used
> for certificate checking. Unfortunately, as per line 536 of the file
> fe-secure.c in the PostgreSQL sources, if hostaddr is specified, SSL full
> verification just plain fails without trying at all. I suspect this line
> should be "if (!conn->pghost)" instead of "if (conn->pghostaddr)".

That's really a definitional change, but it seems like a reasonable one
to me.  Magnus, what do you think?

            regards, tom lane

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Magnus Hagander
Date:
On Wed, Jul 14, 2010 at 00:09, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> "Christopher Head" <chris2k01@hotmail.com> writes:
>> When establishing a connection to a PostgreSQL server using a connection
>> string, there are two parameters that can be provided to specify where to
>> connect to: "host" and "hostaddr". If both are provided, the documentati=
on
>> states that "hostaddr" is used to actually establish the socket (thus
>> avoiding
>> a potentially-expensive DNS lookup), while "host" is used for doing some
>> Kerberos stuff.
>
>> It makes sense that in the case of an SSL connection with
>> "sslmode=3Dverify-full" (check that the server's certificate is signed b=
y a
>> trusted CA and has the
>> correct hostname), if both parameters are provided, that "host" also be =
used
>> for certificate checking. Unfortunately, as per line 536 of the file
>> fe-secure.c in the PostgreSQL sources, if hostaddr is specified, SSL full
>> verification just plain fails without trying at all. I suspect this line
>> should be "if (!conn->pghost)" instead of "if (conn->pghostaddr)".
>
> That's really a definitional change, but it seems like a reasonable one
> to me. =A0Magnus, what do you think?

Yeah, I think it is, but I haven't had the time to look into the code
yet to see if I agree with the fix as well. Hope to get there soon.


--=20
=A0Magnus Hagander
=A0Me: http://www.hagander.net/
=A0Work: http://www.redpill-linpro.com/

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Tom Lane
Date:
Magnus Hagander <magnus@hagander.net> writes:
> On Wed, Jul 14, 2010 at 00:09, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> "Christopher Head" <chris2k01@hotmail.com> writes:
>>> ... Unfortunately, as per line 536 of the file
>>> fe-secure.c in the PostgreSQL sources, if hostaddr is specified, SSL full
>>> verification just plain fails without trying at all. I suspect this line
>>> should be "if (!conn->pghost)" instead of "if (conn->pghostaddr)".
>>
>> That's really a definitional change, but it seems like a reasonable one
>> to me.  Magnus, what do you think?

> Yeah, I think it is, but I haven't had the time to look into the code
> yet to see if I agree with the fix as well. Hope to get there soon.

The test actually needs to check for pghost being nonempty, I think,
but otherwise it seems straightforward.  Will apply.

            regards, tom lane

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Tom Lane
Date:
... btw, the libpq documentation claims that

    If hostaddr is specified without host, the value for hostaddr
    gives the remote address. When Kerberos is used, a reverse name
    query occurs to obtain the host name for Kerberos.

but so far as I can see this is flat wrong.  pg_krb5_sendauth throws
an error if you didn't provide a host name, and so do the other places
in fe-auth.c that need the host name.  What we're about to do to SSL
verification will match that.  So I think the docs need a fix here.

            regards, tom lane

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Stephen Frost
Date:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> ... btw, the libpq documentation claims that
>=20
>     If hostaddr is specified without host, the value for hostaddr
>     gives the remote address. When Kerberos is used, a reverse name
>     query occurs to obtain the host name for Kerberos.
>=20
> but so far as I can see this is flat wrong.  pg_krb5_sendauth throws
> an error if you didn't provide a host name, and so do the other places
> in fe-auth.c that need the host name.  What we're about to do to SSL
> verification will match that.  So I think the docs need a fix here.

I think the confusion here is that the *Kerberos* libraries do the
reverse-DNS lookup to get the hostname to request as part of the
principal.  It's true that we don't, but that doesn't mean it's not
done.  Not sure where or if we need to discuss how Kerberos works in the
libpq documentation or what the context is for the above, but I'm pretty
sure that's where the original wording came from.

    Thanks,

        Stephen

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Tom Lane
Date:
Stephen Frost <sfrost@snowman.net> writes:
> * Tom Lane (tgl@sss.pgh.pa.us) wrote:
>> ... btw, the libpq documentation claims that
>>
>> If hostaddr is specified without host, the value for hostaddr
>> gives the remote address. When Kerberos is used, a reverse name
>> query occurs to obtain the host name for Kerberos.
>>
>> but so far as I can see this is flat wrong.  pg_krb5_sendauth throws
>> an error if you didn't provide a host name, and so do the other places
>> in fe-auth.c that need the host name.  What we're about to do to SSL
>> verification will match that.  So I think the docs need a fix here.

> I think the confusion here is that the *Kerberos* libraries do the
> reverse-DNS lookup to get the hostname to request as part of the
> principal.  It's true that we don't, but that doesn't mean it's not
> done.  Not sure where or if we need to discuss how Kerberos works in the
> libpq documentation or what the context is for the above, but I'm pretty
> sure that's where the original wording came from.

Yeah, but the code in fe-auth.c throws an error before the Kerberos
libraries get a chance to do any such thing.  I suppose that the
documentation text was accurate when written, but that was a long time
ago.

[ pokes in CVS a bit... ]  It looks like the insistence that pghost be
supplied was added by Magnus on 2005-03-25, probably because the Windows
version of Kerberos didn't handle the case correctly; and it's been that
way in every release later than 8.0.1.
http://archives.postgresql.org/pgsql-committers/2005-03/msg00355.php
http://archives.postgresql.org/pgsql-committers/2005-03/msg00356.php

That patch did not adjust the documentation wording, but evidently
should have.  (The claim about a reverse lookup has been in the docs
at least since 7.0.)  Given the lack of complaints in the past five
years, I'm not interested in trying to go back to the old behavior,
but we do need to fix the docs.

            regards, tom lane

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Stephen Frost
Date:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> Yeah, but the code in fe-auth.c throws an error before the Kerberos
> libraries get a chance to do any such thing.  I suppose that the
> documentation text was accurate when written, but that was a long time
> ago.

errrr, yeah, there are some issues with the wording that's there, that's
for sure.  For starters, Kerberos doesn't require nor care if you give
it a host name or an IP address; regardless, it will do a reverse-DNS
lookup on whatever host is connected to and then use *that* hostname to
request the principal from the KDC.  If that fails, it will use what you
gave it to try and find the principal (but that generally needs to be a
fully-qualified DNS name and needs to match exactly what's in the KDC).
I wouldn't bomb out if you've only been given a hostaddr, but I would
warn people that using Kerberos means it'll do a reverse DNS lookup, if
they care about minimizing those.

> [ pokes in CVS a bit... ]  It looks like the insistence that pghost be
> supplied was added by Magnus on 2005-03-25, probably because the Windows
> version of Kerberos didn't handle the case correctly; and it's been that
> way in every release later than 8.0.1.

It's possible that SSPI does something different and may expect you to
provide the FQDN when connecting, but I'd be suprised.  It could have
been a misconfiguration or a bug in older versions that prevented it
from doing the normal rDNS lookup.  In fact, I just had someone test,
and even SSPI, on a recent version of Windows, does the rDNS lookup to
request the principal.

> That patch did not adjust the documentation wording, but evidently
> should have.  (The claim about a reverse lookup has been in the docs
> at least since 7.0.)  Given the lack of complaints in the past five
> years, I'm not interested in trying to go back to the old behavior,
> but we do need to fix the docs.

I've never found a reason to use hostaddr, so I don't particularly care,
but it doesn't seem right to break Kerberos auth if you were only given
an IP address unless hostaddr's entire point is that it will prevent a
DNS lookup from happening, ever.  If that's the case, it should probably
be made more clear in the docs that you can't use hostaddr w/ Kerberos
but you *can* use an IP address in 'host' and have Kerberos work (or at
least, it should).

    Thanks,

        Stephen

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Tom Lane
Date:
Stephen Frost <sfrost@snowman.net> writes:
> I've never found a reason to use hostaddr, so I don't particularly care,
> but it doesn't seem right to break Kerberos auth if you were only given
> an IP address unless hostaddr's entire point is that it will prevent a
> DNS lookup from happening, ever.

Well, given your description we *can't* prevent Kerberos auth from doing
a synchronous reverse-DNS lookup.  So the question is why did that test
get put in, back in 2005?  I have no objection to removing it if that
doesn't lead to crashing, but ...

            regards, tom lane

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Stephen Frost
Date:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> Stephen Frost <sfrost@snowman.net> writes:
> > I've never found a reason to use hostaddr, so I don't particularly care,
> > but it doesn't seem right to break Kerberos auth if you were only given
> > an IP address unless hostaddr's entire point is that it will prevent a
> > DNS lookup from happening, ever.
>=20
> Well, given your description we *can't* prevent Kerberos auth from doing
> a synchronous reverse-DNS lookup.  So the question is why did that test
> get put in, back in 2005?  I have no objection to removing it if that
> doesn't lead to crashing, but ...

We could prevent it by doing exactly what we're doing now- bailing if we
end up in the KRB5 code when hostaddr is passed in but host isn't.  We
could justify that by saying that the user asked for no DNS lookups
(through the use of hostaddr) and that using Kerberos would then violate
that request, since it'd do an rDNS lookup.

I'd advocate *against* that, since it strikes me as bizarre, but having
the hostaddr option in the first place is a bit strange to me, so
perhaps I just don't run into the use-case it's built for enough to be
able to say it doesn't make sense.

In any case, here's what I believe the original issue was and what I
would suggest:

Per the documentation-

     krb5_sname_to_principal() and krb5_sock_to_principal() are for easy cr=
e-
     ation of ``service'' principals that can, for instance, be used to loo=
kup
     a key in a keytab.  For both functions the sname parameter will be used
     for the first component of the created principal.  If sname is NULL,
     ``host'' will be used instead.

     krb5_sname_to_principal() will use the passed hostname for the second
     component.  If type is KRB5_NT_SRV_HST this name will be looked up with
     gethostbyname().  If hostname is NULL, the local hostname will be used.

     krb5_sock_to_principal() will use the ``sockname'' of the passed socke=
t,
     which should be a bound AF_INET or AF_INET6 socket.  There must be a m=
ap-
     ping between the address and ``sockname''.  The function may try to
     resolve the name in DNS.

If we were passing in NULL before when hostaddr was set and host wasn't,
then we were probably ending up with Kerberos trying to use the local
hostname, which almost certainly wasn't right.  I expect that the
correct answer here would be to do whatever the actual connection logic
does- if it connects using host, then use host, if it connects using
hostaddr, then use hostaddr.

An alternative might be to just use krb5_sock_to_principal(), since we
have the socket already.=20=20

    Thanks,

        Stephen

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Tom Lane
Date:
Stephen Frost <sfrost@snowman.net> writes:
>      krb5_sname_to_principal() will use the passed hostname for the second
>      component.  If type is KRB5_NT_SRV_HST this name will be looked up with
>      gethostbyname().  If hostname is NULL, the local hostname will be used.

> If we were passing in NULL before when hostaddr was set and host wasn't,
> then we were probably ending up with Kerberos trying to use the local
> hostname, which almost certainly wasn't right.

Ah.  I agree that that would be unexpected behavior.

> I expect that the
> correct answer here would be to do whatever the actual connection logic
> does- if it connects using host, then use host, if it connects using
> hostaddr, then use hostaddr.

Uh, no, because hostaddr is (required to be) a numeric IP.  The odds of
it being useful in this context seem negligible.

At this point I'm satisfied that what the code is doing is right.  We
can't authenticate against Kerberos without knowing the server host
name, because we can't form a correct principal name.  Whether use of
hostaddr would avoid an rDNS lookup inside the library is not relevant.

            regards, tom lane

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Stephen Frost
Date:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> Stephen Frost <sfrost@snowman.net> writes:
> >      krb5_sname_to_principal() will use the passed hostname for the sec=
ond
> >      component.  If type is KRB5_NT_SRV_HST this name will be looked up=
 with
> >      gethostbyname().  If hostname is NULL, the local hostname will be =
used.
>=20
> > If we were passing in NULL before when hostaddr was set and host wasn't,
> > then we were probably ending up with Kerberos trying to use the local
> > hostname, which almost certainly wasn't right.
>=20
> Ah.  I agree that that would be unexpected behavior.
>=20
> > I expect that the
> > correct answer here would be to do whatever the actual connection logic
> > does- if it connects using host, then use host, if it connects using
> > hostaddr, then use hostaddr.
>=20
> Uh, no, because hostaddr is (required to be) a numeric IP.  The odds of
> it being useful in this context seem negligible.

Err, no, it'll work just fine- gethostbyname() will take the dotted-quad
numeric IP and return the hostname and Kerberos will use that to generate
the principal.  Maybe I'm missing something, but hostaddr being an IP is
just like if you passed in host with an IP, which I believe is what psql
does when called like so:

beren:/home/sfrost> psql -h 172.18.148.12 -d gis
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.

and that certainly works just fine.

beren:/home/sfrost> klist
[...]
07/14/10 17:37:50  07/14/10 17:58:25  postgres/beren.tsf.noblis.org@TSF.NOB=
LIS.ORG

> At this point I'm satisfied that what the code is doing is right.  We
> can't authenticate against Kerberos without knowing the server host
> name, because we can't form a correct principal name.  Whether use of
> hostaddr would avoid an rDNS lookup inside the library is not relevant.

I don't believe anything is going to avoid an rDNS lookup except bombing
out before invoking krb5_sname_to_principal().  Perhaps that's what's
intended, to avoid any DNS lookup, but I don't believe it's because it
wouldn't *work* to give krb5_sname_to_principal() an IP address=20
(provided rDNS is, in fact, functional in your environment).

    Thanks,

        Stephen

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Stephen Frost
Date:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> Uh, no, because hostaddr is (required to be) a numeric IP.  The odds of
> it being useful in this context seem negligible.

Perhaps I was being a bit overzealous in my last response, sorry about
that.  If the point here is that people who are using hostaddr are in an
environment where DNS is non-functional or actively broken, then yes,
just bombing out would probably be fine.  I think the issue I have here
is that if you've gone to the trouble to set things up on the
server-side to a point where it asks the client to do Kerberos (which, I
think, must be the case if we've gotten to this point in the code), and
for some reason the client has decided to use hostaddr instead of host
(perhaps some client-side code saw a dotted-quad and thought "oh, you
must want to use hostaddr instead of host"), it shouldn't break without
a real reason.

    Thanks,

        Stephen

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Tom Lane
Date:
Stephen Frost <sfrost@snowman.net> writes:
> * Tom Lane (tgl@sss.pgh.pa.us) wrote:
>> Uh, no, because hostaddr is (required to be) a numeric IP.  The odds of
>> it being useful in this context seem negligible.

> Err, no, it'll work just fine- gethostbyname() will take the dotted-quad
> numeric IP and return the hostname and Kerberos will use that to generate
> the principal.

Hm.  That might happen to work for Kerberos, but it won't work for
GSSAPI or SSPI --- in both those code paths we just push the host name
literally into a constructed principal string.  Not sure if we really
want Kerberos to work differently from the more modern alternatives.

> Maybe I'm missing something, but hostaddr being an IP is
> just like if you passed in host with an IP,

No, it's entirely different.  The point of hostaddr is to avoid doing a
forward DNS lookup inside PQconnect() when you would rather it be done
at some other time.  It's not to substitute for actually knowing the
host name.  I expect that typical applications making use of it would
essentially cache the hostaddr corresponding to host name and would be
able to pass both to libpq.  The option to supply only hostaddr is just
there for cases where you truly don't need to know the host name, which
clearly does *not* include Kerberos auth.

The case you're describing could perfectly well be handled by passing
host as a numeric IP string, without using hostaddr; so I don't think
we are losing any functionality.

> I don't believe anything is going to avoid an rDNS lookup except bombing
> out before invoking krb5_sname_to_principal().

So it would seem.  The bottom line is that if you don't want any DNS
activity to happen during PQconnect(), you can't use Kerberos auth.
What we allow or don't allow won't change that.

            regards, tom lane

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Tom Lane
Date:
Stephen Frost <sfrost@snowman.net> writes:
> Perhaps I was being a bit overzealous in my last response, sorry about
> that.  If the point here is that people who are using hostaddr are in an
> environment where DNS is non-functional or actively broken, then yes,
> just bombing out would probably be fine.

Well, if your environment includes broken DNS then you are clearly going
to get nowhere anyway with Kerberos auth, no?  The point of hostaddr is
*not* to try to avoid that problem.  Rather, it's to allow the
application to shift the time expense of the forward DNS lookup to some
other place than its PQconnect() call.  If you've got an app where the
cost of PQconnect() is that critical, you're likely going to want to
avoid Kerberos auth anyway, so I don't think it's all that important
exactly how the two features play together.

As the code stands in HEAD, I think everything is nicely
self-consistent: host is what we believe the server name is for
authentication purposes, and hostaddr is an optional pre-looked-up
address corresponding to that.  There is nothing in this suggesting
that we should be expected to try to generate an authentication name
from hostaddr alone.  In particular, the fact that Kerberos is capable
of trying to do that is at odds with the other three code paths where
the server name is needed for authentication.  I don't feel any need
to expose Kerberos' peculiarity here.

            regards, tom lane

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Stephen Frost
Date:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> Hm.  That might happen to work for Kerberos, but it won't work for
> GSSAPI or SSPI --- in both those code paths we just push the host name
> literally into a constructed principal string.  Not sure if we really
> want Kerberos to work differently from the more modern alternatives.

I'm not looking at the code right now, but I just don't see how this can
be the case, at least for GSSAPI.  I routinely use both krb5 and GSSAPI
auth types (depending on which server I'm using) with values passed to
-h that certainly aren't the FQDN of the host, and it works just fine.
I can't imagine we're doing some magic here ourselves and then passing
the right FQDN to the Kerberos/GSSAPI libraries.

Typical usage, all of them work:
vardamir/8.2:
  psql -h 172.18.148.10 -d gis
  psql -h vardamir -d gis
  psql -h vardamir.tsf.noblis.org -d gis

beren/8.3:
  psql -h beren -d gis
  psql -h 172.18.148.12

beren/8.4:
  psql --cluster 8.4/main -h beren -d gis
  psql --cluster 8.4/main -h 172.18.148.12
  psql --cluster 8.4/main -h beren.nicc.noblis.org -d gis

beren:/home/sfrost> hostname --fqdn
beren.tsf.noblis.org

I always get a postgres/beren.tsf.noblis.org@TSF.NOBLIS.ORG ticket, for
that server, since that's what the rDNS is, and that's what's in the KDC
(it hasn't got entries for any of the others).

In any case, let's please make sure not to break that. :)

    Thanks!

        Stephen

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Bruce Momjian
Date:
Do the docs need any more updating?

---------------------------------------------------------------------------

Tom Lane wrote:
> Stephen Frost <sfrost@snowman.net> writes:
> > Perhaps I was being a bit overzealous in my last response, sorry about
> > that.  If the point here is that people who are using hostaddr are in an
> > environment where DNS is non-functional or actively broken, then yes,
> > just bombing out would probably be fine.
>
> Well, if your environment includes broken DNS then you are clearly going
> to get nowhere anyway with Kerberos auth, no?  The point of hostaddr is
> *not* to try to avoid that problem.  Rather, it's to allow the
> application to shift the time expense of the forward DNS lookup to some
> other place than its PQconnect() call.  If you've got an app where the
> cost of PQconnect() is that critical, you're likely going to want to
> avoid Kerberos auth anyway, so I don't think it's all that important
> exactly how the two features play together.
>
> As the code stands in HEAD, I think everything is nicely
> self-consistent: host is what we believe the server name is for
> authentication purposes, and hostaddr is an optional pre-looked-up
> address corresponding to that.  There is nothing in this suggesting
> that we should be expected to try to generate an authentication name
> from hostaddr alone.  In particular, the fact that Kerberos is capable
> of trying to do that is at odds with the other three code paths where
> the server name is needed for authentication.  I don't feel any need
> to expose Kerberos' peculiarity here.
>
>             regards, tom lane
>
> --
> Sent via pgsql-bugs mailing list (pgsql-bugs@postgresql.org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-bugs

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + None of us is going to be here forever. +

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Tom Lane
Date:
Bruce Momjian <bruce@momjian.us> writes:
> Do the docs need any more updating?

No doubt, but it's a bit premature to consider that while we're still
arguing whether the code needs to change more.

            regards, tom lane

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Stephen Frost
Date:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> Stephen Frost <sfrost@snowman.net> writes:
> > Perhaps I was being a bit overzealous in my last response, sorry about
> > that.  If the point here is that people who are using hostaddr are in an
> > environment where DNS is non-functional or actively broken, then yes,
> > just bombing out would probably be fine.
>=20
> Well, if your environment includes broken DNS then you are clearly going
> to get nowhere anyway with Kerberos auth, no?

Yes, that's correct as far as I can tell.  There may be a way to get
Kerberos to work just on IP addresses, but I didn't have any success
when trying to force that in my environment.

> The point of hostaddr is
> *not* to try to avoid that problem.  Rather, it's to allow the
> application to shift the time expense of the forward DNS lookup to some
> other place than its PQconnect() call.  If you've got an app where the
> cost of PQconnect() is that critical, you're likely going to want to
> avoid Kerberos auth anyway, so I don't think it's all that important
> exactly how the two features play together.

I can agree with that in general, I feel we just need to be very clear
that using hostaddr is *only* for that reason, that an IP address *can*
be passed to host, and that using hostaddr should be done judiciously
since it will break Kerberos, GSSAPI, etc.

> As the code stands in HEAD, I think everything is nicely
> self-consistent: host is what we believe the server name is for
> authentication purposes, and hostaddr is an optional pre-looked-up
> address corresponding to that.  There is nothing in this suggesting
> that we should be expected to try to generate an authentication name
> from hostaddr alone.  In particular, the fact that Kerberos is capable
> of trying to do that is at odds with the other three code paths where
> the server name is needed for authentication.  I don't feel any need
> to expose Kerberos' peculiarity here.

Kerberos and GSSAPI act exactly the same in this regard, at a functional
level (even if how it gets there is slightly different), from everything
I've seen with them (and they're supposed to be compatible to boot, so
I'd be suprised if it wasn't the case).  One distinction that I'd make
is that while we may feel host is the server name for authentication,
Kerberos, GSSAPI, SSPI, are just going to use that host to get the IP to
do an rDNS lookup to get what *they* feel the hostname for
authentication is, and that's what will be requested from the KDC.

Reviewing what's currently on developer.postgresql.org, here's what I
think the docs would read and what the associated code behavior should
be (which I think it's pretty close to already, but perhaps not
entirely..):

hostaddr

 This option is not recommended except in cases where PQconnectdb() must
 avoid a host name look-up.  host can be used with regular hostnames, IP
 addresses, etc, directly.

 Numeric IP address of host to connect to. This should be in the
 standard IPv4 address format, e.g., 172.28.40.9. If your machine
 supports IPv6, you can also use those addresses. TCP/IP communication
 is always used when a nonempty string is specified for this parameter.

 Using hostaddr instead of host allows the application to avoid a host
 name look-up, which might be important in applications with time
 constraints. However, Kerberos, GSSAPI, and SSPI depend on being able
 to do a host name look-up, and so are disabled when hostaddr is used
 without host to prevent a DNS lookup from happening.  Full SSL
 certificate verification requires the client provide the host name
 (XXX: I don't believe this needs to be the case. If you have a
 certificate whose CN is an IP address, which I've seen quite a few
 times in the past, I don't see any reason to break SSL-based auth
 when hostaddr is used; of course, if you care about speed, SSL
 negotiation a'int exactly cheap...  I don't believe the OpenSSL libs
 do any DNS lookups; the user must pass in exactly what is in the CN).

 The following rules are used: If host is specified without hostaddr, a
 host name lookup occurs. If hostaddr is specified without host, the
 value for hostaddr gives the server address. The connection attempt
 will fail in any of the cases where a host name is required. If both
 host and hostaddr are specified, the value for hostaddr gives the
 server address. The value for host is ignored unless needed for
 authentication or verification purposes, in which case it will be used
 as the host name, and DNS look-ups may occur.
 (XXX: They will for Kerberos/GSSAPI/SSPI, I don't think they will for
 SSL unless libpq does a lookup, but that shouldn't be the case here,
 since hostaddr is populated.)

 Also, note that host rather than hostaddr is used to identify the
 connection in ~/.pgpass (see Section 31.14).=20

     Thanks,

        Stephen

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Tom Lane
Date:
Stephen Frost <sfrost@snowman.net> writes:
> Reviewing what's currently on developer.postgresql.org, here's what I
> think the docs would read and what the associated code behavior should
> be (which I think it's pretty close to already, but perhaps not
> entirely..):

I think this is overcomplicated and probably wrong in detail.

I suggest that we document hostaddr as being an auxiliary field that is
not intended to be the primary source of the host name, but merely saves
libpq from having to do a forward DNS lookup.  In some cases it will
work to supply hostaddr without host, but in others it won't.  We should
also state that supplying it does not guarantee no DNS lookups occur,
because these external auth libraries will do one anyway.

            regards, tom lane

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Stephen Frost
Date:
* Tom Lane (tgl@sss.pgh.pa.us) wrote:
> I suggest that we document hostaddr as being an auxiliary field that is
> not intended to be the primary source of the host name, but merely saves
> libpq from having to do a forward DNS lookup.  In some cases it will
> work to supply hostaddr without host, but in others it won't.  We should
> also state that supplying it does not guarantee no DNS lookups occur,
> because these external auth libraries will do one anyway.

That sounds like it implies we'd also remove the check which prevents
Kerberos from being used and fix it to use hostaddr if host is null.
That's fine with me.  I'd rather have it not broken anyway.

    Thanks,

        Stephen

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Tom Lane
Date:
Stephen Frost <sfrost@snowman.net> writes:
> * Tom Lane (tgl@sss.pgh.pa.us) wrote:
>> I suggest that we document hostaddr as being an auxiliary field that is
>> not intended to be the primary source of the host name, but merely saves
>> libpq from having to do a forward DNS lookup.  In some cases it will
>> work to supply hostaddr without host, but in others it won't.  We should
>> also state that supplying it does not guarantee no DNS lookups occur,
>> because these external auth libraries will do one anyway.

> That sounds like it implies we'd also remove the check which prevents
> Kerberos from being used and fix it to use hostaddr if host is null.

Uh, no, it implies no such thing.  I don't think that's a "fix", it's
merely fuzzing what the values are for.

Magnus, I'm curious to hear your thoughts on this...

            regards, tom lane

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Christopher Head
Date:
On Wed, 14 Jul 2010 18:35:55 -0400
Tom Lane <tgl@sss.pgh.pa.us> wrote:

> Bruce Momjian <bruce@momjian.us> writes:
> > Do the docs need any more updating?
>
> No doubt, but it's a bit premature to consider that while we're still
> arguing whether the code needs to change more.
>
>             regards, tom lane
>

Sorry to bother everyone, but AFAICT this discussion kind of
disappeared. Did I perhaps get dropped from CC? I'm interested to know
what the final resolution of this is.

My own thought would be:
"host" means the thing you intended to connect to: a unique identifier
for the server, probably (usually) the hostname, and also the thing
that goes in a certificate. Should (probably) never be omitted.

"hostaddr" means the thing you actually send your TCP SYN packet to:
maybe an IP address if you want to save a DNS lookup, maybe even
"localhost" if you want to use an SSH tunnel (or even some other
hostname if you have an even stranger tunnel set up), but purely a
"network-layer" thing about *how to get to* the server, and not a
"user-trust-layer" thing about *who the server is*. If omitted,
defaults to being equal to "host".

I don't know if that's what was intended, but that's what I thought
they would mean.

Chris

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Robert Haas
Date:
On Sun, Dec 19, 2010 at 5:13 PM, Christopher Head <chris2k01@hotmail.com> w=
rote:
> On Wed, 14 Jul 2010 18:35:55 -0400
> Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
>> Bruce Momjian <bruce@momjian.us> writes:
>> > Do the docs need any more updating?
>>
>> No doubt, but it's a bit premature to consider that while we're still
>> arguing whether the code needs to change more.
>>
>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 regards, tom lane
>>
>
> Sorry to bother everyone, but AFAICT this discussion kind of
> disappeared. Did I perhaps get dropped from CC? I'm interested to know
> what the final resolution of this is.

I don't think there ever was any more discussion.

> My own thought would be:
> "host" means the thing you intended to connect to: a unique identifier
> for the server, probably (usually) the hostname, and also the thing
> that goes in a certificate. Should (probably) never be omitted.
>
> "hostaddr" means the thing you actually send your TCP SYN packet to:
> maybe an IP address if you want to save a DNS lookup, maybe even
> "localhost" if you want to use an SSH tunnel (or even some other
> hostname if you have an even stranger tunnel set up), but purely a
> "network-layer" thing about *how to get to* the server, and not a
> "user-trust-layer" thing about *who the server is*. If omitted,
> defaults to being equal to "host".
>
> I don't know if that's what was intended, but that's what I thought
> they would mean.

Me, too.  I reread the original discussion of this topic and I'm still
a little fuzzy on it, but the issue that was under discussion seems to
be what information we pass to external auth libraries like GSSAPI or
Kerberos, given that we have host and hostaddr to choose from.

--=20
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Christopher Head
Date:
On Tue, 4 Jan 2011 19:42:38 -0500
Robert Haas <robertmhaas@gmail.com> wrote:

> Me, too.  I reread the original discussion of this topic and I'm still
> a little fuzzy on it, but the issue that was under discussion seems to
> be what information we pass to external auth libraries like GSSAPI or
> Kerberos, given that we have host and hostaddr to choose from.

I'd have thought the logical thing there would be "host", in keeping
with the idea that "host is the thing you want to connect to, hostaddr
is just how you get there". If you're tunnelling through SSH, you want
to ask Kerberos for a ticket to the final end machine, not "localhost",
after all.

Chris

Re: BUG #5559: Full SSL verification fails when hostaddr provided

From
Bruce Momjian
Date:
Christopher Head wrote:
> On Wed, 14 Jul 2010 18:35:55 -0400
> Tom Lane <tgl@sss.pgh.pa.us> wrote:
>
> > Bruce Momjian <bruce@momjian.us> writes:
> > > Do the docs need any more updating?
> >
> > No doubt, but it's a bit premature to consider that while we're still
> > arguing whether the code needs to change more.
> >
> >             regards, tom lane
> >
>
> Sorry to bother everyone, but AFAICT this discussion kind of
> disappeared. Did I perhaps get dropped from CC? I'm interested to know
> what the final resolution of this is.
>
> My own thought would be:
> "host" means the thing you intended to connect to: a unique identifier
> for the server, probably (usually) the hostname, and also the thing
> that goes in a certificate. Should (probably) never be omitted.
>
> "hostaddr" means the thing you actually send your TCP SYN packet to:
> maybe an IP address if you want to save a DNS lookup, maybe even
> "localhost" if you want to use an SSH tunnel (or even some other
> hostname if you have an even stranger tunnel set up), but purely a
> "network-layer" thing about *how to get to* the server, and not a
> "user-trust-layer" thing about *who the server is*. If omitted,
> defaults to being equal to "host".
>
> I don't know if that's what was intended, but that's what I thought
> they would mean.

I have adjusted the libpq docs to be clearer about 'hostaddr' by using
an itemized list and rewording;   attached and applied.

I am not sure what else needs to be done, and I don't think anyone else
knows either, so unless I hear otherwise, I will consider this item
closed.  Perhaps the clearer docs will highlight a new open item.

--
  Bruce Momjian  <bruce@momjian.us>        http://momjian.us
  EnterpriseDB                             http://enterprisedb.com

  + It's impossible for everything to be true. +
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index e78d708..3824588 100644
*** a/doc/src/sgml/libpq.sgml
--- b/doc/src/sgml/libpq.sgml
*************** PGconn *PQconnectdbParams(const char **k
*** 164,185 ****
             Using <literal>hostaddr</> instead of <literal>host</> allows the
             application to avoid a host name look-up, which might be important
             in applications with time constraints. However, a host name is
!            required for Kerberos, GSSAPI, or SSPI authentication, as well as
!            for full SSL certificate verification. The following rules are
!            used:
!            If <literal>host</> is specified without <literal>hostaddr</>,
!            a host name lookup occurs.
!            If <literal>hostaddr</> is specified without <literal>host</>,
!            the value for <literal>hostaddr</> gives the server network address.
!            The connection attempt will fail in any of the cases where a
!            host name is required.
!            If both <literal>host</> and <literal>hostaddr</> are specified,
!            the value for <literal>hostaddr</> gives the server network address.
!            The value for <literal>host</> is ignored unless needed for
!            authentication or verification purposes, in which case it will be
!            used as the host name.  Note that authentication is likely to fail
!            if <literal>host</> is not the name of the machine at
!            <literal>hostaddr</>.
             Also, note that <literal>host</> rather than <literal>hostaddr</>
             is used to identify the connection in <filename>~/.pgpass</> (see
             <xref linkend="libpq-pgpass">).
--- 164,199 ----
             Using <literal>hostaddr</> instead of <literal>host</> allows the
             application to avoid a host name look-up, which might be important
             in applications with time constraints. However, a host name is
!            required for Kerberos, GSSAPI, or SSPI authentication
!            methods, as well as for <literal>verify-full</> SSL
!            certificate verification.  The following rules are used:
!            <itemizedlist>
!             <listitem>
!              <para>
!               If <literal>host</> is specified without <literal>hostaddr</>,
!               a host name lookup occurs.
!              </para>
!             </listitem>
!             <listitem>
!              <para>
!               If <literal>hostaddr</> is specified without <literal>host</>,
!               the value for <literal>hostaddr</> gives the server network address.
!               The connection attempt will fail if the authentication
!               method requires a host name.
!              </para>
!             </listitem>
!             <listitem>
!              <para>
!               If both <literal>host</> and <literal>hostaddr</> are specified,
!               the value for <literal>hostaddr</> gives the server network address.
!               The value for <literal>host</> is ignored unless the
!               authentication method requires it, in which case it will be
!               used as the host name.
!              </para>
!             </listitem>
!            </itemizedlist>
!            Note that authentication is likely to fail if <literal>host</>
!            is not the name of the server at network address <literal>hostaddr</>.
             Also, note that <literal>host</> rather than <literal>hostaddr</>
             is used to identify the connection in <filename>~/.pgpass</> (see
             <xref linkend="libpq-pgpass">).