summaryrefslogtreecommitdiffstats
path: root/src/test/ssl/t/002_scram.pl
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/ssl/t/002_scram.pl')
-rw-r--r--src/test/ssl/t/002_scram.pl108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/test/ssl/t/002_scram.pl b/src/test/ssl/t/002_scram.pl
new file mode 100644
index 0000000..d1e8d88
--- /dev/null
+++ b/src/test/ssl/t/002_scram.pl
@@ -0,0 +1,108 @@
+# Test SCRAM authentication and TLS channel binding types
+
+use strict;
+use warnings;
+use PostgresNode;
+use TestLib;
+use Test::More;
+
+use File::Copy;
+
+use FindBin;
+use lib $FindBin::RealBin;
+
+use SSLServer;
+
+if ($ENV{with_openssl} ne 'yes')
+{
+ plan skip_all => 'SSL not supported by this build';
+}
+
+# This is the hostname used to connect to the server.
+my $SERVERHOSTADDR = '127.0.0.1';
+# This is the pattern to use in pg_hba.conf to match incoming connections.
+my $SERVERHOSTCIDR = '127.0.0.1/32';
+
+# Determine whether build supports tls-server-end-point.
+my $supports_tls_server_end_point =
+ check_pg_config("#define HAVE_X509_GET_SIGNATURE_NID 1");
+
+my $number_of_tests = $supports_tls_server_end_point ? 9 : 10;
+
+# Allocation of base connection string shared among multiple tests.
+my $common_connstr;
+
+# Set up the server.
+
+note "setting up data directory";
+my $node = get_new_node('master');
+$node->init;
+
+# PGHOST is enforced here to set up the node, subsequent connections
+# will use a dedicated connection string.
+$ENV{PGHOST} = $node->host;
+$ENV{PGPORT} = $node->port;
+$node->start;
+
+# Configure server for SSL connections, with password handling.
+configure_test_server_for_ssl($node, $SERVERHOSTADDR, $SERVERHOSTCIDR,
+ "scram-sha-256", "pass", "scram-sha-256");
+switch_server_cert($node, 'server-cn-only');
+$ENV{PGPASSWORD} = "pass";
+$common_connstr =
+ "dbname=trustdb sslmode=require sslcert=invalid sslrootcert=invalid hostaddr=$SERVERHOSTADDR";
+
+# Default settings
+test_connect_ok($common_connstr, "user=ssltestuser",
+ "Basic SCRAM authentication with SSL");
+
+# Test channel_binding
+test_connect_fails(
+ $common_connstr,
+ "user=ssltestuser channel_binding=invalid_value",
+ qr/invalid channel_binding value: "invalid_value"/,
+ "SCRAM with SSL and channel_binding=invalid_value");
+test_connect_ok(
+ $common_connstr,
+ "user=ssltestuser channel_binding=disable",
+ "SCRAM with SSL and channel_binding=disable");
+if ($supports_tls_server_end_point)
+{
+ test_connect_ok(
+ $common_connstr,
+ "user=ssltestuser channel_binding=require",
+ "SCRAM with SSL and channel_binding=require");
+}
+else
+{
+ test_connect_fails(
+ $common_connstr,
+ "user=ssltestuser channel_binding=require",
+ qr/channel binding is required, but server did not offer an authentication method that supports channel binding/,
+ "SCRAM with SSL and channel_binding=require");
+}
+
+# Now test when the user has an MD5-encrypted password; should fail
+test_connect_fails(
+ $common_connstr,
+ "user=md5testuser channel_binding=require",
+ qr/channel binding required but not supported by server's authentication request/,
+ "MD5 with SSL and channel_binding=require");
+
+# Now test with auth method 'cert' by connecting to 'certdb'. Should fail,
+# because channel binding is not performed. Note that ssl/client.key may
+# be used in a different test, so the name of this temporary client key
+# is chosen here to be unique.
+my $client_tmp_key = "ssl/client_scram_tmp.key";
+copy("ssl/client.key", $client_tmp_key);
+chmod 0600, $client_tmp_key;
+test_connect_fails(
+ "sslcert=ssl/client.crt sslkey=$client_tmp_key sslrootcert=invalid hostaddr=$SERVERHOSTADDR",
+ "dbname=certdb user=ssltestuser channel_binding=require",
+ qr/channel binding required, but server authenticated client without channel binding/,
+ "Cert authentication and channel_binding=require");
+
+# clean up
+unlink($client_tmp_key);
+
+done_testing($number_of_tests);