aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/src/sgml/libpq.sgml49
-rw-r--r--src/interfaces/libpq/fe-connect.c142
-rw-r--r--src/interfaces/libpq/fe-secure-openssl.c2
-rw-r--r--src/interfaces/libpq/libpq-int.h6
-rw-r--r--src/interfaces/libpq/t/005_negotiate_encryption.pl254
5 files changed, 200 insertions, 253 deletions
diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index 74b6ed0cf97..80179f99783 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -1773,15 +1773,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>
@@ -1799,32 +1802,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>
@@ -2065,7 +2050,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 81d278c3950..a6b75ad6ac8 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
{
@@ -3347,42 +3365,45 @@ keep_going: /* We will come back to here until there is
goto error_return;
/*
- * If direct SSL is enabled, jump right into SSL handshake. We
- * will come back here after SSL encryption has been
- * established, with ssl_in_use set.
+ * If SSL is enabled, start the SSL negotiation. We will come
+ * back here after SSL encryption has been established, with
+ * ssl_in_use set.
*/
- if (conn->current_enc_method == ENC_DIRECT_SSL && !conn->ssl_in_use)
+ if (conn->current_enc_method == ENC_SSL && !conn->ssl_in_use)
{
- conn->status = CONNECTION_SSL_STARTUP;
- return PGRES_POLLING_WRITING;
- }
-
- /*
- * If negotiated SSL is enabled, request SSL and proceed with
- * SSL handshake. We will come back here after SSL encryption
- * has been established, with ssl_in_use set.
- */
- if (conn->current_enc_method == ENC_NEGOTIATED_SSL && !conn->ssl_in_use)
- {
- ProtocolVersion pv;
-
/*
- * Send the SSL request packet.
- *
- * Theoretically, this could block, but it really
- * shouldn't since we only got here if the socket is
- * write-ready.
+ * If traditional postgres SSL negotiation is used, send
+ * the SSL request. In direct negotiation, jump straight
+ * into the SSL handshake.
*/
- pv = pg_hton32(NEGOTIATE_SSL_CODE);
- if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
+ if (conn->sslnegotiation[0] == 'p')
{
- libpq_append_conn_error(conn, "could not send SSL negotiation packet: %s",
- SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
- goto error_return;
+ ProtocolVersion pv;
+
+ /*
+ * Send the SSL request packet.
+ *
+ * Theoretically, this could block, but it really
+ * shouldn't since we only got here if the socket is
+ * write-ready.
+ */
+ pv = pg_hton32(NEGOTIATE_SSL_CODE);
+ if (pqPacketSend(conn, 0, &pv, sizeof(pv)) != STATUS_OK)
+ {
+ libpq_append_conn_error(conn, "could not send SSL negotiation packet: %s",
+ SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
+ goto error_return;
+ }
+ /* Ok, wait for response */
+ conn->status = CONNECTION_SSL_STARTUP;
+ return PGRES_POLLING_READING;
+ }
+ else
+ {
+ Assert(conn->sslnegotiation[0] == 'd');
+ conn->status = CONNECTION_SSL_STARTUP;
+ return PGRES_POLLING_WRITING;
}
- /* Ok, wait for response */
- conn->status = CONNECTION_SSL_STARTUP;
- return PGRES_POLLING_READING;
}
#endif /* USE_SSL */
@@ -3453,11 +3474,11 @@ keep_going: /* We will come back to here until there is
PostgresPollingStatusType pollres;
/*
- * On first time through, get the postmaster's response to our
- * SSL negotiation packet. If we are trying a direct ssl
- * connection, go straight to initiating ssl.
+ * On first time through with traditional SSL negotiation, get
+ * the postmaster's response to our SSLRequest packet. With
+ * sslnegotiation='direct', go straight to initiating SSL.
*/
- if (!conn->ssl_in_use && conn->current_enc_method == ENC_NEGOTIATED_SSL)
+ if (!conn->ssl_in_use && conn->sslnegotiation[0] == 'p')
{
/*
* We use pqReadData here since it has the logic to
@@ -4282,7 +4303,7 @@ init_allowed_encryption_methods(PGconn *conn)
if (conn->raddr.addr.ss_family == AF_UNIX)
{
/* Don't request SSL or GSSAPI over Unix sockets */
- conn->allowed_enc_methods &= ~(ENC_DIRECT_SSL | ENC_NEGOTIATED_SSL | ENC_GSSAPI);
+ conn->allowed_enc_methods &= ~(ENC_SSL | ENC_GSSAPI);
/*
* XXX: we probably should not do this. sslmode=require works
@@ -4309,12 +4330,7 @@ init_allowed_encryption_methods(PGconn *conn)
/* sslmode anything but 'disable', and GSSAPI not required */
if (conn->sslmode[0] != 'd' && conn->gssencmode[0] != 'r')
{
- 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;
+ conn->allowed_enc_methods |= ENC_SSL;
}
#endif
@@ -4354,7 +4370,8 @@ encryption_negotiation_failed(PGconn *conn)
if (select_next_encryption_method(conn, true))
{
- if (conn->current_enc_method == ENC_DIRECT_SSL)
+ /* An existing connection cannot be reused for direct SSL */
+ if (conn->current_enc_method == ENC_SSL && conn->sslnegotiation[0] == 'd')
return 2;
else
return 1;
@@ -4376,18 +4393,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);
}
@@ -4445,24 +4450,17 @@ select_next_encryption_method(PGconn *conn, bool have_valid_connection)
SELECT_NEXT_METHOD(ENC_GSSAPI);
#endif
- /* With sslmode=allow, try plaintext connection before SSL. */
- 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.)
+ * The order between SSL encryption and plaintext depends on sslmode. With
+ * sslmode=allow, try plaintext connection before SSL. With
+ * sslmode=prefer, it's the other way round. With other modes, we only try
+ * plaintext or SSL connections so the order they're listed here doesn't
+ * matter.
*/
- if (have_valid_connection)
- SELECT_NEXT_METHOD(ENC_NEGOTIATED_SSL);
+ if (conn->sslmode[0] == 'a')
+ SELECT_NEXT_METHOD(ENC_PLAINTEXT);
- SELECT_NEXT_METHOD(ENC_DIRECT_SSL);
- SELECT_NEXT_METHOD(ENC_NEGOTIATED_SSL);
+ SELECT_NEXT_METHOD(ENC_SSL);
if (conn->sslmode[0] != 'a')
SELECT_NEXT_METHOD(ENC_PLAINTEXT);
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index fb6bb911f52..bf9dfbf918f 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1586,7 +1586,7 @@ open_client_SSL(PGconn *conn)
}
/* ALPN is mandatory with direct SSL connections */
- if (conn->current_enc_method == ENC_DIRECT_SSL)
+ if (conn->current_enc_method == ENC_SSL && conn->sslnegotiation[0] == 'd')
{
const unsigned char *selected;
unsigned int len;
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 3691e5ee969..3886204c708 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -235,8 +235,7 @@ typedef enum
#define ENC_ERROR 0
#define ENC_PLAINTEXT 0x01
#define ENC_GSSAPI 0x02
-#define ENC_DIRECT_SSL 0x04
-#define ENC_NEGOTIATED_SSL 0x08
+#define ENC_SSL 0x04
/* Target server type (decoded value of target_session_attrs) */
typedef enum
@@ -395,8 +394,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 bc19cd244b2..c3f70d31bc8 100644
--- a/src/interfaces/libpq/t/005_negotiate_encryption.pl
+++ b/src/interfaces/libpq/t/005_negotiate_encryption.pl
@@ -213,7 +213,7 @@ 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,
@@ -228,23 +228,22 @@ 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
{
@@ -258,11 +257,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
};
}
@@ -288,34 +286,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
@@ -350,62 +340,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)
{
@@ -445,100 +427,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");