aboutsummaryrefslogtreecommitdiff
path: root/src/test/ssl/t/SSLServer.pm
diff options
context:
space:
mode:
authorDaniel Gustafsson <dgustafsson@postgresql.org>2022-03-26 22:00:39 +0100
committerDaniel Gustafsson <dgustafsson@postgresql.org>2022-03-26 22:00:39 +0100
commit4a7e964fc67a541b6ea1b72729ad3f8e632d003c (patch)
treed1907da1a974fbfb21e789c4edb69135e7075de7 /src/test/ssl/t/SSLServer.pm
parente07d4ddc55fdcf82082950b3eb0cd8f728284c9d (diff)
downloadpostgresql-4a7e964fc67a541b6ea1b72729ad3f8e632d003c.tar.gz
postgresql-4a7e964fc67a541b6ea1b72729ad3f8e632d003c.zip
SSL TAP test backend library independence refactoring
The SSL TAP tests were tightly coupled to the OpenSSL implementation, making it hard to add support for additional SSL/TLS backends. This refactoring makes the test avoid depending on specific implementations The SSLServer Perl module is renamed SSL::Server, which in turn use SSL::Backend::X where X is the backend pointed to by with_ssl. Each backend will implement its own module responsible for setting up keys, certs and to resolve sslkey values to their implementation specific value (file paths or vault nicknames etc). Further, switch_server_cert now takes a set of named parameters rather than a fixed set which used defaults. The modules also come with POD documentation. There are a few testcases which still use OpenSSL specifics, but it's not entirely clear how to abstract those until we have another library implemented. Original patch by me, with lots of rework by Andrew Dunstan to turn it into better Perl. Discussion: https://postgr.es/m/AA18A362-CA65-4F9A-AF61-76AE318FE97C@yesql.se
Diffstat (limited to 'src/test/ssl/t/SSLServer.pm')
-rw-r--r--src/test/ssl/t/SSLServer.pm219
1 files changed, 0 insertions, 219 deletions
diff --git a/src/test/ssl/t/SSLServer.pm b/src/test/ssl/t/SSLServer.pm
deleted file mode 100644
index c85c6fd997a..00000000000
--- a/src/test/ssl/t/SSLServer.pm
+++ /dev/null
@@ -1,219 +0,0 @@
-
-# Copyright (c) 2021-2022, PostgreSQL Global Development Group
-
-# This module sets up a test server, for the SSL regression tests.
-#
-# The server is configured as follows:
-#
-# - SSL enabled, with the server certificate specified by argument to
-# switch_server_cert function.
-# - ssl/root+client_ca.crt as the CA root for validating client certs.
-# - reject non-SSL connections
-# - a database called trustdb that lets anyone in
-# - another database called certdb that uses certificate authentication, ie.
-# the client must present a valid certificate signed by the client CA
-#
-# The server is configured to only accept connections from localhost. If you
-# want to run the client from another host, you'll have to configure that
-# manually.
-#
-# Note: Someone running these test could have key or certificate files
-# in their ~/.postgresql/, which would interfere with the tests. The
-# way to override that is to specify sslcert=invalid and/or
-# sslrootcert=invalid if no actual certificate is used for a
-# particular test. libpq will ignore specifications that name
-# nonexisting files. (sslkey and sslcrl do not need to specified
-# explicitly because an invalid sslcert or sslrootcert, respectively,
-# causes those to be ignored.)
-
-package SSLServer;
-
-use strict;
-use warnings;
-use PostgreSQL::Test::Cluster;
-use PostgreSQL::Test::Utils;
-use File::Basename;
-use File::Copy;
-use Test::More;
-
-use Exporter 'import';
-our @EXPORT = qw(
- configure_test_server_for_ssl
- switch_server_cert
-);
-
-# Copy a set of files, taking into account wildcards
-sub copy_files
-{
- my $orig = shift;
- my $dest = shift;
-
- my @orig_files = glob $orig;
- foreach my $orig_file (@orig_files)
- {
- my $base_file = basename($orig_file);
- copy($orig_file, "$dest/$base_file")
- or die "Could not copy $orig_file to $dest";
- }
- return;
-}
-
-# serverhost: what to put in listen_addresses, e.g. '127.0.0.1'
-# servercidr: what to put in pg_hba.conf, e.g. '127.0.0.1/32'
-sub configure_test_server_for_ssl
-{
- my ($node, $serverhost, $servercidr, $authmethod, %params) = @_;
- my $pgdata = $node->data_dir;
-
- my @databases = ( 'trustdb', 'certdb', 'certdb_dn', 'certdb_dn_re', 'certdb_cn', 'verifydb' );
-
- # Create test users and databases
- $node->psql('postgres', "CREATE USER ssltestuser");
- $node->psql('postgres', "CREATE USER md5testuser");
- $node->psql('postgres', "CREATE USER anotheruser");
- $node->psql('postgres', "CREATE USER yetanotheruser");
-
- foreach my $db (@databases)
- {
- $node->psql('postgres', "CREATE DATABASE $db");
- }
-
- # Update password of each user as needed.
- if (defined($params{password}))
- {
- die "Password encryption must be specified when password is set"
- unless defined($params{password_enc});
-
- $node->psql('postgres',
- "SET password_encryption='$params{password_enc}'; ALTER USER ssltestuser PASSWORD '$params{password}';"
- );
- # A special user that always has an md5-encrypted password
- $node->psql('postgres',
- "SET password_encryption='md5'; ALTER USER md5testuser PASSWORD '$params{password}';"
- );
- $node->psql('postgres',
- "SET password_encryption='$params{password_enc}'; ALTER USER anotheruser PASSWORD '$params{password}';"
- );
- }
-
- # Create any extensions requested in the setup
- if (defined($params{extensions}))
- {
- foreach my $extension (@{$params{extensions}})
- {
- foreach my $db (@databases)
- {
- $node->psql($db, "CREATE EXTENSION $extension CASCADE;");
- }
- }
- }
-
- # enable logging etc.
- open my $conf, '>>', "$pgdata/postgresql.conf";
- print $conf "fsync=off\n";
- print $conf "log_connections=on\n";
- print $conf "log_hostname=on\n";
- print $conf "listen_addresses='$serverhost'\n";
- print $conf "log_statement=all\n";
-
- # enable SSL and set up server key
- print $conf "include 'sslconfig.conf'\n";
-
- close $conf;
-
- # ssl configuration will be placed here
- open my $sslconf, '>', "$pgdata/sslconfig.conf";
- close $sslconf;
-
- # Copy all server certificates and keys, and client root cert, to the data dir
- copy_files("ssl/server-*.crt", $pgdata);
- copy_files("ssl/server-*.key", $pgdata);
- chmod(0600, glob "$pgdata/server-*.key") or die $!;
- copy_files("ssl/root+client_ca.crt", $pgdata);
- copy_files("ssl/root_ca.crt", $pgdata);
- copy_files("ssl/root+client.crl", $pgdata);
- mkdir("$pgdata/root+client-crldir");
- copy_files("ssl/root+client-crldir/*", "$pgdata/root+client-crldir/");
-
- # Stop and restart server to load new listen_addresses.
- $node->restart;
-
- # Change pg_hba after restart because hostssl requires ssl=on
- configure_hba_for_ssl($node, $servercidr, $authmethod);
-
- return;
-}
-
-# Change the configuration to use given server cert file, and reload
-# the server so that the configuration takes effect.
-sub switch_server_cert
-{
- my $node = $_[0];
- my $certfile = $_[1];
- my $cafile = $_[2] || "root+client_ca";
- my $crlfile = "root+client.crl";
- my $crldir;
- my $pgdata = $node->data_dir;
-
- # defaults to use crl file
- if (defined $_[3] || defined $_[4])
- {
- $crlfile = $_[3];
- $crldir = $_[4];
- }
-
- open my $sslconf, '>', "$pgdata/sslconfig.conf";
- print $sslconf "ssl=on\n";
- print $sslconf "ssl_ca_file='$cafile.crt'\n";
- print $sslconf "ssl_cert_file='$certfile.crt'\n";
- print $sslconf "ssl_key_file='$certfile.key'\n";
- print $sslconf "ssl_crl_file='$crlfile'\n" if defined $crlfile;
- print $sslconf "ssl_crl_dir='$crldir'\n" if defined $crldir;
- close $sslconf;
-
- $node->restart;
- return;
-}
-
-sub configure_hba_for_ssl
-{
- my ($node, $servercidr, $authmethod) = @_;
- my $pgdata = $node->data_dir;
-
- # Only accept SSL connections from $servercidr. Our tests don't depend on this
- # but seems best to keep it as narrow as possible for security reasons.
- #
- # When connecting to certdb, also check the client certificate.
- open my $hba, '>', "$pgdata/pg_hba.conf";
- print $hba
- "# TYPE DATABASE USER ADDRESS METHOD OPTIONS\n";
- print $hba
- "hostssl trustdb md5testuser $servercidr md5\n";
- print $hba
- "hostssl trustdb all $servercidr $authmethod\n";
- print $hba
- "hostssl verifydb ssltestuser $servercidr $authmethod clientcert=verify-full\n";
- print $hba
- "hostssl verifydb anotheruser $servercidr $authmethod clientcert=verify-full\n";
- print $hba
- "hostssl verifydb yetanotheruser $servercidr $authmethod clientcert=verify-ca\n";
- print $hba
- "hostssl certdb all $servercidr cert\n";
- print $hba
- "hostssl certdb_dn all $servercidr cert clientname=DN map=dn\n",
- "hostssl certdb_dn_re all $servercidr cert clientname=DN map=dnre\n",
- "hostssl certdb_cn all $servercidr cert clientname=CN map=cn\n";
- close $hba;
-
- # Also set the ident maps. Note: fields with commas must be quoted
- open my $map, ">", "$pgdata/pg_ident.conf";
- print $map
- "# MAPNAME SYSTEM-USERNAME PG-USERNAME\n",
- "dn \"CN=ssltestuser-dn,OU=Testing,OU=Engineering,O=PGDG\" ssltestuser\n",
- "dnre \"/^.*OU=Testing,.*\$\" ssltestuser\n",
- "cn ssltestuser-dn ssltestuser\n";
-
- return;
-}
-
-1;