Skip to content

Commit aa7464d

Browse files
committed
Add TAP tests for password-based authentication methods.
Tests all combinations of users with MD5, plaintext and SCRAM verifiers stored in pg_authid, with plain 'password', 'md5' and 'scram' authentication methods. Michael Paquier
1 parent c6305a9 commit aa7464d

File tree

5 files changed

+124
-1
lines changed

5 files changed

+124
-1
lines changed

src/test/Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ subdir = src/test
1212
top_builddir = ../..
1313
include $(top_builddir)/src/Makefile.global
1414

15-
SUBDIRS = perl regress isolation modules recovery subscription
15+
SUBDIRS = perl regress isolation modules authentication recovery subscription
1616

1717
# We don't build or execute examples/, locale/, or thread/ by default,
1818
# but we do want "make clean" etc to recurse into them. Likewise for ssl/,

src/test/README

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ individual contrib/ modules and in src/bin.
88
Not all these tests get run by "make check". Check src/test/Makefile to see
99
which tests get run automatically.
1010

11+
authentication/
12+
Tests for authentication
13+
1114
examples/
1215
Demonstration programs for libpq that double as regression tests via
1316
"make check"

src/test/authentication/Makefile

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#-------------------------------------------------------------------------
2+
#
3+
# Makefile for src/test/authentication
4+
#
5+
# Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
6+
# Portions Copyright (c) 1994, Regents of the University of California
7+
#
8+
# src/test/authentication/Makefile
9+
#
10+
#-------------------------------------------------------------------------
11+
12+
subdir = src/test/authentication
13+
top_builddir = ../../..
14+
include $(top_builddir)/src/Makefile.global
15+
16+
check:
17+
$(prove_check)
18+
19+
clean distclean maintainer-clean:
20+
rm -rf tmp_check

src/test/authentication/README

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
src/test/authentication/README
2+
3+
Regression tests for authentication
4+
===================================
5+
6+
This directory contains a test suite for authentication. SSL certificate
7+
authentication tests are kept separate, in src/test/ssl/, because they
8+
are more complicated, and are not safe to run in a multi-user system.
9+
10+
11+
Running the tests
12+
=================
13+
14+
make check
15+
16+
NOTE: This requires the --enable-tap-tests argument to configure.
+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Set of tests for authentication and pg_hba.conf. The following password
2+
# methods are checked through this test:
3+
# - Plain
4+
# - MD5-encrypted
5+
# - SCRAM-encrypted
6+
# This test cannot run on Windows as Postgres cannot be set up with Unix
7+
# sockets and needs to go through SSPI.
8+
9+
use strict;
10+
use warnings;
11+
use PostgresNode;
12+
use TestLib;
13+
use Test::More tests => 12;
14+
15+
# Delete pg_hba.conf from the given node, add a new entry to it
16+
# and then execute a reload to refresh it.
17+
sub reset_pg_hba
18+
{
19+
my $node = shift;
20+
my $hba_method = shift;
21+
22+
unlink($node->data_dir . '/pg_hba.conf');
23+
$node->append_conf('pg_hba.conf', "local all all $hba_method");
24+
$node->reload;
25+
}
26+
27+
# Test access for a single role, useful to wrap all tests into one.
28+
sub test_role
29+
{
30+
my $node = shift;
31+
my $role = shift;
32+
my $method = shift;
33+
my $expected_res = shift;
34+
my $status_string = 'failed';
35+
36+
$status_string = 'success' if ($expected_res eq 0);
37+
38+
my $res = $node->psql('postgres', 'SELECT 1', extra_params => ['-U', $role]);
39+
is($res, $expected_res,
40+
"authentication $status_string for method $method, role $role");
41+
}
42+
43+
SKIP:
44+
{
45+
skip "authentication tests cannot run on Windows", 12 if ($windows_os);
46+
47+
# Initialize master node
48+
my $node = get_new_node('master');
49+
$node->init;
50+
$node->start;
51+
52+
# Create 3 roles with different password methods for each one. The same
53+
# password is used for all of them.
54+
$node->safe_psql('postgres', "SET password_encryption='scram'; CREATE ROLE scram_role LOGIN PASSWORD 'pass';");
55+
$node->safe_psql('postgres', "SET password_encryption='md5'; CREATE ROLE md5_role LOGIN PASSWORD 'pass';");
56+
$node->safe_psql('postgres', "SET password_encryption='plain'; CREATE ROLE plain_role LOGIN PASSWORD 'pass';");
57+
$ENV{"PGPASSWORD"} = 'pass';
58+
59+
# For "trust" method, all users should be able to connect.
60+
reset_pg_hba($node, 'trust');
61+
test_role($node, 'scram_role', 'trust', 0);
62+
test_role($node, 'md5_role', 'trust', 0);
63+
test_role($node, 'plain_role', 'trust', 0);
64+
65+
# For plain "password" method, all users should also be able to connect.
66+
reset_pg_hba($node, 'password');
67+
test_role($node, 'scram_role', 'password', 0);
68+
test_role($node, 'md5_role', 'password', 0);
69+
test_role($node, 'plain_role', 'password', 0);
70+
71+
# For "scram" method, user "plain_role" and "scram_role" should be able to
72+
# connect.
73+
reset_pg_hba($node, 'scram');
74+
test_role($node, 'scram_role', 'scram', 0);
75+
test_role($node, 'md5_role', 'scram', 2);
76+
test_role($node, 'plain_role', 'scram', 0);
77+
78+
# For "md5" method, users "plain_role" and "md5_role" should be able to
79+
# connect.
80+
reset_pg_hba($node, 'md5');
81+
test_role($node, 'scram_role', 'md5', 2);
82+
test_role($node, 'md5_role', 'md5', 0);
83+
test_role($node, 'plain_role', 'md5', 0);
84+
}

0 commit comments

Comments
 (0)