Code review for commit 274bb2b385
.
Avoid memory leak in conninfo_uri_parse_options. Use the current host rather than the comma-separated list of host names when the host name is needed for GSS, SSPI, or SSL authentication. Document the way connect_timeout interacts with multiple host specifications. Takayuki Tsunakawa
This commit is contained in:
parent
906bfcad7b
commit
9a1d0af4ad
|
@ -1009,6 +1009,10 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
|
||||||
Maximum wait for connection, in seconds (write as a decimal integer
|
Maximum wait for connection, in seconds (write as a decimal integer
|
||||||
string). Zero or not specified means wait indefinitely. It is not
|
string). Zero or not specified means wait indefinitely. It is not
|
||||||
recommended to use a timeout of less than 2 seconds.
|
recommended to use a timeout of less than 2 seconds.
|
||||||
|
This timeout applies separately to each connection attempt.
|
||||||
|
For example, if you specify two hosts and both of them are unreachable,
|
||||||
|
and <literal>connect_timeout</> is 5, the total time spent waiting for a
|
||||||
|
connection might be up to 10 seconds.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
|
@ -170,8 +170,9 @@ pg_GSS_startup(PGconn *conn)
|
||||||
min_stat;
|
min_stat;
|
||||||
int maxlen;
|
int maxlen;
|
||||||
gss_buffer_desc temp_gbuf;
|
gss_buffer_desc temp_gbuf;
|
||||||
|
char *host = PQhost(conn);
|
||||||
|
|
||||||
if (!(conn->pghost && conn->pghost[0] != '\0'))
|
if (!(host && host[0] != '\0'))
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("host name must be specified\n"));
|
libpq_gettext("host name must be specified\n"));
|
||||||
|
@ -198,7 +199,7 @@ pg_GSS_startup(PGconn *conn)
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
snprintf(temp_gbuf.value, maxlen, "%s@%s",
|
snprintf(temp_gbuf.value, maxlen, "%s@%s",
|
||||||
conn->krbsrvname, conn->pghost);
|
conn->krbsrvname, host);
|
||||||
temp_gbuf.length = strlen(temp_gbuf.value);
|
temp_gbuf.length = strlen(temp_gbuf.value);
|
||||||
|
|
||||||
maj_stat = gss_import_name(&min_stat, &temp_gbuf,
|
maj_stat = gss_import_name(&min_stat, &temp_gbuf,
|
||||||
|
@ -371,6 +372,7 @@ pg_SSPI_startup(PGconn *conn, int use_negotiate)
|
||||||
{
|
{
|
||||||
SECURITY_STATUS r;
|
SECURITY_STATUS r;
|
||||||
TimeStamp expire;
|
TimeStamp expire;
|
||||||
|
char *host = PQhost(conn);
|
||||||
|
|
||||||
conn->sspictx = NULL;
|
conn->sspictx = NULL;
|
||||||
|
|
||||||
|
@ -406,19 +408,19 @@ pg_SSPI_startup(PGconn *conn, int use_negotiate)
|
||||||
* but not more complex. We can skip the @REALM part, because Windows will
|
* but not more complex. We can skip the @REALM part, because Windows will
|
||||||
* fill that in for us automatically.
|
* fill that in for us automatically.
|
||||||
*/
|
*/
|
||||||
if (!(conn->pghost && conn->pghost[0] != '\0'))
|
if (!(host && host[0] != '\0'))
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("host name must be specified\n"));
|
libpq_gettext("host name must be specified\n"));
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(conn->pghost) + 2);
|
conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(host) + 2);
|
||||||
if (!conn->sspitarget)
|
if (!conn->sspitarget)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
|
printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
sprintf(conn->sspitarget, "%s/%s", conn->krbsrvname, conn->pghost);
|
sprintf(conn->sspitarget, "%s/%s", conn->krbsrvname, host);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Indicate that we're in SSPI authentication mode to make sure that
|
* Indicate that we're in SSPI authentication mode to make sure that
|
||||||
|
|
|
@ -4931,7 +4931,7 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
|
||||||
{
|
{
|
||||||
int prefix_len;
|
int prefix_len;
|
||||||
char *p;
|
char *p;
|
||||||
char *buf;
|
char *buf = NULL;
|
||||||
char *start;
|
char *start;
|
||||||
char prevchar = '\0';
|
char prevchar = '\0';
|
||||||
char *user = NULL;
|
char *user = NULL;
|
||||||
|
@ -4946,7 +4946,7 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(errorMessage,
|
printfPQExpBuffer(errorMessage,
|
||||||
libpq_gettext("out of memory\n"));
|
libpq_gettext("out of memory\n"));
|
||||||
return false;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* need a modifiable copy of the input URI */
|
/* need a modifiable copy of the input URI */
|
||||||
|
@ -4955,7 +4955,7 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(errorMessage,
|
printfPQExpBuffer(errorMessage,
|
||||||
libpq_gettext("out of memory\n"));
|
libpq_gettext("out of memory\n"));
|
||||||
return false;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
start = buf;
|
start = buf;
|
||||||
|
|
||||||
|
@ -5156,6 +5156,7 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
|
||||||
cleanup:
|
cleanup:
|
||||||
termPQExpBuffer(&hostbuf);
|
termPQExpBuffer(&hostbuf);
|
||||||
termPQExpBuffer(&portbuf);
|
termPQExpBuffer(&portbuf);
|
||||||
|
if (buf)
|
||||||
free(buf);
|
free(buf);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
|
@ -483,6 +483,7 @@ verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
|
||||||
char *name;
|
char *name;
|
||||||
const unsigned char *namedata;
|
const unsigned char *namedata;
|
||||||
int result;
|
int result;
|
||||||
|
char *host = PQhost(conn);
|
||||||
|
|
||||||
*store_name = NULL;
|
*store_name = NULL;
|
||||||
|
|
||||||
|
@ -528,12 +529,12 @@ verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pg_strcasecmp(name, conn->pghost) == 0)
|
if (pg_strcasecmp(name, host) == 0)
|
||||||
{
|
{
|
||||||
/* Exact name match */
|
/* Exact name match */
|
||||||
result = 1;
|
result = 1;
|
||||||
}
|
}
|
||||||
else if (wildcard_certificate_match(name, conn->pghost))
|
else if (wildcard_certificate_match(name, host))
|
||||||
{
|
{
|
||||||
/* Matched wildcard name */
|
/* Matched wildcard name */
|
||||||
result = 1;
|
result = 1;
|
||||||
|
@ -563,6 +564,7 @@ verify_peer_name_matches_certificate(PGconn *conn)
|
||||||
STACK_OF(GENERAL_NAME) *peer_san;
|
STACK_OF(GENERAL_NAME) *peer_san;
|
||||||
int i;
|
int i;
|
||||||
int rc;
|
int rc;
|
||||||
|
char *host = PQhost(conn);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If told not to verify the peer name, don't do it. Return true
|
* If told not to verify the peer name, don't do it. Return true
|
||||||
|
@ -572,7 +574,7 @@ verify_peer_name_matches_certificate(PGconn *conn)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Check that we have a hostname to compare with. */
|
/* Check that we have a hostname to compare with. */
|
||||||
if (!(conn->pghost && conn->pghost[0] != '\0'))
|
if (!(host && host[0] != '\0'))
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("host name must be specified for a verified SSL connection\n"));
|
libpq_gettext("host name must be specified for a verified SSL connection\n"));
|
||||||
|
@ -670,13 +672,13 @@ verify_peer_name_matches_certificate(PGconn *conn)
|
||||||
libpq_ngettext("server certificate for \"%s\" (and %d other name) does not match host name \"%s\"\n",
|
libpq_ngettext("server certificate for \"%s\" (and %d other name) does not match host name \"%s\"\n",
|
||||||
"server certificate for \"%s\" (and %d other names) does not match host name \"%s\"\n",
|
"server certificate for \"%s\" (and %d other names) does not match host name \"%s\"\n",
|
||||||
names_examined - 1),
|
names_examined - 1),
|
||||||
first_name, names_examined - 1, conn->pghost);
|
first_name, names_examined - 1, host);
|
||||||
}
|
}
|
||||||
else if (names_examined == 1)
|
else if (names_examined == 1)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&conn->errorMessage,
|
printfPQExpBuffer(&conn->errorMessage,
|
||||||
libpq_gettext("server certificate for \"%s\" does not match host name \"%s\"\n"),
|
libpq_gettext("server certificate for \"%s\" does not match host name \"%s\"\n"),
|
||||||
first_name, conn->pghost);
|
first_name, host);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue