Skip to content

Commit 0a5f229

Browse files
committed
Fix libpq_encryption tests when compiled without SSL support
It correctly skipped tests involving SSL in the server when SSL support was not compiled in, but even when SSL is not enabled in the server and the connection is established without SSL, libpq behaves differently in many of the test scenarios when libpq is compiled without SSL support. For example, with sslmode=prefer, if libpq is compiled with SSL support it will attempt to use SSL, but without SSL support it will try authenticating in plaintext mode directly. The expected test output didn't take that into account. Discussion: https://www.postgresql.org/message-id/CA%2BhUKG%2BHRTtB%2Bx%2BKKKj_cfX6sNhbeGuqmGxjGMwdVPG7YGFP8w@mail.gmail.com
1 parent 929c057 commit 0a5f229

File tree

1 file changed

+71
-33
lines changed

1 file changed

+71
-33
lines changed

src/test/libpq_encryption/t/001_negotiate_encryption.pl

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
# We test all combinations of:
1010
#
1111
# - all the libpq client options that affect the protocol negotiations
12-
# (gssencmode, sslmode)
12+
# (gssencmode, sslmode, sslnegotiation)
1313
# - server accepting or rejecting the authentication due to
1414
# pg_hba.conf entries
1515
# - SSL and GSS enabled/disabled in the server
@@ -216,7 +216,9 @@ BEGIN
216216
###
217217
### Run tests with GSS and SSL disabled in the server
218218
###
219-
my $test_table = q{
219+
my $test_table;
220+
if ($ssl_supported) {
221+
$test_table = q{
220222
# USER GSSENCMODE SSLMODE SSLNEGOTIATION EVENTS -> OUTCOME
221223
testuser disable disable * connect, authok -> plain
222224
. . allow * connect, authok -> plain
@@ -227,24 +229,45 @@ BEGIN
227229
. . . direct connect, directsslreject, reconnect, sslreject -> fail
228230
. . . requiredirect connect, directsslreject -> fail
229231
. prefer disable * connect, authok -> plain
230-
. . allow postgres connect, authok -> plain
231-
. . . direct connect, authok -> plain
232-
. . . requiredirect connect, authok -> plain
232+
. . allow * connect, authok -> plain
233233
. . prefer postgres connect, sslreject, authok -> plain
234234
. . . direct connect, directsslreject, reconnect, sslreject, authok -> plain
235235
. . . requiredirect connect, directsslreject, reconnect, authok -> plain
236236
. . require postgres connect, sslreject -> fail
237237
. . . direct connect, directsslreject, reconnect, sslreject -> fail
238238
. . . requiredirect connect, directsslreject -> fail
239+
};
240+
} else {
241+
# Compiled without SSL support
242+
$test_table = q{
243+
# USER GSSENCMODE SSLMODE SSLNEGOTIATION EVENTS -> OUTCOME
244+
testuser disable disable postgres connect, authok -> plain
245+
. . allow postgres connect, authok -> plain
246+
. . prefer postgres connect, authok -> plain
247+
. prefer disable postgres connect, authok -> plain
248+
. . allow postgres connect, authok -> plain
249+
. . prefer postgres connect, authok -> plain
250+
251+
# Without SSL support, sslmode=require and sslnegotiation=direct/requiredirect
252+
# are not accepted at all.
253+
. * require * - -> fail
254+
. * * direct - -> fail
255+
. * * requiredirect - -> fail
256+
};
257+
}
239258

240259
# All attempts with gssencmode=require fail without connecting because
241-
# no credential cache has been configured in the client
242-
. require * * - -> fail
260+
# no credential cache has been configured in the client. (Or if GSS
261+
# support is not compiled in, they will fail because of that.)
262+
$test_table .= q{
263+
testuser require * * - -> fail
243264
};
265+
244266
note("Running tests with SSL and GSS disabled in the server");
245267
test_matrix($node, $server_config,
246-
['testuser'],
247-
\@all_sslmodes, \@all_gssencmodes, parse_table($test_table));
268+
['testuser'], \@all_gssencmodes, \@all_sslmodes, \@all_sslnegotiations,
269+
parse_table($test_table));
270+
248271

249272
###
250273
### Run tests with GSS disabled and SSL enabled in the server
@@ -293,7 +316,8 @@ BEGIN
293316
note("Running tests with SSL enabled in server");
294317
test_matrix($node, $server_config,
295318
['testuser', 'ssluser', 'nossluser'],
296-
\@all_sslmodes, ['disable'], parse_table($test_table));
319+
['disable'], \@all_sslmodes, \@all_sslnegotiations,
320+
parse_table($test_table));
297321

298322
# Disable SSL again
299323
$node->adjust_conf('postgresql.conf', 'ssl', 'off');
@@ -307,6 +331,11 @@ BEGIN
307331
SKIP:
308332
{
309333
skip "GSSAPI/Kerberos not supported by this build" if $gss_supported == 0;
334+
335+
$krb->create_principal('gssuser', $gssuser_password);
336+
$krb->create_ticket('gssuser', $gssuser_password);
337+
$server_config->{server_gss} = 1;
338+
310339
$test_table = q{
311340
# USER GSSENCMODE SSLMODE SSLNEGOTIATION EVENTS -> OUTCOME
312341
testuser disable disable * connect, authok -> plain
@@ -357,20 +386,26 @@ BEGIN
357386
. . allow * connect, gssaccept, authfail -> fail
358387
. . prefer * connect, gssaccept, authfail -> fail
359388
. . require * connect, gssaccept, authfail -> fail # If both GSSAPI and sslmode are required, and GSS is not available -> fail
360-
};
361-
362-
# Sanity check that the connection fails when no kerberos ticket
363-
# is present in the client
364-
connect_test($node, 'user=testuser gssencmode=require sslmode=disable', '- -> fail');
365-
366-
$krb->create_principal('gssuser', $gssuser_password);
367-
$krb->create_ticket('gssuser', $gssuser_password);
368-
$server_config->{server_gss} = 1;
389+
};
390+
391+
# The expected events and outcomes above assume that SSL support
392+
# is enabled. When libpq is compiled without SSL support, all
393+
# attempts to connect with sslmode=require or
394+
# sslnegotition=direct/requiredirectwould fail immediately without
395+
# even connecting to the server. Skip those, because we tested
396+
# them earlier already.
397+
my ($sslmodes, $sslnegotiations);
398+
if ($ssl_supported != 0) {
399+
($sslmodes, $sslnegotiations) = (\@all_sslmodes, \@all_sslnegotiations);
400+
} else {
401+
($sslmodes, $sslnegotiations) = (['disable'], ['postgres']);
402+
}
369403

370404
note("Running tests with GSS enabled in server");
371405
test_matrix($node, $server_config,
372406
['testuser', 'gssuser', 'nogssuser'],
373-
\@all_sslmodes, \@all_gssencmodes, parse_table($test_table));
407+
\@all_gssencmodes, $sslmodes, $sslnegotiations,
408+
parse_table($test_table));
374409
}
375410

376411
###
@@ -380,6 +415,14 @@ BEGIN
380415
{
381416
skip "GSSAPI/Kerberos or SSL not supported by this build" unless ($ssl_supported && $gss_supported);
382417

418+
# Sanity check that GSSAPI is still enabled from previous test.
419+
connect_test($node, 'user=testuser gssencmode=prefer sslmode=prefer', 'connect, gssaccept, authok -> gss');
420+
421+
# Enable SSL
422+
$node->adjust_conf('postgresql.conf', 'ssl', 'on');
423+
$node->reload;
424+
$server_config->{server_ssl} = 1;
425+
383426
$test_table = q{
384427
# USER GSSENCMODE SSLMODE SSLNEGOTIATION EVENTS -> OUTCOME
385428
testuser disable disable * connect, authok -> plain
@@ -476,20 +519,13 @@ BEGIN
476519
. . . requiredirect connect, directsslaccept, authfail -> fail
477520
. prefer * * connect, gssaccept, authok -> gss
478521
. require * * connect, gssaccept, authok -> gss
479-
};
480-
481-
# Sanity check that GSSAPI is still enabled from previous test.
482-
connect_test($node, 'user=testuser gssencmode=prefer sslmode=prefer', 'connect, gssaccept, authok -> gss');
483-
484-
# Enable SSL
485-
$node->adjust_conf('postgresql.conf', 'ssl', 'on');
486-
$node->reload;
487-
$server_config->{server_ssl} = 1;
522+
};
488523

489524
note("Running tests with both GSS and SSL enabled in server");
490525
test_matrix($node, $server_config,
491526
['testuser', 'gssuser', 'ssluser', 'nogssuser', 'nossluser'],
492-
\@all_sslmodes, \@all_gssencmodes, parse_table($test_table));
527+
\@all_gssencmodes, \@all_sslmodes, \@all_sslnegotiations,
528+
parse_table($test_table));
493529
}
494530

495531
###
@@ -499,7 +535,9 @@ BEGIN
499535
{
500536
skip "Unix domain sockets not supported" unless ($unixdir ne "");
501537

502-
connect_test($node, "user=localuser gssencmode=prefer sslmode=require host=$unixdir", 'connect, authok -> plain');
538+
# libpq doesn't attempt SSL or GSSAPI over Unix domain
539+
# sockets. The server would reject them too.
540+
connect_test($node, "user=localuser gssencmode=prefer sslmode=prefer host=$unixdir", 'connect, authok -> plain');
503541
connect_test($node, "user=localuser gssencmode=require sslmode=prefer host=$unixdir", '- -> fail');
504542
}
505543

@@ -514,7 +552,7 @@ sub test_matrix
514552
local $Test::Builder::Level = $Test::Builder::Level + 1;
515553

516554
my ($pg_node, $node_conf,
517-
$test_users, $sslmodes, $gssencmodes, %expected) = @_;
555+
$test_users, $gssencmodes, $sslmodes, $sslnegotiations, %expected) = @_;
518556

519557
foreach my $test_user (@{$test_users})
520558
{
@@ -524,7 +562,7 @@ sub test_matrix
524562
{
525563
# sslnegotiation only makes a difference if SSL is enabled. This saves a few combinations.
526564
my ($key, $expected_events);
527-
foreach my $negotiation (@all_sslnegotiations)
565+
foreach my $negotiation (@{$sslnegotiations})
528566
{
529567
$key = "$test_user $gssencmode $client_mode $negotiation";
530568
$expected_events = $expected{$key};

0 commit comments

Comments
 (0)