pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Tom Lane <tgl@sss.pgh.pa.us>
To: Daniel Gustafsson <daniel@yesql.se>
Cc: Magnus Hagander <magnus@hagander.net>
Cc: Peter Eisentraut <peter.eisentraut@2ndquadrant.com>
Cc: pgsql-hackers <pgsql-hackers@postgresql.org>
Subject: Re: should libpq also require TLSv1.2 by default?
Date: Fri, 26 Jun 2020 11:36:42 -0400
Message-ID: <16724.1593185802@sss.pgh.pa.us> (raw)
In-Reply-To: <2339796.1593177583@sss.pgh.pa.us>
References: <a9408304-4381-a5af-d259-e55d349ae4ce@2ndquadrant.com>
	<4FBC50DB-599A-42AA-90C8-3051E3A748BB@yesql.se>
	<CABUevEzn3BH0y+ToD8jkXkXmSvRSA7tAX4v+16M4fSr4fJDH4A@mail.gmail.com>
	<DF11E406-A9AB-43A6-9B0E-5291644CC16F@yesql.se>
	<2305871.1593125045@sss.pgh.pa.us>
	<F50C22DD-A2C0-461A-93CD-3B87847F8F82@yesql.se>
	<2339796.1593177583@sss.pgh.pa.us>

Here is a quick attempt at getting libpq and the server to report
suitable hint messages about SSL version problems.

The main thing I don't like about this as formulated is that I hard-wired
knowledge of the minimum and maximum SSL versions into the hint messages.
That's clearly not very maintainable, but it seems really hard to keep the
messages readable/useful without giving concrete version numbers.
Anybdy have a better idea?  Is there a reasonably direct way to ask
OpenSSL what its min and max versions are?

			regards, tom lane

Attachments:

ssl-protocol-version-hints-1.patch (text/x-diff, 4.8K) download diff --git a/src/backend/libpq/be-secure-openssl.c b/src/backend/libpq/be-secure-openssl.c index 8adf64c78e..380268636a 100644 --- a/src/backend/libpq/be-secure-openssl.c +++ b/src/backend/libpq/be-secure-openssl.c @@ -72,6 +72,7 @@ static bool dummy_ssl_passwd_cb_called = false; static bool ssl_is_server_start; static int ssl_protocol_version_to_openssl(int v); +static const char *ssl_protocol_version_to_string(int v); /* ------------------------------------------------------------ */ /* Public interface */ @@ -365,6 +366,7 @@ be_tls_open_server(Port *port) int err; int waitfor; unsigned long ecode; + bool give_proto_hint; Assert(!port->ssl); Assert(!port->peer); @@ -451,10 +453,44 @@ aloop: errmsg("could not accept SSL connection: EOF detected"))); break; case SSL_ERROR_SSL: + switch (ERR_GET_REASON(ecode)) + { + /* + * NO_PROTOCOLS_AVAILABLE occurs if the client and + * server min/max protocol version limits don't + * overlap. UNSUPPORTED_PROTOCOL and + * WRONG_VERSION_NUMBER have been observed when trying + * to communicate with an old OpenSSL library. It's + * not very clear what would make OpenSSL return the + * other codes listed here, but a hint about protocol + * versions seems like it's appropriate for all. + */ + case SSL_R_NO_PROTOCOLS_AVAILABLE: + case SSL_R_UNSUPPORTED_PROTOCOL: + case SSL_R_BAD_PROTOCOL_VERSION_NUMBER: + case SSL_R_UNKNOWN_SSL_VERSION: + case SSL_R_UNSUPPORTED_SSL_VERSION: + case SSL_R_VERSION_TOO_HIGH: + case SSL_R_VERSION_TOO_LOW: + case SSL_R_WRONG_SSL_VERSION: + case SSL_R_WRONG_VERSION_NUMBER: + give_proto_hint = true; + break; + default: + give_proto_hint = false; + break; + } ereport(COMMERROR, (errcode(ERRCODE_PROTOCOL_VIOLATION), errmsg("could not accept SSL connection: %s", - SSLerrmessage(ecode)))); + SSLerrmessage(ecode)), + give_proto_hint ? errhint("This may indicate that the client does not support any SSL protocol version between %s and %s.", + ssl_min_protocol_version ? + ssl_protocol_version_to_string(ssl_min_protocol_version) : + "TLSv1", + ssl_max_protocol_version ? + ssl_protocol_version_to_string(ssl_max_protocol_version) : + "TLSv1.3") : 0)); break; case SSL_ERROR_ZERO_RETURN: ereport(COMMERROR, @@ -1328,6 +1364,29 @@ ssl_protocol_version_to_openssl(int v) return -1; } +/* + * Likewise provide a mapping to strings. + */ +static const char * +ssl_protocol_version_to_string(int v) +{ + switch (v) + { + case PG_TLS_ANY: + return "any"; + case PG_TLS1_VERSION: + return "TLSv1"; + case PG_TLS1_1_VERSION: + return "TLSv1.1"; + case PG_TLS1_2_VERSION: + return "TLSv1.2"; + case PG_TLS1_3_VERSION: + return "TLSv1.3"; + } + + return "(unrecognized)"; +} + static void default_openssl_tls_init(SSL_CTX *context, bool isServerStart) diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c index 2d813ef5f9..71407bffd4 100644 --- a/src/interfaces/libpq/fe-secure-openssl.c +++ b/src/interfaces/libpq/fe-secure-openssl.c @@ -1304,6 +1304,40 @@ open_client_SSL(PGconn *conn) libpq_gettext("SSL error: %s\n"), err); SSLerrfree(err); + switch (ERR_GET_REASON(ecode)) + { + /* + * NO_PROTOCOLS_AVAILABLE occurs if the client and + * server min/max protocol version limits don't + * overlap. UNSUPPORTED_PROTOCOL and + * WRONG_VERSION_NUMBER have been observed when + * trying to communicate with an old OpenSSL + * library. It's not very clear what would make + * OpenSSL return the other codes listed here, but + * a hint about protocol versions seems like it's + * appropriate for all. + */ + case SSL_R_NO_PROTOCOLS_AVAILABLE: + case SSL_R_UNSUPPORTED_PROTOCOL: + case SSL_R_BAD_PROTOCOL_VERSION_NUMBER: + case SSL_R_UNKNOWN_SSL_VERSION: + case SSL_R_UNSUPPORTED_SSL_VERSION: + case SSL_R_VERSION_TOO_HIGH: + case SSL_R_VERSION_TOO_LOW: + case SSL_R_WRONG_SSL_VERSION: + case SSL_R_WRONG_VERSION_NUMBER: + appendPQExpBuffer(&conn->errorMessage, + libpq_gettext("This may indicate that the server does not support any SSL protocol version between %s and %s.\n"), + conn->ssl_min_protocol_version ? + conn->ssl_min_protocol_version : + "TLSv1", + conn->ssl_max_protocol_version ? + conn->ssl_max_protocol_version : + "TLSv1.3"); + break; + default: + break; + } pgtls_close(conn); return PGRES_POLLING_FAILED; }

view thread (21+ messages)  latest in thread

Message-ID: <16724.1593185802@sss.pgh.pa.us>
Permalink:  ../16724.1593185802@sss.pgh.pa.us/
Also on:    postgresql.org/message-id/16724.1593185802@sss.pgh.pa.us

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-hackers@postgresql.org
  Cc: tgl@sss.pgh.pa.us, daniel@yesql.se, magnus@hagander.net, peter.eisentraut@2ndquadrant.com
  Subject: Re: should libpq also require TLSv1.2 by default?
  In-Reply-To: <16724.1593185802@sss.pgh.pa.us>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox