summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2010-07-14 17:09:45 +0000
committerTom Lane2010-07-14 17:09:45 +0000
commitd494e685c580ae149639f4a380157996a7b61f74 (patch)
tree0835f6f02dddcaa1a88235834b939fc181aa9f58
parent1cc29fe7c60ba643c114979dbe588d3a38005449 (diff)
Allow full SSL certificate verification (wherein libpq checks its host name
parameter against server cert's CN field) to succeed in the case where both host and hostaddr are specified. As with the existing precedents for Kerberos, GSSAPI, SSPI, it is the calling application's responsibility that host and hostaddr match up --- we just use the host name as given. Per bug #5559 from Christopher Head. In passing, make the error handling and messages for the no-host-name-given failure more consistent among these four cases, and correct a lie in the documentation: we don't attempt to reverse-lookup host from hostaddr if host is missing. Back-patch to 8.4 where SSL cert verification was introduced.
-rw-r--r--doc/src/sgml/libpq.sgml38
-rw-r--r--src/interfaces/libpq/fe-auth.c16
-rw-r--r--src/interfaces/libpq/fe-secure.c8
-rw-r--r--src/interfaces/libpq/libpq-int.h9
4 files changed, 38 insertions, 33 deletions
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 9e047b110d..595cb0bb55 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1,4 +1,4 @@
-<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.313 2010/07/08 10:20:14 mha Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.314 2010/07/14 17:09:45 tgl Exp $ -->
<chapter id="libpq">
<title><application>libpq</application> - C Library</title>
@@ -162,22 +162,26 @@
<para>
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, Kerberos and GSSAPI authentication
- requires the host name. The following therefore applies: 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 remote
- address. When Kerberos is used, a reverse name query occurs to obtain
- the host name for Kerberos. If both
- <literal>host</> and <literal>hostaddr</> are specified, the value for
- <literal>hostaddr</> gives the remote address; the value for
- <literal>host</> is ignored, unless Kerberos is used, in which case that
- value is used for Kerberos authentication. (Note that authentication is
- likely to fail if <application>libpq</application> is passed a host name
- that is not the name of the machine at <literal>hostaddr</>.) Also,
- <literal>host</> rather than <literal>hostaddr</> is used to identify
- the connection in <filename>~/.pgpass</> (see
+ 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 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 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">).
</para>
diff --git a/src/interfaces/libpq/fe-auth.c b/src/interfaces/libpq/fe-auth.c
index 65f3e2625c..a46259eee2 100644
--- a/src/interfaces/libpq/fe-auth.c
+++ b/src/interfaces/libpq/fe-auth.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-auth.c,v 1.144 2010/03/08 10:01:12 mha Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-auth.c,v 1.145 2010/07/14 17:09:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -206,10 +206,10 @@ pg_krb5_sendauth(PGconn *conn)
info.pg_krb5_initialised = 0;
- if (!conn->pghost)
+ if (!(conn->pghost && conn->pghost[0] != '\0'))
{
printfPQExpBuffer(&conn->errorMessage,
- "pg_krb5_sendauth: hostname must be specified for Kerberos authentication\n");
+ libpq_gettext("host name must be specified\n"));
return STATUS_ERROR;
}
@@ -426,9 +426,10 @@ pg_GSS_startup(PGconn *conn)
int maxlen;
gss_buffer_desc temp_gbuf;
- if (!conn->pghost)
+ if (!(conn->pghost && conn->pghost[0] != '\0'))
{
- printfPQExpBuffer(&conn->errorMessage, libpq_gettext("host name must be specified\n"));
+ printfPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("host name must be specified\n"));
return STATUS_ERROR;
}
@@ -652,9 +653,10 @@ pg_SSPI_startup(PGconn *conn, int use_negotiate)
* but not more complex. We can skip the @REALM part, because Windows will
* fill that in for us automatically.
*/
- if (conn->pghost == NULL)
+ if (!(conn->pghost && conn->pghost[0] != '\0'))
{
- printfPQExpBuffer(&conn->errorMessage, libpq_gettext("host name must be specified\n"));
+ printfPQExpBuffer(&conn->errorMessage,
+ libpq_gettext("host name must be specified\n"));
return STATUS_ERROR;
}
conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(conn->pghost) + 2);
diff --git a/src/interfaces/libpq/fe-secure.c b/src/interfaces/libpq/fe-secure.c
index 9558010a81..9aab6e13d2 100644
--- a/src/interfaces/libpq/fe-secure.c
+++ b/src/interfaces/libpq/fe-secure.c
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.135 2010/07/06 19:19:01 momjian Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.136 2010/07/14 17:09:45 tgl Exp $
*
* NOTES
*
@@ -589,16 +589,16 @@ static bool
verify_peer_name_matches_certificate(PGconn *conn)
{
/*
- * If told not to verify the peer name, don't do it. Return 0 indicating
+ * If told not to verify the peer name, don't do it. Return true indicating
* that the verification was successful.
*/
if (strcmp(conn->sslmode, "verify-full") != 0)
return true;
- if (conn->pghostaddr)
+ if (!(conn->pghost && conn->pghost[0] != '\0'))
{
printfPQExpBuffer(&conn->errorMessage,
- libpq_gettext("verified SSL connections are only supported when connecting to a host name\n"));
+ libpq_gettext("host name must be specified for a verified SSL connection\n"));
return false;
}
else
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index ca3497f8f7..571c3fbbf4 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.152 2010/07/06 19:19:01 momjian Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-int.h,v 1.153 2010/07/14 17:09:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -282,10 +282,9 @@ struct pg_conn
{
/* Saved values of connection options */
char *pghost; /* the machine on which the server is running */
- char *pghostaddr; /* the IPv4 address of the machine on which
- * the server is running, in IPv4
- * numbers-and-dots notation. Takes precedence
- * over above. */
+ char *pghostaddr; /* the numeric IP address of the machine on
+ * which the server is running. Takes
+ * precedence over above. */
char *pgport; /* the server's communication port */
char *pgunixsocket; /* the Unix-domain socket that the server is
* listening on; if NULL, uses a default