Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb63dd3d

Browse files
committed
Add hints about protocol-version-related SSL connection failures.
OpenSSL's native reports about problems related to protocol versionrestrictions are pretty opaque and inconsistent. When we get anSSL error that is plausibly due to this, emit a hint message thatincludes the range of SSL protocol versions we (think we) areallowing. This should at least get the user thinking in the rightdirection to resolve the problem, even if the hint isn't totallyaccurate, which it might not be for assorted reasons.Back-patch to v13 where we increased the default minimum protocolversion, thereby increasing the risk of this class of failure.Patch by me, reviewed by Daniel GustafssonDiscussion:https://postgr.es/m/a9408304-4381-a5af-d259-e55d349ae4ce@2ndquadrant.com
1 parent6e682f6 commitb63dd3d

File tree

3 files changed

+127
-2
lines changed

3 files changed

+127
-2
lines changed

‎src/backend/libpq/be-secure-openssl.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ static bool dummy_ssl_passwd_cb_called = false;
7272
staticboolssl_is_server_start;
7373

7474
staticintssl_protocol_version_to_openssl(intv);
75+
staticconstchar*ssl_protocol_version_to_string(intv);
7576

7677
/* ------------------------------------------------------------ */
7778
/* Public interface*/
@@ -365,6 +366,7 @@ be_tls_open_server(Port *port)
365366
interr;
366367
intwaitfor;
367368
unsigned longecode;
369+
boolgive_proto_hint;
368370

369371
Assert(!port->ssl);
370372
Assert(!port->peer);
@@ -451,10 +453,50 @@ be_tls_open_server(Port *port)
451453
errmsg("could not accept SSL connection: EOF detected")));
452454
break;
453455
caseSSL_ERROR_SSL:
456+
switch (ERR_GET_REASON(ecode))
457+
{
458+
/*
459+
* UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
460+
* TLSV1_ALERT_PROTOCOL_VERSION have been observed
461+
* when trying to communicate with an old OpenSSL
462+
* library, or when the client and server specify
463+
* disjoint protocol ranges. NO_PROTOCOLS_AVAILABLE
464+
* occurs if there's a local misconfiguration (which
465+
* can happen despite our checks, if openssl.cnf
466+
* injects a limit we didn't account for). It's not
467+
* very clear what would make OpenSSL return the other
468+
* codes listed here, but a hint about protocol
469+
* versions seems like it's appropriate for all.
470+
*/
471+
caseSSL_R_NO_PROTOCOLS_AVAILABLE:
472+
caseSSL_R_UNSUPPORTED_PROTOCOL:
473+
caseSSL_R_BAD_PROTOCOL_VERSION_NUMBER:
474+
caseSSL_R_UNKNOWN_PROTOCOL:
475+
caseSSL_R_UNKNOWN_SSL_VERSION:
476+
caseSSL_R_UNSUPPORTED_SSL_VERSION:
477+
caseSSL_R_VERSION_TOO_HIGH:
478+
caseSSL_R_VERSION_TOO_LOW:
479+
caseSSL_R_WRONG_SSL_VERSION:
480+
caseSSL_R_WRONG_VERSION_NUMBER:
481+
caseSSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
482+
give_proto_hint= true;
483+
break;
484+
default:
485+
give_proto_hint= false;
486+
break;
487+
}
454488
ereport(COMMERROR,
455489
(errcode(ERRCODE_PROTOCOL_VIOLATION),
456490
errmsg("could not accept SSL connection: %s",
457-
SSLerrmessage(ecode))));
491+
SSLerrmessage(ecode)),
492+
give_proto_hint ?
493+
errhint("This may indicate that the client does not support any SSL protocol version between %s and %s.",
494+
ssl_min_protocol_version ?
495+
ssl_protocol_version_to_string(ssl_min_protocol_version) :
496+
MIN_OPENSSL_TLS_VERSION,
497+
ssl_max_protocol_version ?
498+
ssl_protocol_version_to_string(ssl_max_protocol_version) :
499+
MAX_OPENSSL_TLS_VERSION) :0));
458500
break;
459501
caseSSL_ERROR_ZERO_RETURN:
460502
ereport(COMMERROR,
@@ -1328,6 +1370,29 @@ ssl_protocol_version_to_openssl(int v)
13281370
return-1;
13291371
}
13301372

1373+
/*
1374+
* Likewise provide a mapping to strings.
1375+
*/
1376+
staticconstchar*
1377+
ssl_protocol_version_to_string(intv)
1378+
{
1379+
switch (v)
1380+
{
1381+
casePG_TLS_ANY:
1382+
return"any";
1383+
casePG_TLS1_VERSION:
1384+
return"TLSv1";
1385+
casePG_TLS1_1_VERSION:
1386+
return"TLSv1.1";
1387+
casePG_TLS1_2_VERSION:
1388+
return"TLSv1.2";
1389+
casePG_TLS1_3_VERSION:
1390+
return"TLSv1.3";
1391+
}
1392+
1393+
return"(unrecognized)";
1394+
}
1395+
13311396

13321397
staticvoid
13331398
default_openssl_tls_init(SSL_CTX*context,boolisServerStart)

‎src/include/common/openssl.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,33 @@
1717
#ifdefUSE_OPENSSL
1818
#include<openssl/ssl.h>
1919

20+
/*
21+
* OpenSSL doesn't provide any very nice way to identify the min/max
22+
* protocol versions the library supports, so we fake it as best we can.
23+
* Note in particular that this doesn't account for restrictions that
24+
* might be specified in the installation's openssl.cnf.
25+
*
26+
* We disable SSLv3 and older in library setup, so TLSv1 is the oldest
27+
* protocol version of interest.
28+
*/
29+
#defineMIN_OPENSSL_TLS_VERSION "TLSv1"
30+
31+
#if defined(TLS1_3_VERSION)
32+
#defineMAX_OPENSSL_TLS_VERSION "TLSv1.3"
33+
#elif defined(TLS1_2_VERSION)
34+
#defineMAX_OPENSSL_TLS_VERSION "TLSv1.2"
35+
#elif defined(TLS1_1_VERSION)
36+
#defineMAX_OPENSSL_TLS_VERSION "TLSv1.1"
37+
#else
38+
#defineMAX_OPENSSL_TLS_VERSION "TLSv1"
39+
#endif
40+
2041
/* src/common/protocol_openssl.c */
2142
#ifndefSSL_CTX_set_min_proto_version
2243
externintSSL_CTX_set_min_proto_version(SSL_CTX*ctx,intversion);
2344
externintSSL_CTX_set_max_proto_version(SSL_CTX*ctx,intversion);
2445
#endif
2546

26-
#endif
47+
#endif/* USE_OPENSSL */
2748

2849
#endif/* COMMON_OPENSSL_H */

‎src/interfaces/libpq/fe-secure-openssl.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,6 +1304,45 @@ open_client_SSL(PGconn *conn)
13041304
libpq_gettext("SSL error: %s\n"),
13051305
err);
13061306
SSLerrfree(err);
1307+
switch (ERR_GET_REASON(ecode))
1308+
{
1309+
/*
1310+
* UNSUPPORTED_PROTOCOL, WRONG_VERSION_NUMBER, and
1311+
* TLSV1_ALERT_PROTOCOL_VERSION have been observed
1312+
* when trying to communicate with an old OpenSSL
1313+
* library, or when the client and server specify
1314+
* disjoint protocol ranges.
1315+
* NO_PROTOCOLS_AVAILABLE occurs if there's a
1316+
* local misconfiguration (which can happen
1317+
* despite our checks, if openssl.cnf injects a
1318+
* limit we didn't account for). It's not very
1319+
* clear what would make OpenSSL return the other
1320+
* codes listed here, but a hint about protocol
1321+
* versions seems like it's appropriate for all.
1322+
*/
1323+
caseSSL_R_NO_PROTOCOLS_AVAILABLE:
1324+
caseSSL_R_UNSUPPORTED_PROTOCOL:
1325+
caseSSL_R_BAD_PROTOCOL_VERSION_NUMBER:
1326+
caseSSL_R_UNKNOWN_PROTOCOL:
1327+
caseSSL_R_UNKNOWN_SSL_VERSION:
1328+
caseSSL_R_UNSUPPORTED_SSL_VERSION:
1329+
caseSSL_R_VERSION_TOO_HIGH:
1330+
caseSSL_R_VERSION_TOO_LOW:
1331+
caseSSL_R_WRONG_SSL_VERSION:
1332+
caseSSL_R_WRONG_VERSION_NUMBER:
1333+
caseSSL_R_TLSV1_ALERT_PROTOCOL_VERSION:
1334+
appendPQExpBuffer(&conn->errorMessage,
1335+
libpq_gettext("This may indicate that the server does not support any SSL protocol version between %s and %s.\n"),
1336+
conn->ssl_min_protocol_version ?
1337+
conn->ssl_min_protocol_version :
1338+
MIN_OPENSSL_TLS_VERSION,
1339+
conn->ssl_max_protocol_version ?
1340+
conn->ssl_max_protocol_version :
1341+
MAX_OPENSSL_TLS_VERSION);
1342+
break;
1343+
default:
1344+
break;
1345+
}
13071346
pgtls_close(conn);
13081347
returnPGRES_POLLING_FAILED;
13091348
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp