postgres/src/test/ssl/ServerSetup.pm
Peter Eisentraut 967a4b01e3 Fix ssl tests
facde2a98f0b5f7689b4e30a9e7376e926e733b8 introduced a typo during
rebasing.
2017-03-28 13:23:33 -04:00

137 lines
4.0 KiB
Perl

# 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
# - two users, called ssltestuser and anotheruser.
#
# 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.
package ServerSetup;
use strict;
use warnings;
use PostgresNode;
use TestLib;
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";
}
}
sub configure_test_server_for_ssl
{
my $node = $_[0];
my $serverhost = $_[1];
my $pgdata = $node->data_dir;
# Create test users and databases
$node->psql('postgres', "CREATE USER ssltestuser");
$node->psql('postgres', "CREATE USER anotheruser");
$node->psql('postgres', "CREATE DATABASE trustdb");
$node->psql('postgres', "CREATE DATABASE certdb");
# 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'";
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);
# 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, $serverhost);
}
# 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 $pgdata = $node->data_dir;
diag "Reloading server with certfile \"$certfile\" and cafile \"$cafile\"...";
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='root+client.crl'\n";
close $sslconf;
$node->reload;
}
sub configure_hba_for_ssl
{
my $node = $_[0];
my $serverhost = $_[1];
my $pgdata = $node->data_dir;
# Only accept SSL connections from localhost. 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\n";
print $hba
"hostssl trustdb ssltestuser $serverhost/32 trust\n";
print $hba
"hostssl trustdb ssltestuser ::1/128 trust\n";
print $hba
"hostssl certdb ssltestuser $serverhost/32 cert\n";
print $hba
"hostssl certdb ssltestuser ::1/128 cert\n";
close $hba;
}