On 10/05/2024 16:50, Heikki Linnakangas wrote:
New proposal:
- Remove the "try both" mode completely, and rename "requiredirect" to
just "direct". So there would be just two modes: "postgres" and
"direct". On reflection, the automatic fallback mode doesn't seem very
useful. It would make sense as the default, because then you would get
the benefits automatically in most cases but still be compatible with
old servers. But if it's not the default, you have to fiddle with libpq
settings anyway to enable it, and then you might as well use the
"requiredirect" mode when you know the server supports it. There isn't
anything wrong with it as such, but given how much confusion there's
been on how this all works, I'd prefer to cut this back to the bare
minimum now. We can add it back in the future, and perhaps make it the
default at the same time. This addresses points 2. and 3. above.
and:
- Only allow sslnegotiation=direct with sslmode=require or higher. This
is what you, Jacob, wanted to do all along, and addresses point 1.
Here's a patch to implement that.
--
Heikki Linnakangas
Neon (https://neon.tech)
From 2a7bde8502966a634b62d4109f0cde5fdc685da2 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakan...@iki.fi>
Date: Mon, 13 May 2024 16:36:54 +0300
Subject: [PATCH 1/1] Remove option to fall back from direct to postgres SSL
negotiation
There were three problems with the sslnegotiation options:
1. The sslmode=prefer and sslnegotiation=requiredirect combination was
somewhat dangerous, as you might unintentionally fall back to
plaintext authentication when connecting to a pre-v17 server.
2. There was an asymmetry between 'postgres' and 'direct'
options. 'postgres' meant "try only traditional negotiation", while
'direct' meant "try direct first, and fall back to traditional
negotiation if it fails". That was apparent only if you knew that the
'requiredirect' mode also exists.
3. The "require" word in 'requiredirect' suggests that it's somehow
more strict or more secure, similar to sslmode. However, I don't
consider direct SSL connections to be a security feature.
To address these problems:
- Only allow sslnegotiation='direct' if sslmode='require' or
stronger. And for the record, Jacob and Robert felt that we should do
that (or have sslnegotiation='direct' imply sslmode='require') anyway,
regardless of the first issue.
- Remove the 'direct' mode that falls back to traditional negotiation,
and rename what was called 'requiredirect' to 'direct' instead. In
other words, there is no "try both methods" option anymore, 'postgres'
now means the traditional negotiation and 'direct' means a direct SSL
connection.
Discussion: https://www.postgresql.org/message-id/d3b1608a-a1b6-4eda-9ec5-ddb3e4375808%40iki.fi
---
doc/src/sgml/libpq.sgml | 49 ++--
src/interfaces/libpq/fe-connect.c | 52 ++--
src/interfaces/libpq/libpq-int.h | 3 +-
.../libpq/t/005_negotiate_encryption.pl | 254 ++++++++----------
4 files changed, 150 insertions(+), 208 deletions(-)
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 1d32c226d8..b32e497b1b 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1772,15 +1772,18 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>sslnegotiation</literal></term>
<listitem>
<para>
- This option controls whether <productname>PostgreSQL</productname>
- will perform its protocol negotiation to request encryption from the
- server or will just directly make a standard <acronym>SSL</acronym>
- connection. Traditional <productname>PostgreSQL</productname>
- protocol negotiation is the default and the most flexible with
- different server configurations. If the server is known to support
- direct <acronym>SSL</acronym> connections then the latter requires one
- fewer round trip reducing connection latency and also allows the use
- of protocol agnostic SSL network tools.
+ This option controls how SSL encryption is negotiated with the server,
+ if SSL is used. In the default <literal>postgres</literal> mode, the
+ client first asks the server if SSL is supported. In
+ <literal>direct</literal> mode, the client starts the standard SSL
+ handshake directly after establishing the TCP/IP connection. Traditional
+ <productname>PostgreSQL</productname> protocol negotiation is the most
+ flexible with different server configurations. If the server is known
+ to support direct <acronym>SSL</acronym> connections then the latter
+ requires one fewer round trip reducing connection latency and also
+ allows the use of protocol agnostic SSL network tools. The direct SSL
+ option was introduced in <productname>PostgreSQL</productname> version
+ 17.
</para>
<variablelist>
@@ -1798,32 +1801,14 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
<term><literal>direct</literal></term>
<listitem>
<para>
- first attempt to establish a standard SSL connection and if that
- fails reconnect and perform the negotiation. This fallback
- process adds significant latency if the initial SSL connection
- fails.
- </para>
- <para>
- An exception is if <literal>gssencmode</literal> is set
- to <literal>prefer</literal>, but the server rejects GSS encryption.
- In that case, SSL is negotiated over the same TCP connection using
- <productname>PostgreSQL</productname> protocol negotiation. In
- other words, the direct SSL handshake is not used, if a TCP
- connection has already been established and can be used for the
+ start SSL handshake directly after establishing the TCP/IP
+ connection. This is only allowed with sslmode=require or higher,
+ because the weaker settings could lead to unintended fallback to
+ plaintext authentication when the server does not support direct
SSL handshake.
</para>
</listitem>
</varlistentry>
-
- <varlistentry>
- <term><literal>requiredirect</literal></term>
- <listitem>
- <para>
- attempt to establish a standard SSL connection and if that fails
- return a connection failure immediately.
- </para>
- </listitem>
- </varlistentry>
</variablelist>
</listitem>
</varlistentry>
@@ -2064,7 +2049,7 @@ postgresql://%2Fvar%2Flib%2Fpostgresql/dbname
connections without having to decrypt the SSL stream. (Note that
unless the proxy is aware of the PostgreSQL protocol handshake this
would require setting <literal>sslnegotiation</literal>
- to <literal>direct</literal> or <literal>requiredirect</literal>.)
+ to <literal>direct</literal>.)
However, <acronym>SNI</acronym> makes the destination host name appear
in cleartext in the network traffic, so it might be undesirable in
some cases.
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 81d278c395..4a5a71de4b 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -274,7 +274,7 @@ static const internalPQconninfoOption PQconninfoOptions[] = {
offsetof(struct pg_conn, sslmode)},
{"sslnegotiation", "PGSSLNEGOTIATION", DefaultSSLNegotiation, NULL,
- "SSL-Negotiation", "", 14, /* sizeof("requiredirect") == 14 */
+ "SSL-Negotiation", "", 9, /* sizeof("postgres") == 9 */
offsetof(struct pg_conn, sslnegotiation)},
{"sslcompression", "PGSSLCOMPRESSION", "0", NULL,
@@ -1590,8 +1590,7 @@ pqConnectOptions2(PGconn *conn)
if (conn->sslnegotiation)
{
if (strcmp(conn->sslnegotiation, "postgres") != 0
- && strcmp(conn->sslnegotiation, "direct") != 0
- && strcmp(conn->sslnegotiation, "requiredirect") != 0)
+ && strcmp(conn->sslnegotiation, "direct") != 0)
{
conn->status = CONNECTION_BAD;
libpq_append_conn_error(conn, "invalid %s value: \"%s\"",
@@ -1608,6 +1607,25 @@ pqConnectOptions2(PGconn *conn)
return false;
}
#endif
+
+ /*
+ * Don't allow direct SSL negotiation with sslmode='prefer', because
+ * that poses a risk of unintentional fallback to plaintext connection
+ * when connecting to a pre-v17 server that does not support direct
+ * SSL connections. To keep things simple, don't allow it with
+ * sslmode='allow' or sslmode='disable' either. If a user goes through
+ * the trouble of setting sslnegotiation='direct', they probably
+ * intend to use SSL, and sslmode=disable or allow is probably a user
+ * user mistake anyway.
+ */
+ if (conn->sslnegotiation[0] == 'd' &&
+ conn->sslmode[0] != 'r' && conn->sslmode[0] != 'v')
+ {
+ conn->status = CONNECTION_BAD;
+ libpq_append_conn_error(conn, "weak sslmode \"%s\" may not be used with sslnegotiation=direct (use \"require\", \"verify-ca\", or \"verify-full\")",
+ conn->sslmode);
+ return false;
+ }
}
else
{
@@ -4312,8 +4330,6 @@ init_allowed_encryption_methods(PGconn *conn)
if (conn->sslnegotiation[0] == 'p')
conn->allowed_enc_methods |= ENC_NEGOTIATED_SSL;
else if (conn->sslnegotiation[0] == 'd')
- conn->allowed_enc_methods |= ENC_DIRECT_SSL | ENC_NEGOTIATED_SSL;
- else if (conn->sslnegotiation[0] == 'r')
conn->allowed_enc_methods |= ENC_DIRECT_SSL;
}
#endif
@@ -4376,18 +4392,6 @@ connection_failed(PGconn *conn)
Assert((conn->failed_enc_methods & conn->current_enc_method) == 0);
conn->failed_enc_methods |= conn->current_enc_method;
- /*
- * If the server reported an error after the SSL handshake, no point in
- * retrying with negotiated vs direct SSL.
- */
- if ((conn->current_enc_method & (ENC_DIRECT_SSL | ENC_NEGOTIATED_SSL)) != 0 &&
- conn->ssl_handshake_started)
- {
- conn->failed_enc_methods |= (ENC_DIRECT_SSL | ENC_NEGOTIATED_SSL) & conn->allowed_enc_methods;
- }
- else
- conn->failed_enc_methods |= conn->current_enc_method;
-
return select_next_encryption_method(conn, false);
}
@@ -4449,20 +4453,8 @@ select_next_encryption_method(PGconn *conn, bool have_valid_connection)
if (conn->sslmode[0] == 'a')
SELECT_NEXT_METHOD(ENC_PLAINTEXT);
- /*
- * If enabled, try direct SSL. Unless we have a valid TCP connection that
- * failed negotiating GSSAPI encryption; in that case we prefer to reuse
- * the connection with negotiated SSL, instead of reconnecting to do
- * direct SSL. The point of sslnegotiation=direct is to avoid the
- * roundtrip from the negotiation, but reconnecting would also incur a
- * roundtrip. (In sslnegotiation=requiredirect mode, negotiated SSL is not
- * in the list of allowed methods and we will reconnect.)
- */
- if (have_valid_connection)
- SELECT_NEXT_METHOD(ENC_NEGOTIATED_SSL);
-
- SELECT_NEXT_METHOD(ENC_DIRECT_SSL);
SELECT_NEXT_METHOD(ENC_NEGOTIATED_SSL);
+ SELECT_NEXT_METHOD(ENC_DIRECT_SSL);
if (conn->sslmode[0] != 'a')
SELECT_NEXT_METHOD(ENC_PLAINTEXT);
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 3691e5ee96..10d2709869 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -395,8 +395,7 @@ struct pg_conn
char *keepalives_count; /* maximum number of TCP keepalive
* retransmits */
char *sslmode; /* SSL mode (require,prefer,allow,disable) */
- char *sslnegotiation; /* SSL initiation style
- * (postgres,direct,requiredirect) */
+ char *sslnegotiation; /* SSL initiation style (postgres,direct) */
char *sslcompression; /* SSL compression (0 or 1) */
char *sslkey; /* client key filename */
char *sslcert; /* client certificate filename */
diff --git a/src/interfaces/libpq/t/005_negotiate_encryption.pl b/src/interfaces/libpq/t/005_negotiate_encryption.pl
index 03a9079f3f..36ba8aede8 100644
--- a/src/interfaces/libpq/t/005_negotiate_encryption.pl
+++ b/src/interfaces/libpq/t/005_negotiate_encryption.pl
@@ -209,7 +209,7 @@ $node->reload;
my @all_test_users = ('testuser', 'ssluser', 'nossluser', 'gssuser', 'nogssuser');
my @all_gssencmodes = ('disable', 'prefer', 'require');
my @all_sslmodes = ('disable', 'allow', 'prefer', 'require');
-my @all_sslnegotiations = ('postgres', 'direct', 'requiredirect');
+my @all_sslnegotiations = ('postgres', 'direct');
my $server_config = {
server_ssl => 0,
@@ -223,23 +223,22 @@ my $test_table;
if ($ssl_supported) {
$test_table = q{
# USER GSSENCMODE SSLMODE SSLNEGOTIATION EVENTS -> OUTCOME
-testuser disable disable * connect, authok -> plain
-. . allow * connect, authok -> plain
+testuser disable disable postgres connect, authok -> plain
+. . allow postgres connect, authok -> plain
. . prefer postgres connect, sslreject, authok -> plain
-. . . direct connect, directsslreject, reconnect, sslreject, authok -> plain
-. . . requiredirect connect, directsslreject, reconnect, authok -> plain
. . require postgres connect, sslreject -> fail
-. . . direct connect, directsslreject, reconnect, sslreject -> fail
-. . . requiredirect connect, directsslreject -> fail
-. prefer disable * connect, authok -> plain
-. . allow * connect, authok -> plain
+. . . direct connect, directsslreject -> fail
+. prefer disable postgres connect, authok -> plain
+. . allow postgres connect, authok -> plain
. . prefer postgres connect, sslreject, authok -> plain
-. . . direct connect, directsslreject, reconnect, sslreject, authok -> plain
-. . . requiredirect connect, directsslreject, reconnect, authok -> plain
. . require postgres connect, sslreject -> fail
-. . . direct connect, directsslreject, reconnect, sslreject -> fail
-. . . requiredirect connect, directsslreject -> fail
- };
+. . . direct connect, directsslreject -> fail
+
+# sslnegotiation=direct is not acccepted unless sslmode=require or stronger
+* * disable direct - -> fail
+* * allow direct - -> fail
+* * prefer direct - -> fail
+};
} else {
# Compiled without SSL support
$test_table = q{
@@ -251,11 +250,10 @@ testuser disable disable postgres connect, authok
. . allow postgres connect, authok -> plain
. . prefer postgres connect, authok -> plain
-# Without SSL support, sslmode=require and sslnegotiation=direct/requiredirect
-# are not accepted at all.
-. * require * - -> fail
-. * * direct - -> fail
-. * * requiredirect - -> fail
+# Without SSL support, sslmode=require and sslnegotiation=direct are
+# not accepted at all
+* * require * - -> fail
+* * * direct - -> fail
};
}
@@ -281,34 +279,26 @@ SKIP:
$test_table = q{
# USER GSSENCMODE SSLMODE SSLNEGOTIATION EVENTS -> OUTCOME
-testuser disable disable * connect, authok -> plain
-. . allow * connect, authok -> plain
+testuser disable disable postgres connect, authok -> plain
+. . allow postgres connect, authok -> plain
. . prefer postgres connect, sslaccept, authok -> ssl
-. . . direct connect, directsslaccept, authok -> ssl
-. . . requiredirect connect, directsslaccept, authok -> ssl
. . require postgres connect, sslaccept, authok -> ssl
. . . direct connect, directsslaccept, authok -> ssl
-. . . requiredirect connect, directsslaccept, authok -> ssl
-ssluser . disable * connect, authfail -> fail
+ssluser . disable postgres connect, authfail -> fail
. . allow postgres connect, authfail, reconnect, sslaccept, authok -> ssl
-. . . direct connect, authfail, reconnect, directsslaccept, authok -> ssl
-. . . requiredirect connect, authfail, reconnect, directsslaccept, authok -> ssl
. . prefer postgres connect, sslaccept, authok -> ssl
-. . . direct connect, directsslaccept, authok -> ssl
-. . . requiredirect connect, directsslaccept, authok -> ssl
. . require postgres connect, sslaccept, authok -> ssl
. . . direct connect, directsslaccept, authok -> ssl
-. . . requiredirect connect, directsslaccept, authok -> ssl
-nossluser . disable * connect, authok -> plain
+nossluser . disable postgres connect, authok -> plain
. . allow postgres connect, authok -> plain
-. . . direct connect, authok -> plain
-. . . requiredirect connect, authok -> plain
. . prefer postgres connect, sslaccept, authfail, reconnect, authok -> plain
-. . . direct connect, directsslaccept, authfail, reconnect, authok -> plain
-. . . requiredirect connect, directsslaccept, authfail, reconnect, authok -> plain
. . require postgres connect, sslaccept, authfail -> fail
. . require direct connect, directsslaccept, authfail -> fail
-. . require requiredirect connect, directsslaccept, authfail -> fail
+
+# sslnegotiation=direct is not acccepted unless sslmode=require or stronger
+* * disable direct - -> fail
+* * allow direct - -> fail
+* * prefer direct - -> fail
};
# Enable SSL in the server
@@ -342,62 +332,54 @@ SKIP:
$test_table = q{
# USER GSSENCMODE SSLMODE SSLNEGOTIATION EVENTS -> OUTCOME
-testuser disable disable * connect, authok -> plain
-. . allow * connect, authok -> plain
+testuser disable disable postgres connect, authok -> plain
+. . allow postgres connect, authok -> plain
. . prefer postgres connect, sslreject, authok -> plain
-. . . direct connect, directsslreject, reconnect, sslreject, authok -> plain
-. . . requiredirect connect, directsslreject, reconnect, authok -> plain
. . require postgres connect, sslreject -> fail
-. . . direct connect, directsslreject, reconnect, sslreject -> fail
-. . . requiredirect connect, directsslreject -> fail
-. prefer * * connect, gssaccept, authok -> gss
-. require * * connect, gssaccept, authok -> gss
+. . . direct connect, directsslreject -> fail
+. prefer * postgres connect, gssaccept, authok -> gss
+. prefer require direct connect, gssaccept, authok -> gss
+. require * postgres connect, gssaccept, authok -> gss
+. . require direct connect, gssaccept, authok -> gss
-gssuser disable disable * connect, authfail -> fail
+gssuser disable disable postgres connect, authfail -> fail
. . allow postgres connect, authfail, reconnect, sslreject -> fail
-. . . direct connect, authfail, reconnect, directsslreject, reconnect, sslreject -> fail
-. . . requiredirect connect, authfail, reconnect, directsslreject -> fail
. . prefer postgres connect, sslreject, authfail -> fail
-. . . direct connect, directsslreject, reconnect, sslreject, authfail -> fail
-. . . requiredirect connect, directsslreject, reconnect, authfail -> fail
. . require postgres connect, sslreject -> fail
-. . . direct connect, directsslreject, reconnect, sslreject -> fail
-. . . requiredirect connect, directsslreject -> fail
-. prefer * * connect, gssaccept, authok -> gss
-. require * * connect, gssaccept, authok -> gss
+. . . direct connect, directsslreject -> fail
+. prefer * postgres connect, gssaccept, authok -> gss
+. prefer require direct connect, gssaccept, authok -> gss
+. require * postgres connect, gssaccept, authok -> gss
+. . require direct connect, gssaccept, authok -> gss
-nogssuser disable disable * connect, authok -> plain
+nogssuser disable disable postgres connect, authok -> plain
. . allow postgres connect, authok -> plain
-. . . direct connect, authok -> plain
-. . . requiredirect connect, authok -> plain
. . prefer postgres connect, sslreject, authok -> plain
-. . . direct connect, directsslreject, reconnect, sslreject, authok -> plain
-. . . requiredirect connect, directsslreject, reconnect, authok -> plain
. . require postgres connect, sslreject -> fail
-. . . direct connect, directsslreject, reconnect, sslreject -> fail
-. . . requiredirect connect, directsslreject -> fail
-. prefer disable * connect, gssaccept, authfail, reconnect, authok -> plain
+. . . direct connect, directsslreject -> fail
+. prefer disable postgres connect, gssaccept, authfail, reconnect, authok -> plain
. . allow postgres connect, gssaccept, authfail, reconnect, authok -> plain
-. . . direct connect, gssaccept, authfail, reconnect, authok -> plain
-. . . requiredirect connect, gssaccept, authfail, reconnect, authok -> plain
. . prefer postgres connect, gssaccept, authfail, reconnect, sslreject, authok -> plain
-. . . direct connect, gssaccept, authfail, reconnect, directsslreject, reconnect, sslreject, authok -> plain
-. . . requiredirect connect, gssaccept, authfail, reconnect, directsslreject, reconnect, authok -> plain
. . require postgres connect, gssaccept, authfail, reconnect, sslreject -> fail
-. . . direct connect, gssaccept, authfail, reconnect, directsslreject, reconnect, sslreject -> fail
-. . . requiredirect connect, gssaccept, authfail, reconnect, directsslreject -> fail
-. require disable * connect, gssaccept, authfail -> fail
-. . allow * connect, gssaccept, authfail -> fail
-. . prefer * connect, gssaccept, authfail -> fail
-. . require * connect, gssaccept, authfail -> fail # If both GSSAPI and sslmode are required, and GSS is not available -> fail
+. . . direct connect, gssaccept, authfail, reconnect, directsslreject -> fail
+. require disable postgres connect, gssaccept, authfail -> fail
+. . allow postgres connect, gssaccept, authfail -> fail
+. . prefer postgres connect, gssaccept, authfail -> fail
+. . require postgres connect, gssaccept, authfail -> fail # If both GSSAPI and sslmode are required, and GSS is not available -> fail
+. . . direct connect, gssaccept, authfail -> fail # If both GSSAPI and sslmode are required, and GSS is not available -> fail
+
+# sslnegotiation=direct is not acccepted unless sslmode=require or stronger
+* * disable direct - -> fail
+* * allow direct - -> fail
+* * prefer direct - -> fail
};
# The expected events and outcomes above assume that SSL support
# is enabled. When libpq is compiled without SSL support, all
# attempts to connect with sslmode=require or
- # sslnegotiation=direct/requiredirect would fail immediately without
- # even connecting to the server. Skip those, because we tested
- # them earlier already.
+ # sslnegotiation=direct would fail immediately without even
+ # connecting to the server. Skip those, because we tested them
+ # earlier already.
my ($sslmodes, $sslnegotiations);
if ($ssl_supported != 0) {
($sslmodes, $sslnegotiations) = (\@all_sslmodes, \@all_sslnegotiations);
@@ -431,100 +413,84 @@ SKIP:
$test_table = q{
# USER GSSENCMODE SSLMODE SSLNEGOTIATION EVENTS -> OUTCOME
-testuser disable disable * connect, authok -> plain
-. . allow * connect, authok -> plain
-. . prefer postgres connect, sslaccept, authok -> ssl
-. . . direct connect, directsslaccept, authok -> ssl
-. . . requiredirect connect, directsslaccept, authok -> ssl
-. . require postgres connect, sslaccept, authok -> ssl
+testuser disable disable postgres connect, authok -> plain
+. . allow postgres connect, authok -> plain
+. . prefer postgres connect, sslaccept, authok -> ssl
+. . require postgres connect, sslaccept, authok -> ssl
. . . direct connect, directsslaccept, authok -> ssl
-. . . requiredirect connect, directsslaccept, authok -> ssl
-. prefer disable * connect, gssaccept, authok -> gss
-. . allow * connect, gssaccept, authok -> gss
-. . prefer * connect, gssaccept, authok -> gss
-. . require * connect, gssaccept, authok -> gss # If both GSS and SSL is possible, GSS is chosen over SSL, even if sslmode=require
-. require disable * connect, gssaccept, authok -> gss
-. . allow * connect, gssaccept, authok -> gss
-. . prefer * connect, gssaccept, authok -> gss
-. . require * connect, gssaccept, authok -> gss # If both GSS and SSL is possible, GSS is chosen over SSL, even if sslmode=require
-
-gssuser disable disable * connect, authfail -> fail
+. prefer disable postgres connect, gssaccept, authok -> gss
+. . allow postgres connect, gssaccept, authok -> gss
+. . prefer postgres connect, gssaccept, authok -> gss
+. . require postgres connect, gssaccept, authok -> gss # If both GSS and SSL is possible, GSS is chosen over SSL, even if sslmode=require
+. . . direct connect, gssaccept, authok -> gss
+. require disable postgres connect, gssaccept, authok -> gss
+. . allow postgres connect, gssaccept, authok -> gss
+. . prefer postgres connect, gssaccept, authok -> gss
+. . require postgres connect, gssaccept, authok -> gss # If both GSS and SSL is possible, GSS is chosen over SSL, even if sslmode=require
+. . . direct connect, gssaccept, authok -> gss
+
+gssuser disable disable postgres connect, authfail -> fail
. . allow postgres connect, authfail, reconnect, sslaccept, authfail -> fail
-. . . direct connect, authfail, reconnect, directsslaccept, authfail -> fail
-. . . requiredirect connect, authfail, reconnect, directsslaccept, authfail -> fail
. . prefer postgres connect, sslaccept, authfail, reconnect, authfail -> fail
-. . . direct connect, directsslaccept, authfail, reconnect, authfail -> fail
-. . . requiredirect connect, directsslaccept, authfail, reconnect, authfail -> fail
. . require postgres connect, sslaccept, authfail -> fail
. . . direct connect, directsslaccept, authfail -> fail
-. . . requiredirect connect, directsslaccept, authfail -> fail
-. prefer disable * connect, gssaccept, authok -> gss
-. . allow * connect, gssaccept, authok -> gss
-. . prefer * connect, gssaccept, authok -> gss
-. . require * connect, gssaccept, authok -> gss # GSS is chosen over SSL, even though sslmode=require
-. require disable * connect, gssaccept, authok -> gss
-. . allow * connect, gssaccept, authok -> gss
-. . prefer * connect, gssaccept, authok -> gss
-. . require * connect, gssaccept, authok -> gss # If both GSS and SSL is possible, GSS is chosen over SSL, even if sslmode=require
-
-ssluser disable disable * connect, authfail -> fail
+. prefer disable postgres connect, gssaccept, authok -> gss
+. . allow postgres connect, gssaccept, authok -> gss
+. . prefer postgres connect, gssaccept, authok -> gss
+. . require postgres connect, gssaccept, authok -> gss # GSS is chosen over SSL, even though sslmode=require
+. . . direct connect, gssaccept, authok -> gss
+. require disable postgres connect, gssaccept, authok -> gss
+. . allow postgres connect, gssaccept, authok -> gss
+. . prefer postgres connect, gssaccept, authok -> gss
+. . require postgres connect, gssaccept, authok -> gss # If both GSS and SSL is possible, GSS is chosen over SSL, even if sslmode=require
+. . . direct connect, gssaccept, authok -> gss
+
+ssluser disable disable postgres connect, authfail -> fail
. . allow postgres connect, authfail, reconnect, sslaccept, authok -> ssl
-. . . direct connect, authfail, reconnect, directsslaccept, authok -> ssl
-. . . requiredirect connect, authfail, reconnect, directsslaccept, authok -> ssl
. . prefer postgres connect, sslaccept, authok -> ssl
-. . . direct connect, directsslaccept, authok -> ssl
-. . . requiredirect connect, directsslaccept, authok -> ssl
. . require postgres connect, sslaccept, authok -> ssl
. . . direct connect, directsslaccept, authok -> ssl
-. . . requiredirect connect, directsslaccept, authok -> ssl
-. prefer disable * connect, gssaccept, authfail, reconnect, authfail -> fail
+. prefer disable postgres connect, gssaccept, authfail, reconnect, authfail -> fail
. . allow postgres connect, gssaccept, authfail, reconnect, authfail, reconnect, sslaccept, authok -> ssl
-. . . direct connect, gssaccept, authfail, reconnect, authfail, reconnect, directsslaccept, authok -> ssl
-. . . requiredirect connect, gssaccept, authfail, reconnect, authfail, reconnect, directsslaccept, authok -> ssl
. . prefer postgres connect, gssaccept, authfail, reconnect, sslaccept, authok -> ssl
-. . . direct connect, gssaccept, authfail, reconnect, directsslaccept, authok -> ssl
-. . . requiredirect connect, gssaccept, authfail, reconnect, directsslaccept, authok -> ssl
. . require postgres connect, gssaccept, authfail, reconnect, sslaccept, authok -> ssl
. . . direct connect, gssaccept, authfail, reconnect, directsslaccept, authok -> ssl
-. . . requiredirect connect, gssaccept, authfail, reconnect, directsslaccept, authok -> ssl
-. require disable * connect, gssaccept, authfail -> fail
-. . allow * connect, gssaccept, authfail -> fail
-. . prefer * connect, gssaccept, authfail -> fail
-. . require * connect, gssaccept, authfail -> fail # If both GSS and SSL are required, the sslmode=require is effectively ignored and GSS is required
+. require disable postgres connect, gssaccept, authfail -> fail
+. . allow postgres connect, gssaccept, authfail -> fail
+. . prefer postgres connect, gssaccept, authfail -> fail
+. . require postgres connect, gssaccept, authfail -> fail # If both GSS and SSL are required, the sslmode=require is effectively ignored and GSS is required
+. . . direct connect, gssaccept, authfail -> fail
-nogssuser disable disable * connect, authok -> plain
+nogssuser disable disable postgres connect, authok -> plain
. . allow postgres connect, authok -> plain
-. . . direct connect, authok -> plain
-. . . requiredirect connect, authok -> plain
. . prefer postgres connect, sslaccept, authok -> ssl
-. . . direct connect, directsslaccept, authok -> ssl
-. . . requiredirect connect, directsslaccept, authok -> ssl
. . require postgres connect, sslaccept, authok -> ssl
. . . direct connect, directsslaccept, authok -> ssl
-. . . requiredirect connect, directsslaccept, authok -> ssl
-. prefer disable * connect, gssaccept, authfail, reconnect, authok -> plain
-. . allow * connect, gssaccept, authfail, reconnect, authok -> plain
+. prefer disable postgres connect, gssaccept, authfail, reconnect, authok -> plain
+. . allow postgres connect, gssaccept, authfail, reconnect, authok -> plain
. . prefer postgres connect, gssaccept, authfail, reconnect, sslaccept, authok -> ssl
-. . . direct connect, gssaccept, authfail, reconnect, directsslaccept, authok -> ssl
-. . . requiredirect connect, gssaccept, authfail, reconnect, directsslaccept, authok -> ssl
. . require postgres connect, gssaccept, authfail, reconnect, sslaccept, authok -> ssl
. . . direct connect, gssaccept, authfail, reconnect, directsslaccept, authok -> ssl
-. . . requiredirect connect, gssaccept, authfail, reconnect, directsslaccept, authok -> ssl
-. require disable * connect, gssaccept, authfail -> fail
-. . allow * connect, gssaccept, authfail -> fail
-. . prefer * connect, gssaccept, authfail -> fail
-. . require * connect, gssaccept, authfail -> fail # If both GSS and SSL are required, the sslmode=require is effectively ignored and GSS is required
-
-nossluser disable disable * connect, authok -> plain
-. . allow * connect, authok -> plain
+. require disable postgres connect, gssaccept, authfail -> fail
+. . allow postgres connect, gssaccept, authfail -> fail
+. . prefer postgres connect, gssaccept, authfail -> fail
+. . require postgres connect, gssaccept, authfail -> fail # If both GSS and SSL are required, the sslmode=require is effectively ignored and GSS is required
+. . . direct connect, gssaccept, authfail -> fail
+
+nossluser disable disable postgres connect, authok -> plain
+. . allow postgres connect, authok -> plain
. . prefer postgres connect, sslaccept, authfail, reconnect, authok -> plain
-. . . direct connect, directsslaccept, authfail, reconnect, authok -> plain
-. . . requiredirect connect, directsslaccept, authfail, reconnect, authok -> plain
. . require postgres connect, sslaccept, authfail -> fail
. . . direct connect, directsslaccept, authfail -> fail
-. . . requiredirect connect, directsslaccept, authfail -> fail
-. prefer * * connect, gssaccept, authok -> gss
-. require * * connect, gssaccept, authok -> gss
+. prefer * postgres connect, gssaccept, authok -> gss
+. . require direct connect, gssaccept, authok -> gss
+. require * postgres connect, gssaccept, authok -> gss
+. . require direct connect, gssaccept, authok -> gss
+
+# sslnegotiation=direct is not acccepted unless sslmode=require or stronger
+* * disable direct - -> fail
+* * allow direct - -> fail
+* * prefer direct - -> fail
};
note("Running tests with both GSS and SSL enabled in server");
--
2.39.2