Allow tests to pass in OpenSSL FIPS mode (TAP tests)
authorPeter Eisentraut <[email protected]>
Fri, 17 Nov 2023 13:40:13 +0000 (14:40 +0100)
committerPeter Eisentraut <[email protected]>
Fri, 17 Nov 2023 15:52:46 +0000 (16:52 +0100)
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 <[email protected]>
Reviewed-by: Daniel Gustafsson <[email protected]>
Discussion: https://www.postgresql.org/message-id/flat/dbbd927f-ef1f-c9a1-4ec6-c759778ac852%40enterprisedb.com

src/test/authentication/t/001_password.pl
src/test/ssl/t/002_scram.pl

index 891860886afb894cc9e95070e4229c30549f9e40..320e45ef8422d0af725cef5faf97f3e8ee06d640 100644 (file)
@@ -66,24 +66,33 @@ $node->init;
 $node->append_conf('postgresql.conf', "log_connections = on\n");
 $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
 # password is used for all of them.
-$node->safe_psql('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';"
-);
+is( $node->psql(
+               'postgres',
+               "SET password_encryption='scram-sha-256'; CREATE ROLE scram_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.
 $node->safe_psql(
        'postgres',
        "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';
 
 # Create a role that contains a comma to stress the parsing.
 $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
@@ -141,8 +150,13 @@ reset_pg_hba($node, 'all', 'all', 'trust');
 test_conn($node, 'user=scram_role', 'trust', 0,
        log_like =>
          [qr/connection authenticated: user="scram_role" method=trust/]);
-test_conn($node, 'user=md5_role', 'trust', 0,
-       log_like => [qr/connection authenticated: user="md5_role" method=trust/]);
+SKIP:
+{
+       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.
 $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;
 
         SELECT bool_and(SYSTEM_USER IS NOT DISTINCT FROM n) FROM sysuser_data;),
-       connstr => "user=md5_role");
+       connstr => "user=scram_role");
 is($res, 't',
        "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,
        log_like =>
          [qr/connection authenticated: identity="scram_role" method=password/]);
-test_conn($node, 'user=md5_role', 'password', 0,
-       log_like =>
-         [qr/connection authenticated: identity="md5_role" method=password/]);
+SKIP:
+{
+       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.
 $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,
        log_like =>
          [qr/connection authenticated: identity="scram_role" method=md5/]);
-test_conn($node, 'user=md5_role', 'md5', 0,
-       log_like =>
-         [qr/connection authenticated: identity="md5_role" method=md5/]);
+SKIP:
+{
+       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.
-$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");
+# require_auth succeeds with SCRAM required.
 $node->connect_ok(
-       "user=md5_role require_auth=md5,scram-sha-256,password",
-       "multiple authentication types required, works with MD5 auth");
+       "user=scram_role require_auth=scram-sha-256",
+       "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.
 $node->connect_fails(
-       "user=md5_role require_auth=password",
-       "password authentication required, fails with MD5 auth",
+       "user=scram_role require_auth=password",
+       "password authentication required, fails with SCRAM auth",
        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(
-       "user=md5_role require_auth=scram-sha-256",
-       "SCRAM authentication required, fails with MD5 auth",
+       "user=scram_role require_auth=md5",
+       "MD5 authentication required, fails with SCRAM auth",
        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(
-       "user=md5_role require_auth=none",
-       "all authentication types forbidden, fails with MD5 auth",
+       "user=scram_role require_auth=none",
+       "all authentication types forbidden, fails with SCRAM auth",
        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(
-       "user=md5_role require_auth=!md5",
-       "password authentication forbidden, fails with MD5 auth",
+       "user=scram_role require_auth=!scram-sha-256",
+       "password authentication forbidden, fails with SCRAM auth",
        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(
-       "user=md5_role require_auth=!password,!md5,!scram-sha-256",
-       "multiple authentication types forbidden, fails with MD5 auth",
+       "user=scram_role require_auth=!password,!md5,!scram-sha-256",
+       "multiple authentication types forbidden, fails with SCRAM auth",
        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.
 $node->safe_psql(
        'postgres',
        "TRUNCATE sysuser_data;
-INSERT INTO sysuser_data SELECT 'md5:md5_role' FROM generate_series(1, 10);",
-       connstr => "user=md5_role");
+INSERT INTO sysuser_data SELECT 'md5:scram_role' FROM generate_series(1, 10);",
+       connstr => "user=scram_role");
 $res = $node->safe_psql(
        'postgres', qq(
         SET min_parallel_table_scan_size TO 0;
@@ -454,7 +478,7 @@ $res = $node->safe_psql(
         SET max_parallel_workers_per_gather TO 2;
 
         SELECT bool_and(SYSTEM_USER IS NOT DISTINCT FROM n) FROM sysuser_data;),
-       connstr => "user=md5_role");
+       connstr => "user=scram_role");
 is($res, 't',
        "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(
        $pgpassfile, qq!
-*:*:*:md5_role:p\\ass
-*:*:*:md5,role:p\\ass
+*:*:*:scram_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.
-reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^md.*$', 'password');
-test_conn($node, 'user=md5_role', 'password, matching regexp for username', 0,
+reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^scr.*$', 'password');
+test_conn(
+       $node,
+       'user=scram_role',
+       'password, matching regexp for username',
+       0,
        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.
-reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^m_d.*$', 'password');
-test_conn($node, 'user=md5_role',
+reset_pg_hba($node, 'all', '/^.*nomatch.*$, baduser, /^sc_r.*$', 'password');
+test_conn($node, 'user=scram_role',
        'password, non matching regexp for username',
        2, log_unlike => [qr/connection authenticated:/]);
 
 # 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
 # of the user name list when parsing pg_hba.conf.
-reset_pg_hba($node, 'all', '"/^.*5,.*e$"', 'password');
-test_conn($node, 'user=md5,role', 'password, matching regexp for username', 0,
+reset_pg_hba($node, 'all', '"/^.*m,.*e$"', 'password');
+test_conn(
+       $node,
+       'user=scram,role',
+       'password, matching regexp for username',
+       0,
        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.
 reset_pg_hba($node, '/^.*nomatch.*$, baddb, /^regex_t.*b$', 'all',
        'password');
 test_conn(
        $node,
-       'user=md5_role dbname=regex_testdb',
+       'user=scram_role dbname=regex_testdb',
        'password, matching regexp for dbname',
        0,
        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.
 reset_pg_hba($node, '/^.*nomatch.*$, baddb, /^regex_t.*ba$',
        'all', 'password');
 test_conn(
        $node,
-       'user=md5_role dbname=regex_testdb',
+       'user=scram_role dbname=regex_testdb',
        'password, non matching regexp for dbname',
        2, log_unlike => [qr/connection authenticated:/]);
 
index 27abd02abf15efc929fb478f08a0457bce3d50da..91e771ec47d64177e4cdbf0d9f3d48a502ae84f4 100644 (file)
@@ -64,6 +64,9 @@ $ENV{PGHOST} = $node->host;
 $ENV{PGPORT} = $node->port;
 $node->start;
 
+# could fail in FIPS mode
+my $md5_works = ($node->psql('postgres', "select md5('')") == 0);
+
 # Configure server for SSL connections, with password handling.
 $ssl_server->configure_test_server_for_ssl(
        $node, $SERVERHOSTADDR, $SERVERHOSTCIDR,
@@ -91,12 +94,16 @@ $node->connect_ok("$common_connstr user=ssltestuser channel_binding=require",
        "SCRAM with SSL and channel_binding=require");
 
 # Now test when the user has an MD5-encrypted password; should fail
-$node->connect_fails(
-       "$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/
-);
+SKIP:
+{
+       skip "MD5 not supported" unless $md5_works;
+       $node->connect_fails(
+               "$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,
 # 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",
        "SCRAM with SSL, channel_binding=disable, and require_auth=scram-sha-256"
 );
-$node->connect_fails(
-       "$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/
-);
+SKIP:
+{
+       skip "MD5 not supported" unless $md5_works;
+       $node->connect_fails(
+               "$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(
        "$common_connstr user=ssltestuser channel_binding=require require_auth=scram-sha-256",
        "SCRAM with SSL, channel_binding=require, and require_auth=scram-sha-256"