Allow tests to pass in OpenSSL FIPS mode (TAP tests)
Some tests using md5 authentication have to be skipped. In other cases, we can rewrite the tests to use a different authentication method. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Reviewed-by: Daniel Gustafsson <daniel@yesql.se> Discussion: https://www.postgresql.org/message-id/flat/dbbd927f-ef1f-c9a1-4ec6-c759778ac852%40enterprisedb.com
This commit is contained in:
parent
795592865c
commit
284cbaea7c
@ -66,24 +66,33 @@ $node->init;
|
|||||||
$node->append_conf('postgresql.conf', "log_connections = on\n");
|
$node->append_conf('postgresql.conf', "log_connections = on\n");
|
||||||
$node->start;
|
$node->start;
|
||||||
|
|
||||||
|
# could fail in FIPS mode
|
||||||
|
my $md5_works = ($node->psql('postgres', "select md5('')") == 0);
|
||||||
|
|
||||||
# Create 3 roles with different password methods for each one. The same
|
# Create 3 roles with different password methods for each one. The same
|
||||||
# password is used for all of them.
|
# password is used for all of them.
|
||||||
$node->safe_psql('postgres',
|
is( $node->psql(
|
||||||
"SET password_encryption='scram-sha-256'; CREATE ROLE scram_role LOGIN PASSWORD 'pass';"
|
'postgres',
|
||||||
);
|
"SET password_encryption='scram-sha-256'; CREATE ROLE scram_role LOGIN PASSWORD 'pass';"
|
||||||
$node->safe_psql('postgres',
|
),
|
||||||
"SET password_encryption='md5'; CREATE ROLE md5_role LOGIN PASSWORD 'pass';"
|
0,
|
||||||
);
|
'created user with SCRAM password');
|
||||||
|
is( $node->psql(
|
||||||
|
'postgres',
|
||||||
|
"SET password_encryption='md5'; CREATE ROLE md5_role LOGIN PASSWORD 'pass';"
|
||||||
|
),
|
||||||
|
$md5_works ? 0 : 3,
|
||||||
|
'created user with md5 password');
|
||||||
# Set up a table for tests of SYSTEM_USER.
|
# Set up a table for tests of SYSTEM_USER.
|
||||||
$node->safe_psql(
|
$node->safe_psql(
|
||||||
'postgres',
|
'postgres',
|
||||||
"CREATE TABLE sysuser_data (n) AS SELECT NULL FROM generate_series(1, 10);
|
"CREATE TABLE sysuser_data (n) AS SELECT NULL FROM generate_series(1, 10);
|
||||||
GRANT ALL ON sysuser_data TO md5_role;");
|
GRANT ALL ON sysuser_data TO scram_role;");
|
||||||
$ENV{"PGPASSWORD"} = 'pass';
|
$ENV{"PGPASSWORD"} = 'pass';
|
||||||
|
|
||||||
# Create a role that contains a comma to stress the parsing.
|
# Create a role that contains a comma to stress the parsing.
|
||||||
$node->safe_psql('postgres',
|
$node->safe_psql('postgres',
|
||||||
q{SET password_encryption='md5'; CREATE ROLE "md5,role" LOGIN PASSWORD 'pass';}
|
q{SET password_encryption='scram-sha-256'; CREATE ROLE "scram,role" LOGIN PASSWORD 'pass';}
|
||||||
);
|
);
|
||||||
|
|
||||||
# Create a role with a non-default iteration count
|
# Create a role with a non-default iteration count
|
||||||
@ -141,8 +150,13 @@ reset_pg_hba($node, 'all', 'all', 'trust');
|
|||||||
test_conn($node, 'user=scram_role', 'trust', 0,
|
test_conn($node, 'user=scram_role', 'trust', 0,
|
||||||
log_like =>
|
log_like =>
|
||||||
[qr/connection authenticated: user="scram_role" method=trust/]);
|
[qr/connection authenticated: user="scram_role" method=trust/]);
|
||||||
test_conn($node, 'user=md5_role', 'trust', 0,
|
SKIP:
|
||||||
log_like => [qr/connection authenticated: user="md5_role" method=trust/]);
|
{
|
||||||
|
skip "MD5 not supported" unless $md5_works;
|
||||||
|
test_conn($node, 'user=md5_role', 'trust', 0,
|
||||||
|
log_like =>
|
||||||
|
[qr/connection authenticated: user="md5_role" method=trust/]);
|
||||||
|
}
|
||||||
|
|
||||||
# SYSTEM_USER is null when not authenticated.
|
# SYSTEM_USER is null when not authenticated.
|
||||||
$res = $node->safe_psql('postgres', "SELECT SYSTEM_USER IS NULL;");
|
$res = $node->safe_psql('postgres', "SELECT SYSTEM_USER IS NULL;");
|
||||||
@ -157,7 +171,7 @@ $res = $node->safe_psql(
|
|||||||
SET max_parallel_workers_per_gather TO 2;
|
SET max_parallel_workers_per_gather TO 2;
|
||||||
|
|
||||||
SELECT bool_and(SYSTEM_USER IS NOT DISTINCT FROM n) FROM sysuser_data;),
|
SELECT bool_and(SYSTEM_USER IS NOT DISTINCT FROM n) FROM sysuser_data;),
|
||||||
connstr => "user=md5_role");
|
connstr => "user=scram_role");
|
||||||
is($res, 't',
|
is($res, 't',
|
||||||
"users with trust authentication use SYSTEM_USER = NULL in parallel workers"
|
"users with trust authentication use SYSTEM_USER = NULL in parallel workers"
|
||||||
);
|
);
|
||||||
@ -275,9 +289,14 @@ reset_pg_hba($node, 'all', 'all', 'password');
|
|||||||
test_conn($node, 'user=scram_role', 'password', 0,
|
test_conn($node, 'user=scram_role', 'password', 0,
|
||||||
log_like =>
|
log_like =>
|
||||||
[qr/connection authenticated: identity="scram_role" method=password/]);
|
[qr/connection authenticated: identity="scram_role" method=password/]);
|
||||||
test_conn($node, 'user=md5_role', 'password', 0,
|
SKIP:
|
||||||
log_like =>
|
{
|
||||||
[qr/connection authenticated: identity="md5_role" method=password/]);
|
skip "MD5 not supported" unless $md5_works;
|
||||||
|
test_conn($node, 'user=md5_role', 'password', 0,
|
||||||
|
log_like =>
|
||||||
|
[qr/connection authenticated: identity="md5_role" method=password/]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
# require_auth succeeds here with a plaintext password.
|
# require_auth succeeds here with a plaintext password.
|
||||||
$node->connect_ok("user=scram_role require_auth=password",
|
$node->connect_ok("user=scram_role require_auth=password",
|
||||||
@ -393,59 +412,64 @@ reset_pg_hba($node, 'all', 'all', 'md5');
|
|||||||
test_conn($node, 'user=scram_role', 'md5', 0,
|
test_conn($node, 'user=scram_role', 'md5', 0,
|
||||||
log_like =>
|
log_like =>
|
||||||
[qr/connection authenticated: identity="scram_role" method=md5/]);
|
[qr/connection authenticated: identity="scram_role" method=md5/]);
|
||||||
test_conn($node, 'user=md5_role', 'md5', 0,
|
SKIP:
|
||||||
log_like =>
|
{
|
||||||
[qr/connection authenticated: identity="md5_role" method=md5/]);
|
skip "MD5 not supported" unless $md5_works;
|
||||||
|
test_conn($node, 'user=md5_role', 'md5', 0,
|
||||||
|
log_like =>
|
||||||
|
[qr/connection authenticated: identity="md5_role" method=md5/]);
|
||||||
|
}
|
||||||
|
|
||||||
# require_auth succeeds with MD5 required.
|
# require_auth succeeds with SCRAM required.
|
||||||
$node->connect_ok("user=md5_role require_auth=md5",
|
|
||||||
"MD5 authentication required, works with MD5 auth");
|
|
||||||
$node->connect_ok("user=md5_role require_auth=!none",
|
|
||||||
"any authentication required, works with MD5 auth");
|
|
||||||
$node->connect_ok(
|
$node->connect_ok(
|
||||||
"user=md5_role require_auth=md5,scram-sha-256,password",
|
"user=scram_role require_auth=scram-sha-256",
|
||||||
"multiple authentication types required, works with MD5 auth");
|
"SCRAM authentication required, works with SCRAM auth");
|
||||||
|
$node->connect_ok("user=scram_role require_auth=!none",
|
||||||
|
"any authentication required, works with SCRAM auth");
|
||||||
|
$node->connect_ok(
|
||||||
|
"user=scram_role require_auth=md5,scram-sha-256,password",
|
||||||
|
"multiple authentication types required, works with SCRAM auth");
|
||||||
|
|
||||||
# Authentication fails if other types are required.
|
# Authentication fails if other types are required.
|
||||||
$node->connect_fails(
|
$node->connect_fails(
|
||||||
"user=md5_role require_auth=password",
|
"user=scram_role require_auth=password",
|
||||||
"password authentication required, fails with MD5 auth",
|
"password authentication required, fails with SCRAM auth",
|
||||||
expected_stderr =>
|
expected_stderr =>
|
||||||
qr/authentication method requirement "password" failed: server requested a hashed password/
|
qr/authentication method requirement "password" failed: server requested SASL authentication/
|
||||||
);
|
);
|
||||||
$node->connect_fails(
|
$node->connect_fails(
|
||||||
"user=md5_role require_auth=scram-sha-256",
|
"user=scram_role require_auth=md5",
|
||||||
"SCRAM authentication required, fails with MD5 auth",
|
"MD5 authentication required, fails with SCRAM auth",
|
||||||
expected_stderr =>
|
expected_stderr =>
|
||||||
qr/authentication method requirement "scram-sha-256" failed: server requested a hashed password/
|
qr/authentication method requirement "md5" failed: server requested SASL authentication/
|
||||||
);
|
);
|
||||||
$node->connect_fails(
|
$node->connect_fails(
|
||||||
"user=md5_role require_auth=none",
|
"user=scram_role require_auth=none",
|
||||||
"all authentication types forbidden, fails with MD5 auth",
|
"all authentication types forbidden, fails with SCRAM auth",
|
||||||
expected_stderr =>
|
expected_stderr =>
|
||||||
qr/authentication method requirement "none" failed: server requested a hashed password/
|
qr/authentication method requirement "none" failed: server requested SASL authentication/
|
||||||
);
|
);
|
||||||
|
|
||||||
# Authentication fails if MD5 is forbidden.
|
# Authentication fails if SCRAM is forbidden.
|
||||||
$node->connect_fails(
|
$node->connect_fails(
|
||||||
"user=md5_role require_auth=!md5",
|
"user=scram_role require_auth=!scram-sha-256",
|
||||||
"password authentication forbidden, fails with MD5 auth",
|
"password authentication forbidden, fails with SCRAM auth",
|
||||||
expected_stderr =>
|
expected_stderr =>
|
||||||
qr/authentication method requirement "!md5" failed: server requested a hashed password/
|
qr/authentication method requirement "!scram-sha-256" failed: server requested SASL authentication/
|
||||||
);
|
);
|
||||||
$node->connect_fails(
|
$node->connect_fails(
|
||||||
"user=md5_role require_auth=!password,!md5,!scram-sha-256",
|
"user=scram_role require_auth=!password,!md5,!scram-sha-256",
|
||||||
"multiple authentication types forbidden, fails with MD5 auth",
|
"multiple authentication types forbidden, fails with SCRAM auth",
|
||||||
expected_stderr =>
|
expected_stderr =>
|
||||||
qr/authentication method requirement "!password,!md5,!scram-sha-256" failed: server requested a hashed password/
|
qr/authentication method requirement "!password,!md5,!scram-sha-256" failed: server requested SASL authentication/
|
||||||
);
|
);
|
||||||
|
|
||||||
# Test SYSTEM_USER <> NULL with parallel workers.
|
# Test SYSTEM_USER <> NULL with parallel workers.
|
||||||
$node->safe_psql(
|
$node->safe_psql(
|
||||||
'postgres',
|
'postgres',
|
||||||
"TRUNCATE sysuser_data;
|
"TRUNCATE sysuser_data;
|
||||||
INSERT INTO sysuser_data SELECT 'md5:md5_role' FROM generate_series(1, 10);",
|
INSERT INTO sysuser_data SELECT 'md5:scram_role' FROM generate_series(1, 10);",
|
||||||
connstr => "user=md5_role");
|
connstr => "user=scram_role");
|
||||||
$res = $node->safe_psql(
|
$res = $node->safe_psql(
|
||||||
'postgres', qq(
|
'postgres', qq(
|
||||||
SET min_parallel_table_scan_size TO 0;
|
SET min_parallel_table_scan_size TO 0;
|
||||||
@ -454,7 +478,7 @@ $res = $node->safe_psql(
|
|||||||
SET max_parallel_workers_per_gather TO 2;
|
SET max_parallel_workers_per_gather TO 2;
|
||||||
|
|
||||||
SELECT bool_and(SYSTEM_USER IS NOT DISTINCT FROM n) FROM sysuser_data;),
|
SELECT bool_and(SYSTEM_USER IS NOT DISTINCT FROM n) FROM sysuser_data;),
|
||||||
connstr => "user=md5_role");
|
connstr => "user=scram_role");
|
||||||
is($res, 't',
|
is($res, 't',
|
||||||
"users with md5 authentication use SYSTEM_USER = md5:role in parallel workers"
|
"users with md5 authentication use SYSTEM_USER = md5:role in parallel workers"
|
||||||
);
|
);
|
||||||
@ -490,49 +514,57 @@ test_conn($node, 'user=md5_role', 'password from pgpass', 2);
|
|||||||
|
|
||||||
append_to_file(
|
append_to_file(
|
||||||
$pgpassfile, qq!
|
$pgpassfile, qq!
|
||||||
*:*:*:md5_role:p\\ass
|
*:*:*:scram_role:p\\ass
|
||||||
*:*:*:md5,role:p\\ass
|
*:*:*:scram,role:p\\ass
|
||||||
!);
|
!);
|
||||||
|
|
||||||
test_conn($node, 'user=md5_role', 'password from pgpass', 0);
|
test_conn($node, 'user=scram_role', 'password from pgpass', 0);
|
||||||
|
|
||||||
# Testing with regular expression for username. The third regexp matches.
|
# Testing with regular expression for username. The third regexp matches.
|
||||||
reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^md.*$', 'password');
|
reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^scr.*$', 'password');
|
||||||
test_conn($node, 'user=md5_role', 'password, matching regexp for username', 0,
|
test_conn(
|
||||||
|
$node,
|
||||||
|
'user=scram_role',
|
||||||
|
'password, matching regexp for username',
|
||||||
|
0,
|
||||||
log_like =>
|
log_like =>
|
||||||
[qr/connection authenticated: identity="md5_role" method=password/]);
|
[qr/connection authenticated: identity="scram_role" method=password/]);
|
||||||
|
|
||||||
# The third regex does not match anymore.
|
# The third regex does not match anymore.
|
||||||
reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^m_d.*$', 'password');
|
reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^sc_r.*$', 'password');
|
||||||
test_conn($node, 'user=md5_role',
|
test_conn($node, 'user=scram_role',
|
||||||
'password, non matching regexp for username',
|
'password, non matching regexp for username',
|
||||||
2, log_unlike => [qr/connection authenticated:/]);
|
2, log_unlike => [qr/connection authenticated:/]);
|
||||||
|
|
||||||
# Test with a comma in the regular expression. In this case, the use of
|
# Test with a comma in the regular expression. In this case, the use of
|
||||||
# double quotes is mandatory so as this is not considered as two elements
|
# double quotes is mandatory so as this is not considered as two elements
|
||||||
# of the user name list when parsing pg_hba.conf.
|
# of the user name list when parsing pg_hba.conf.
|
||||||
reset_pg_hba($node, 'all', '"/^.*5,.*e$"', 'password');
|
reset_pg_hba($node, 'all', '"/^.*m,.*e$"', 'password');
|
||||||
test_conn($node, 'user=md5,role', 'password, matching regexp for username', 0,
|
test_conn(
|
||||||
|
$node,
|
||||||
|
'user=scram,role',
|
||||||
|
'password, matching regexp for username',
|
||||||
|
0,
|
||||||
log_like =>
|
log_like =>
|
||||||
[qr/connection authenticated: identity="md5,role" method=password/]);
|
[qr/connection authenticated: identity="scram,role" method=password/]);
|
||||||
|
|
||||||
# Testing with regular expression for dbname. The third regex matches.
|
# Testing with regular expression for dbname. The third regex matches.
|
||||||
reset_pg_hba($node, '/^.*nomatch.*$, baddb, /^regex_t.*b$', 'all',
|
reset_pg_hba($node, '/^.*nomatch.*$, baddb, /^regex_t.*b$', 'all',
|
||||||
'password');
|
'password');
|
||||||
test_conn(
|
test_conn(
|
||||||
$node,
|
$node,
|
||||||
'user=md5_role dbname=regex_testdb',
|
'user=scram_role dbname=regex_testdb',
|
||||||
'password, matching regexp for dbname',
|
'password, matching regexp for dbname',
|
||||||
0,
|
0,
|
||||||
log_like =>
|
log_like =>
|
||||||
[qr/connection authenticated: identity="md5_role" method=password/]);
|
[qr/connection authenticated: identity="scram_role" method=password/]);
|
||||||
|
|
||||||
# The third regexp does not match anymore.
|
# The third regexp does not match anymore.
|
||||||
reset_pg_hba($node, '/^.*nomatch.*$, baddb, /^regex_t.*ba$',
|
reset_pg_hba($node, '/^.*nomatch.*$, baddb, /^regex_t.*ba$',
|
||||||
'all', 'password');
|
'all', 'password');
|
||||||
test_conn(
|
test_conn(
|
||||||
$node,
|
$node,
|
||||||
'user=md5_role dbname=regex_testdb',
|
'user=scram_role dbname=regex_testdb',
|
||||||
'password, non matching regexp for dbname',
|
'password, non matching regexp for dbname',
|
||||||
2, log_unlike => [qr/connection authenticated:/]);
|
2, log_unlike => [qr/connection authenticated:/]);
|
||||||
|
|
||||||
|
@ -64,6 +64,9 @@ $ENV{PGHOST} = $node->host;
|
|||||||
$ENV{PGPORT} = $node->port;
|
$ENV{PGPORT} = $node->port;
|
||||||
$node->start;
|
$node->start;
|
||||||
|
|
||||||
|
# could fail in FIPS mode
|
||||||
|
my $md5_works = ($node->psql('postgres', "select md5('')") == 0);
|
||||||
|
|
||||||
# Configure server for SSL connections, with password handling.
|
# Configure server for SSL connections, with password handling.
|
||||||
$ssl_server->configure_test_server_for_ssl(
|
$ssl_server->configure_test_server_for_ssl(
|
||||||
$node, $SERVERHOSTADDR, $SERVERHOSTCIDR,
|
$node, $SERVERHOSTADDR, $SERVERHOSTCIDR,
|
||||||
@ -91,12 +94,16 @@ $node->connect_ok("$common_connstr user=ssltestuser channel_binding=require",
|
|||||||
"SCRAM with SSL and channel_binding=require");
|
"SCRAM with SSL and channel_binding=require");
|
||||||
|
|
||||||
# Now test when the user has an MD5-encrypted password; should fail
|
# Now test when the user has an MD5-encrypted password; should fail
|
||||||
$node->connect_fails(
|
SKIP:
|
||||||
"$common_connstr user=md5testuser channel_binding=require",
|
{
|
||||||
"MD5 with SSL and channel_binding=require",
|
skip "MD5 not supported" unless $md5_works;
|
||||||
expected_stderr =>
|
$node->connect_fails(
|
||||||
qr/channel binding required but not supported by server's authentication request/
|
"$common_connstr user=md5testuser channel_binding=require",
|
||||||
);
|
"MD5 with SSL and channel_binding=require",
|
||||||
|
expected_stderr =>
|
||||||
|
qr/channel binding required but not supported by server's authentication request/
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
# Now test with auth method 'cert' by connecting to 'certdb'. Should fail,
|
# Now test with auth method 'cert' by connecting to 'certdb'. Should fail,
|
||||||
# because channel binding is not performed. Note that ssl/client.key may
|
# because channel binding is not performed. Note that ssl/client.key may
|
||||||
@ -130,12 +137,16 @@ $node->connect_ok(
|
|||||||
"$common_connstr user=ssltestuser channel_binding=disable require_auth=scram-sha-256",
|
"$common_connstr user=ssltestuser channel_binding=disable require_auth=scram-sha-256",
|
||||||
"SCRAM with SSL, channel_binding=disable, and require_auth=scram-sha-256"
|
"SCRAM with SSL, channel_binding=disable, and require_auth=scram-sha-256"
|
||||||
);
|
);
|
||||||
$node->connect_fails(
|
SKIP:
|
||||||
"$common_connstr user=md5testuser require_auth=md5 channel_binding=require",
|
{
|
||||||
"channel_binding can fail even when require_auth succeeds",
|
skip "MD5 not supported" unless $md5_works;
|
||||||
expected_stderr =>
|
$node->connect_fails(
|
||||||
qr/channel binding required but not supported by server's authentication request/
|
"$common_connstr user=md5testuser require_auth=md5 channel_binding=require",
|
||||||
);
|
"channel_binding can fail even when require_auth succeeds",
|
||||||
|
expected_stderr =>
|
||||||
|
qr/channel binding required but not supported by server's authentication request/
|
||||||
|
);
|
||||||
|
}
|
||||||
$node->connect_ok(
|
$node->connect_ok(
|
||||||
"$common_connstr user=ssltestuser channel_binding=require require_auth=scram-sha-256",
|
"$common_connstr user=ssltestuser channel_binding=require require_auth=scram-sha-256",
|
||||||
"SCRAM with SSL, channel_binding=require, and require_auth=scram-sha-256"
|
"SCRAM with SSL, channel_binding=require, and require_auth=scram-sha-256"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user