Skip to content

Commit 9a1d0af

Browse files
committed
Code review for commit 274bb2b.
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
1 parent 906bfca commit 9a1d0af

File tree

4 files changed

+23
-14
lines changed

4 files changed

+23
-14
lines changed

doc/src/sgml/libpq.sgml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,10 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
10091009
Maximum wait for connection, in seconds (write as a decimal integer
10101010
string). Zero or not specified means wait indefinitely. It is not
10111011
recommended to use a timeout of less than 2 seconds.
1012+
This timeout applies separately to each connection attempt.
1013+
For example, if you specify two hosts and both of them are unreachable,
1014+
and <literal>connect_timeout</> is 5, the total time spent waiting for a
1015+
connection might be up to 10 seconds.
10121016
</para>
10131017
</listitem>
10141018
</varlistentry>

src/interfaces/libpq/fe-auth.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,9 @@ pg_GSS_startup(PGconn *conn)
170170
min_stat;
171171
int maxlen;
172172
gss_buffer_desc temp_gbuf;
173+
char *host = PQhost(conn);
173174

174-
if (!(conn->pghost && conn->pghost[0] != '\0'))
175+
if (!(host && host[0] != '\0'))
175176
{
176177
printfPQExpBuffer(&conn->errorMessage,
177178
libpq_gettext("host name must be specified\n"));
@@ -198,7 +199,7 @@ pg_GSS_startup(PGconn *conn)
198199
return STATUS_ERROR;
199200
}
200201
snprintf(temp_gbuf.value, maxlen, "%s@%s",
201-
conn->krbsrvname, conn->pghost);
202+
conn->krbsrvname, host);
202203
temp_gbuf.length = strlen(temp_gbuf.value);
203204

204205
maj_stat = gss_import_name(&min_stat, &temp_gbuf,
@@ -371,6 +372,7 @@ pg_SSPI_startup(PGconn *conn, int use_negotiate)
371372
{
372373
SECURITY_STATUS r;
373374
TimeStamp expire;
375+
char *host = PQhost(conn);
374376

375377
conn->sspictx = NULL;
376378

@@ -406,19 +408,19 @@ pg_SSPI_startup(PGconn *conn, int use_negotiate)
406408
* but not more complex. We can skip the @REALM part, because Windows will
407409
* fill that in for us automatically.
408410
*/
409-
if (!(conn->pghost && conn->pghost[0] != '\0'))
411+
if (!(host && host[0] != '\0'))
410412
{
411413
printfPQExpBuffer(&conn->errorMessage,
412414
libpq_gettext("host name must be specified\n"));
413415
return STATUS_ERROR;
414416
}
415-
conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(conn->pghost) + 2);
417+
conn->sspitarget = malloc(strlen(conn->krbsrvname) + strlen(host) + 2);
416418
if (!conn->sspitarget)
417419
{
418420
printfPQExpBuffer(&conn->errorMessage, libpq_gettext("out of memory\n"));
419421
return STATUS_ERROR;
420422
}
421-
sprintf(conn->sspitarget, "%s/%s", conn->krbsrvname, conn->pghost);
423+
sprintf(conn->sspitarget, "%s/%s", conn->krbsrvname, host);
422424

423425
/*
424426
* Indicate that we're in SSPI authentication mode to make sure that

src/interfaces/libpq/fe-connect.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4931,7 +4931,7 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
49314931
{
49324932
int prefix_len;
49334933
char *p;
4934-
char *buf;
4934+
char *buf = NULL;
49354935
char *start;
49364936
char prevchar = '\0';
49374937
char *user = NULL;
@@ -4946,7 +4946,7 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
49464946
{
49474947
printfPQExpBuffer(errorMessage,
49484948
libpq_gettext("out of memory\n"));
4949-
return false;
4949+
goto cleanup;
49504950
}
49514951

49524952
/* need a modifiable copy of the input URI */
@@ -4955,7 +4955,7 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
49554955
{
49564956
printfPQExpBuffer(errorMessage,
49574957
libpq_gettext("out of memory\n"));
4958-
return false;
4958+
goto cleanup;
49594959
}
49604960
start = buf;
49614961

@@ -5156,7 +5156,8 @@ conninfo_uri_parse_options(PQconninfoOption *options, const char *uri,
51565156
cleanup:
51575157
termPQExpBuffer(&hostbuf);
51585158
termPQExpBuffer(&portbuf);
5159-
free(buf);
5159+
if (buf)
5160+
free(buf);
51605161
return retval;
51615162
}
51625163

src/interfaces/libpq/fe-secure-openssl.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,7 @@ verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
483483
char *name;
484484
const unsigned char *namedata;
485485
int result;
486+
char *host = PQhost(conn);
486487

487488
*store_name = NULL;
488489

@@ -528,12 +529,12 @@ verify_peer_name_matches_certificate_name(PGconn *conn, ASN1_STRING *name_entry,
528529
return -1;
529530
}
530531

531-
if (pg_strcasecmp(name, conn->pghost) == 0)
532+
if (pg_strcasecmp(name, host) == 0)
532533
{
533534
/* Exact name match */
534535
result = 1;
535536
}
536-
else if (wildcard_certificate_match(name, conn->pghost))
537+
else if (wildcard_certificate_match(name, host))
537538
{
538539
/* Matched wildcard name */
539540
result = 1;
@@ -563,6 +564,7 @@ verify_peer_name_matches_certificate(PGconn *conn)
563564
STACK_OF(GENERAL_NAME) *peer_san;
564565
int i;
565566
int rc;
567+
char *host = PQhost(conn);
566568

567569
/*
568570
* 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)
572574
return true;
573575

574576
/* Check that we have a hostname to compare with. */
575-
if (!(conn->pghost && conn->pghost[0] != '\0'))
577+
if (!(host && host[0] != '\0'))
576578
{
577579
printfPQExpBuffer(&conn->errorMessage,
578580
libpq_gettext("host name must be specified for a verified SSL connection\n"));
@@ -670,13 +672,13 @@ verify_peer_name_matches_certificate(PGconn *conn)
670672
libpq_ngettext("server certificate for \"%s\" (and %d other name) does not match host name \"%s\"\n",
671673
"server certificate for \"%s\" (and %d other names) does not match host name \"%s\"\n",
672674
names_examined - 1),
673-
first_name, names_examined - 1, conn->pghost);
675+
first_name, names_examined - 1, host);
674676
}
675677
else if (names_examined == 1)
676678
{
677679
printfPQExpBuffer(&conn->errorMessage,
678680
libpq_gettext("server certificate for \"%s\" does not match host name \"%s\"\n"),
679-
first_name, conn->pghost);
681+
first_name, host);
680682
}
681683
else
682684
{

0 commit comments

Comments
 (0)