TLS: Propagate and handle SSL_new() failures. (#7576)
The connection API may create an accepted connection object in an error state, and callers are expected to check it before attempting to use it. Co-authored-by: mrpre <mrpre@163.com>
This commit is contained in:
parent
109b5ccdcd
commit
784ceeb90d
@ -672,6 +672,15 @@ void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
|
||||
|
||||
connection *conn = server.tls_cluster ?
|
||||
connCreateAcceptedTLS(cfd, TLS_CLIENT_AUTH_YES) : connCreateAcceptedSocket(cfd);
|
||||
|
||||
/* Make sure connection is not in an error state */
|
||||
if (connGetState(conn) != CONN_STATE_ACCEPTING) {
|
||||
serverLog(LL_VERBOSE,
|
||||
"Error creating an accepting connection for cluster node: %s",
|
||||
connGetLastError(conn));
|
||||
connClose(conn);
|
||||
return;
|
||||
}
|
||||
connNonBlock(conn);
|
||||
connEnableTcpNoDelay(conn);
|
||||
|
||||
|
@ -85,8 +85,12 @@ connection *connCreateSocket() {
|
||||
/* Create a new socket-type connection that is already associated with
|
||||
* an accepted connection.
|
||||
*
|
||||
* The socket is not read for I/O until connAccept() was called and
|
||||
* The socket is not ready for I/O until connAccept() was called and
|
||||
* invoked the connection-level accept handler.
|
||||
*
|
||||
* Callers should use connGetState() and verify the created connection
|
||||
* is not in an error state (which is not possible for a socket connection,
|
||||
* but could but possible with other protocols).
|
||||
*/
|
||||
connection *connCreateAcceptedSocket(int fd) {
|
||||
connection *conn = connCreateSocket();
|
||||
|
@ -895,8 +895,18 @@ void clientAcceptHandler(connection *conn) {
|
||||
#define MAX_ACCEPTS_PER_CALL 1000
|
||||
static void acceptCommonHandler(connection *conn, int flags, char *ip) {
|
||||
client *c;
|
||||
char conninfo[100];
|
||||
UNUSED(ip);
|
||||
|
||||
if (connGetState(conn) != CONN_STATE_ACCEPTING) {
|
||||
serverLog(LL_VERBOSE,
|
||||
"Accepted client connection in error state: %s (conn: %s)",
|
||||
connGetLastError(conn),
|
||||
connGetInfo(conn, conninfo, sizeof(conninfo)));
|
||||
connClose(conn);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Limit the number of connections we take at the same time.
|
||||
*
|
||||
* Admission control will happen before a client is created and connAccept()
|
||||
@ -925,7 +935,6 @@ static void acceptCommonHandler(connection *conn, int flags, char *ip) {
|
||||
|
||||
/* Create connection and client */
|
||||
if ((c = createClient(conn)) == NULL) {
|
||||
char conninfo[100];
|
||||
serverLog(LL_WARNING,
|
||||
"Error registering fd event for the new client: %s (conn: %s)",
|
||||
connGetLastError(conn),
|
||||
|
28
src/tls.c
28
src/tls.c
@ -337,11 +337,34 @@ connection *connCreateTLS(void) {
|
||||
return (connection *) conn;
|
||||
}
|
||||
|
||||
/* Fetch the latest OpenSSL error and store it in the connection */
|
||||
static void updateTLSError(tls_connection *conn) {
|
||||
conn->c.last_errno = 0;
|
||||
if (conn->ssl_error) zfree(conn->ssl_error);
|
||||
conn->ssl_error = zmalloc(512);
|
||||
ERR_error_string_n(ERR_get_error(), conn->ssl_error, 512);
|
||||
}
|
||||
|
||||
/* Create a new TLS connection that is already associated with
|
||||
* an accepted underlying file descriptor.
|
||||
*
|
||||
* The socket is not ready for I/O until connAccept() was called and
|
||||
* invoked the connection-level accept handler.
|
||||
*
|
||||
* Callers should use connGetState() and verify the created connection
|
||||
* is not in an error state.
|
||||
*/
|
||||
connection *connCreateAcceptedTLS(int fd, int require_auth) {
|
||||
tls_connection *conn = (tls_connection *) connCreateTLS();
|
||||
conn->c.fd = fd;
|
||||
conn->c.state = CONN_STATE_ACCEPTING;
|
||||
|
||||
if (!conn->ssl) {
|
||||
updateTLSError(conn);
|
||||
conn->c.state = CONN_STATE_ERROR;
|
||||
return (connection *) conn;
|
||||
}
|
||||
|
||||
switch (require_auth) {
|
||||
case TLS_CLIENT_AUTH_NO:
|
||||
SSL_set_verify(conn->ssl, SSL_VERIFY_NONE, NULL);
|
||||
@ -384,10 +407,7 @@ static int handleSSLReturnCode(tls_connection *conn, int ret_value, WantIOType *
|
||||
break;
|
||||
default:
|
||||
/* Error! */
|
||||
conn->c.last_errno = 0;
|
||||
if (conn->ssl_error) zfree(conn->ssl_error);
|
||||
conn->ssl_error = zmalloc(512);
|
||||
ERR_error_string_n(ERR_get_error(), conn->ssl_error, 512);
|
||||
updateTLSError(conn);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user