@ -72,6 +72,7 @@ static bool dummy_ssl_passwd_cb_called = false;
static bool ssl_is_server_start ;
static bool ssl_is_server_start ;
static int ssl_protocol_version_to_openssl ( int v ) ;
static int ssl_protocol_version_to_openssl ( int v ) ;
static const char * ssl_protocol_version_to_string ( int v ) ;
/* ------------------------------------------------------------ */
/* ------------------------------------------------------------ */
/* Public interface */
/* Public interface */
@ -365,6 +366,7 @@ be_tls_open_server(Port *port)
int err ;
int err ;
int waitfor ;
int waitfor ;
unsigned long ecode ;
unsigned long ecode ;
bool give_proto_hint ;
Assert ( ! port - > ssl ) ;
Assert ( ! port - > ssl ) ;
Assert ( ! port - > peer ) ;
Assert ( ! port - > peer ) ;
@ -451,10 +453,50 @@ aloop:
errmsg ( " could not accept SSL connection: EOF detected " ) ) ) ;
errmsg ( " could not accept SSL connection: EOF detected " ) ) ) ;
break ;
break ;
case SSL_ERROR_SSL :
case SSL_ERROR_SSL :
switch ( ERR_GET_REASON ( ecode ) )
{
/*
* UNSUPPORTED_PROTOCOL , WRONG_VERSION_NUMBER , and
* TLSV1_ALERT_PROTOCOL_VERSION have been observed
* when trying to communicate with an old OpenSSL
* library , or when the client and server specify
* disjoint protocol ranges . NO_PROTOCOLS_AVAILABLE
* occurs if there ' s a local misconfiguration ( which
* can happen despite our checks , if openssl . cnf
* injects a limit we didn ' t account for ) . 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_PROTOCOL :
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 :
case SSL_R_TLSV1_ALERT_PROTOCOL_VERSION :
give_proto_hint = true ;
break ;
default :
give_proto_hint = false ;
break ;
}
ereport ( COMMERROR ,
ereport ( COMMERROR ,
( errcode ( ERRCODE_PROTOCOL_VIOLATION ) ,
( errcode ( ERRCODE_PROTOCOL_VIOLATION ) ,
errmsg ( " could not accept SSL connection: %s " ,
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 ) :
MIN_OPENSSL_TLS_VERSION ,
ssl_max_protocol_version ?
ssl_protocol_version_to_string ( ssl_max_protocol_version ) :
MAX_OPENSSL_TLS_VERSION ) : 0 ) ) ;
break ;
break ;
case SSL_ERROR_ZERO_RETURN :
case SSL_ERROR_ZERO_RETURN :
ereport ( COMMERROR ,
ereport ( COMMERROR ,
@ -1328,6 +1370,29 @@ ssl_protocol_version_to_openssl(int v)
return - 1 ;
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
static void
default_openssl_tls_init ( SSL_CTX * context , bool isServerStart )
default_openssl_tls_init ( SSL_CTX * context , bool isServerStart )