Skip to content

Commit 0caafab

Browse files
committed
Improved TLSTest to cover more cases
1 parent a2d2f90 commit 0caafab

File tree

4 files changed

+183
-9
lines changed

4 files changed

+183
-9
lines changed

vertx-pg-client/src/test/java/io/vertx/pgclient/TLSTest.java

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,13 @@
3535
public class TLSTest {
3636

3737
@ClassRule
38-
public static ContainerPgRule rule = new ContainerPgRule().ssl(true);
38+
public static ContainerPgRule ruleOptionalSll = new ContainerPgRule().ssl(true);
39+
40+
@ClassRule
41+
public static ContainerPgRule ruleForceSsl = new ContainerPgRule().ssl(true).forceSsl(true);
42+
43+
@ClassRule
44+
public static ContainerPgRule ruleSllOff = new ContainerPgRule().ssl(false);
3945

4046
private Vertx vertx;
4147

@@ -53,7 +59,7 @@ public void teardown(TestContext ctx) {
5359
public void testTLS(TestContext ctx) {
5460
Async async = ctx.async();
5561

56-
PgConnectOptions options = new PgConnectOptions(rule.options())
62+
PgConnectOptions options = new PgConnectOptions(ruleOptionalSll.options())
5763
.setSslMode(SslMode.REQUIRE)
5864
.setSslOptions(new ClientSSLOptions().setTrustOptions(new PemTrustOptions().addCertPath("tls/server.crt")));
5965
PgConnection.connect(vertx, options.setSslMode(SslMode.REQUIRE)).onComplete(ctx.asyncAssertSuccess(conn -> {
@@ -74,7 +80,7 @@ public void testTLS(TestContext ctx) {
7480
@Test
7581
public void testTLSTrustAll(TestContext ctx) {
7682
Async async = ctx.async();
77-
PgConnection.connect(vertx, rule.options().setSslMode(SslMode.REQUIRE).setSslOptions(new ClientSSLOptions().setTrustAll(true))).onComplete(ctx.asyncAssertSuccess(conn -> {
83+
PgConnection.connect(vertx, ruleOptionalSll.options().setSslMode(SslMode.REQUIRE).setSslOptions(new ClientSSLOptions().setTrustAll(true))).onComplete(ctx.asyncAssertSuccess(conn -> {
7884
ctx.assertTrue(conn.isSSL());
7985
async.complete();
8086
}));
@@ -83,7 +89,7 @@ public void testTLSTrustAll(TestContext ctx) {
8389
@Test
8490
public void testTLSInvalidCertificate(TestContext ctx) {
8591
Async async = ctx.async();
86-
PgConnection.connect(vertx, rule.options().setSslMode(SslMode.REQUIRE).setSslOptions(new ClientSSLOptions().setTrustOptions(new PemTrustOptions().addCertPath("tls/another.crt")))).onComplete(ctx.asyncAssertFailure(err -> {
92+
PgConnection.connect(vertx, ruleOptionalSll.options().setSslMode(SslMode.REQUIRE).setSslOptions(new ClientSSLOptions().setTrustOptions(new PemTrustOptions().addCertPath("tls/another.crt")))).onComplete(ctx.asyncAssertFailure(err -> {
8793
// ctx.assertEquals(err.getClass(), VertxException.class);
8894
ctx.assertEquals(err.getMessage(), "SSL handshake failed");
8995
async.complete();
@@ -93,7 +99,7 @@ public void testTLSInvalidCertificate(TestContext ctx) {
9399
@Test
94100
public void testSslModeDisable(TestContext ctx) {
95101
Async async = ctx.async();
96-
PgConnectOptions options = rule.options()
102+
PgConnectOptions options = ruleOptionalSll.options()
97103
.setSslMode(SslMode.DISABLE);
98104
PgConnection.connect(vertx, new PgConnectOptions(options)).onComplete(ctx.asyncAssertSuccess(conn -> {
99105
ctx.assertFalse(conn.isSSL());
@@ -104,18 +110,30 @@ public void testSslModeDisable(TestContext ctx) {
104110
@Test
105111
public void testSslModeAllow(TestContext ctx) {
106112
Async async = ctx.async();
107-
PgConnectOptions options = rule.options()
113+
PgConnectOptions options = ruleOptionalSll.options()
108114
.setSslMode(SslMode.ALLOW);
109115
PgConnection.connect(vertx, new PgConnectOptions(options)).onComplete(ctx.asyncAssertSuccess(conn -> {
110116
ctx.assertFalse(conn.isSSL());
111117
async.complete();
112118
}));
113119
}
114120

121+
@Test
122+
public void testSslModeAllowFallback(TestContext ctx) {
123+
Async async = ctx.async();
124+
PgConnectOptions options = ruleForceSsl.options()
125+
.setSslMode(SslMode.ALLOW)
126+
.setSslOptions(new ClientSSLOptions().setTrustAll(true));
127+
PgConnection.connect(vertx, new PgConnectOptions(options)).onComplete(ctx.asyncAssertSuccess(conn -> {
128+
ctx.assertFalse(conn.isSSL());
129+
async.complete();
130+
}));
131+
}
132+
115133
@Test
116134
public void testSslModePrefer(TestContext ctx) {
117135
Async async = ctx.async();
118-
PgConnectOptions options = rule.options()
136+
PgConnectOptions options = ruleOptionalSll.options()
119137
.setSslMode(SslMode.PREFER)
120138
.setSslOptions(new ClientSSLOptions().setTrustAll(true));
121139
PgConnection.connect(vertx, new PgConnectOptions(options)).onComplete(ctx.asyncAssertSuccess(conn -> {
@@ -124,9 +142,21 @@ public void testSslModePrefer(TestContext ctx) {
124142
}));
125143
}
126144

145+
@Test
146+
public void testSslModePreferFallback(TestContext ctx) {
147+
Async async = ctx.async();
148+
PgConnectOptions options = ruleSllOff.options()
149+
.setSslMode(SslMode.PREFER)
150+
.setSslOptions(new ClientSSLOptions().setTrustAll(true));
151+
PgConnection.connect(vertx, options).onComplete(ctx.asyncAssertSuccess(conn -> {
152+
ctx.assertTrue(conn.isSSL());
153+
async.complete();
154+
}));
155+
}
156+
127157
@Test
128158
public void testSslModeVerifyCaConf(TestContext ctx) {
129-
PgConnectOptions options = rule.options()
159+
PgConnectOptions options = ruleOptionalSll.options()
130160
.setSslMode(SslMode.VERIFY_CA)
131161
.setSslOptions(new ClientSSLOptions().setTrustAll(true));
132162
PgConnection.connect(vertx, new PgConnectOptions(options)).onComplete(ctx.asyncAssertFailure(error -> {
@@ -136,7 +166,7 @@ public void testSslModeVerifyCaConf(TestContext ctx) {
136166

137167
@Test
138168
public void testSslModeVerifyFullConf(TestContext ctx) {
139-
PgConnectOptions options = rule.options()
169+
PgConnectOptions options = ruleOptionalSll.options()
140170
.setSslOptions(new ClientSSLOptions().setTrustOptions(new PemTrustOptions().addCertPath("tls/another.crt")))
141171
.setSslMode(SslMode.VERIFY_FULL);
142172
PgConnection.connect(vertx, new PgConnectOptions(options)).onComplete(ctx.asyncAssertFailure(error -> {

vertx-pg-client/src/test/java/io/vertx/pgclient/junit/ContainerPgRule.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,19 @@ public class ContainerPgRule extends ExternalResource {
4141
private PgConnectOptions options;
4242
private String databaseVersion;
4343
private boolean ssl;
44+
private boolean forceSsl;
4445
private String user = "postgres";
4546

4647
public ContainerPgRule ssl(boolean ssl) {
4748
this.ssl = ssl;
4849
return this;
4950
}
5051

52+
public ContainerPgRule forceSsl(boolean forceSsl) {
53+
this.forceSsl = forceSsl;
54+
return this;
55+
}
56+
5157
public PgConnectOptions options() {
5258
return new PgConnectOptions(options);
5359
}
@@ -75,6 +81,12 @@ private void initServer(String version) throws Exception {
7581
.withClasspathResourceMapping("tls/server.crt", "/server.crt", BindMode.READ_ONLY)
7682
.withClasspathResourceMapping("tls/server.key", "/server.key", BindMode.READ_ONLY)
7783
.withClasspathResourceMapping("tls/ssl.sh", "/docker-entrypoint-initdb.d/ssl.sh", BindMode.READ_ONLY);
84+
if (forceSsl) {
85+
server
86+
.withClasspathResourceMapping("tls/pg_hba.conf", "/tmp/pg_hba.conf", BindMode.READ_ONLY)
87+
.withClasspathResourceMapping("tls/force_ssl.sh", "/docker-entrypoint-initdb.d/force_ssl.sh", BindMode.READ_ONLY);
88+
89+
}
7890
}
7991
if (System.getProperties().containsKey("containerFixedPort")) {
8092
server.withFixedExposedPort(POSTGRESQL_PORT, POSTGRESQL_PORT);
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/bash
2+
3+
# force ssl
4+
cp /tmp/pg_hba.conf /var/lib/postgresql/data/pg_hba.conf
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# PostgreSQL Client Authentication Configuration File
2+
# ===================================================
3+
#
4+
# Refer to the "Client Authentication" section in the PostgreSQL
5+
# documentation for a complete description of this file. A short
6+
# synopsis follows.
7+
#
8+
# ----------------------
9+
# Authentication Records
10+
# ----------------------
11+
#
12+
# This file controls: which hosts are allowed to connect, how clients
13+
# are authenticated, which PostgreSQL user names they can use, which
14+
# databases they can access. Records take one of these forms:
15+
#
16+
# local DATABASE USER METHOD [OPTIONS]
17+
# host DATABASE USER ADDRESS METHOD [OPTIONS]
18+
# hostssl DATABASE USER ADDRESS METHOD [OPTIONS]
19+
# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS]
20+
# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS]
21+
# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS]
22+
#
23+
# (The uppercase items must be replaced by actual values.)
24+
#
25+
# The first field is the connection type:
26+
# - "local" is a Unix-domain socket
27+
# - "host" is a TCP/IP socket (encrypted or not)
28+
# - "hostssl" is a TCP/IP socket that is SSL-encrypted
29+
# - "hostnossl" is a TCP/IP socket that is not SSL-encrypted
30+
# - "hostgssenc" is a TCP/IP socket that is GSSAPI-encrypted
31+
# - "hostnogssenc" is a TCP/IP socket that is not GSSAPI-encrypted
32+
#
33+
# DATABASE can be "all", "sameuser", "samerole", "replication", a
34+
# database name, a regular expression (if it starts with a slash (/))
35+
# or a comma-separated list thereof. The "all" keyword does not match
36+
# "replication". Access to replication must be enabled in a separate
37+
# record (see example below).
38+
#
39+
# USER can be "all", a user name, a group name prefixed with "+", a
40+
# regular expression (if it starts with a slash (/)) or a comma-separated
41+
# list thereof. In both the DATABASE and USER fields you can also write
42+
# a file name prefixed with "@" to include names from a separate file.
43+
#
44+
# ADDRESS specifies the set of hosts the record matches. It can be a
45+
# host name, or it is made up of an IP address and a CIDR mask that is
46+
# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that
47+
# specifies the number of significant bits in the mask. A host name
48+
# that starts with a dot (.) matches a suffix of the actual host name.
49+
# Alternatively, you can write an IP address and netmask in separate
50+
# columns to specify the set of hosts. Instead of a CIDR-address, you
51+
# can write "samehost" to match any of the server's own IP addresses,
52+
# or "samenet" to match any address in any subnet that the server is
53+
# directly connected to.
54+
#
55+
# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256",
56+
# "gss", "sspi", "ident", "peer", "pam", "ldap", "radius" or "cert".
57+
# Note that "password" sends passwords in clear text; "md5" or
58+
# "scram-sha-256" are preferred since they send encrypted passwords.
59+
#
60+
# OPTIONS are a set of options for the authentication in the format
61+
# NAME=VALUE. The available options depend on the different
62+
# authentication methods -- refer to the "Client Authentication"
63+
# section in the documentation for a list of which options are
64+
# available for which authentication methods.
65+
#
66+
# Database and user names containing spaces, commas, quotes and other
67+
# special characters must be quoted. Quoting one of the keywords
68+
# "all", "sameuser", "samerole" or "replication" makes the name lose
69+
# its special character, and just match a database or username with
70+
# that name.
71+
#
72+
# ---------------
73+
# Include Records
74+
# ---------------
75+
#
76+
# This file allows the inclusion of external files or directories holding
77+
# more records, using the following keywords:
78+
#
79+
# include FILE
80+
# include_if_exists FILE
81+
# include_dir DIRECTORY
82+
#
83+
# FILE is the file name to include, and DIR is the directory name containing
84+
# the file(s) to include. Any file in a directory will be loaded if suffixed
85+
# with ".conf". The files of a directory are ordered by name.
86+
# include_if_exists ignores missing files. FILE and DIRECTORY can be
87+
# specified as a relative or an absolute path, and can be double-quoted if
88+
# they contain spaces.
89+
#
90+
# -------------
91+
# Miscellaneous
92+
# -------------
93+
#
94+
# This file is read on server startup and when the server receives a
95+
# SIGHUP signal. If you edit the file on a running system, you have to
96+
# SIGHUP the server for the changes to take effect, run "pg_ctl reload",
97+
# or execute "SELECT pg_reload_conf()".
98+
#
99+
# ----------------------------------
100+
# Put your actual configuration here
101+
# ----------------------------------
102+
#
103+
# If you want to allow non-local connections, you need to add more
104+
# "host" records. In that case you will also need to make PostgreSQL
105+
# listen on a non-local interface via the listen_addresses
106+
# configuration parameter, or via the -i or -h command line switches.
107+
108+
# CAUTION: Configuring the system for local "trust" authentication
109+
# allows any local user to connect as any PostgreSQL user, including
110+
# the database superuser. If you do not trust all your local users,
111+
# use another authentication method.
112+
113+
114+
# TYPE DATABASE USER ADDRESS METHOD
115+
116+
# "local" is for Unix domain socket connections only
117+
local all all trust
118+
# IPv4 local connections:
119+
hostssl all all 127.0.0.1/32 trust
120+
# IPv6 local connections:
121+
hostssl all all ::1/128 trust
122+
# Allow replication connections from localhost, by a user with the
123+
# replication privilege.
124+
local replication all trust
125+
host replication all 127.0.0.1/32 trust
126+
host replication all ::1/128 trust
127+
128+
hostssl all all all scram-sha-256

0 commit comments

Comments
 (0)