Fix TLS Build Errors

Former-commit-id: aea86c5977c01debb4f4a4340c866aa5c5f20f04
This commit is contained in:
John Sully 2021-05-25 16:55:59 +00:00
parent 5267928381
commit caba5639f4
4 changed files with 118 additions and 49 deletions

View File

@ -2560,6 +2560,16 @@ static int updateTlsCfgInt(long long val, long long prev, const char **err) {
return updateTlsCfg(NULL, NULL, err);
}
static int updateTLSPortThread(long long val, bool fFirstCall, const char **err)
{
if (changeListenPort(val, &serverTL->tlsfd, acceptTLSHandler, fFirstCall) == C_ERR) {
*err = "Unable to listen on this port. Check server logs.";
return 0;
}
return 1;
}
static int updateTLSPort(long long val, long long prev, const char **err) {
/* Do nothing if port is unchanged */
if (val == prev) {
@ -2567,14 +2577,25 @@ static int updateTLSPort(long long val, long long prev, const char **err) {
}
/* Configure TLS if tls is enabled */
if (prev == 0 && tlsConfigure(&server.tls_ctx_config) == C_ERR) {
if (prev == 0 && tlsConfigure(&g_pserver->tls_ctx_config) == C_ERR) {
*err = "Unable to update TLS configuration. Check server logs.";
return 0;
}
asdsa
if (changeListenPort(val, &server.tlsfd, acceptTLSHandler) == C_ERR) {
*err = "Unable to listen on this port. Check server logs.";
// Do our thread first in case there is a config issue
if (!updateTLSPortThread(val, true /*fFirstCall*/, err))
return 0;
for (int ithread = 0; ithread < cserver.cthreads; ++ithread) {
if (ithread == serverTL - g_pserver->rgthreadvar)
continue; // we already did our thread
aePostFunction(g_pserver->rgthreadvar[ithread].el, [val]{
const char **err;
if (!updateTLSPortThread(val, false /*fFirstCall*/, err)) {
serverLog(LL_WARNING, "Failed to update TLS port for a thread: %s", *err);
serverLog(LL_WARNING, "\tKeyDB will still be listening on the old port for some threads.");
}
});
}
return 1;
@ -2740,26 +2761,26 @@ standardConfig configs[] = {
createBoolConfig("allow-write-during-load", NULL, MODIFIABLE_CONFIG, g_pserver->fWriteDuringActiveLoad, 0, NULL, NULL),
#ifdef USE_OPENSSL
createIntConfig("tls-port", NULL, IMMUTABLE_CONFIG, 0, 65535, server.tls_port, 0, INTEGER_CONFIG, NULL, updateTLSPort), /* TCP port. */
createIntConfig("tls-session-cache-size", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.tls_ctx_config.session_cache_size, 20*1024, INTEGER_CONFIG, NULL, updateTlsCfgInt),
createIntConfig("tls-session-cache-timeout", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, server.tls_ctx_config.session_cache_timeout, 300, INTEGER_CONFIG, NULL, updateTlsCfgInt),
createBoolConfig("tls-cluster", NULL, MODIFIABLE_CONFIG, server.tls_cluster, 0, NULL, updateTlsCfgBool),
createBoolConfig("tls-replication", NULL, MODIFIABLE_CONFIG, server.tls_replication, 0, NULL, updateTlsCfgBool),
createEnumConfig("tls-auth-clients", NULL, MODIFIABLE_CONFIG, tls_auth_clients_enum, server.tls_auth_clients, TLS_CLIENT_AUTH_YES, NULL, NULL),
createBoolConfig("tls-prefer-server-ciphers", NULL, MODIFIABLE_CONFIG, server.tls_ctx_config.prefer_server_ciphers, 0, NULL, updateTlsCfgBool),
createBoolConfig("tls-session-caching", NULL, MODIFIABLE_CONFIG, server.tls_ctx_config.session_caching, 1, NULL, updateTlsCfgBool),
createStringConfig("tls-cert-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.cert_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-key-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.key_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-key-file-pass", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.key_file_pass, NULL, NULL, updateTlsCfg),
createStringConfig("tls-client-cert-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.client_cert_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-client-key-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.client_key_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-client-key-file-pass", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.client_key_file_pass, NULL, NULL, updateTlsCfg),
createStringConfig("tls-dh-params-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.dh_params_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-ca-cert-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.ca_cert_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-ca-cert-dir", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.ca_cert_dir, NULL, NULL, updateTlsCfg),
createStringConfig("tls-protocols", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.protocols, NULL, NULL, updateTlsCfg),
createStringConfig("tls-ciphers", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.ciphers, NULL, NULL, updateTlsCfg),
createStringConfig("tls-ciphersuites", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, server.tls_ctx_config.ciphersuites, NULL, NULL, updateTlsCfg),
createIntConfig("tls-port", NULL, IMMUTABLE_CONFIG, 0, 65535, g_pserver->tls_port, 0, INTEGER_CONFIG, NULL, updateTLSPort), /* TCP port. */
createIntConfig("tls-session-cache-size", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, g_pserver->tls_ctx_config.session_cache_size, 20*1024, INTEGER_CONFIG, NULL, updateTlsCfgInt),
createIntConfig("tls-session-cache-timeout", NULL, MODIFIABLE_CONFIG, 0, INT_MAX, g_pserver->tls_ctx_config.session_cache_timeout, 300, INTEGER_CONFIG, NULL, updateTlsCfgInt),
createBoolConfig("tls-cluster", NULL, MODIFIABLE_CONFIG, g_pserver->tls_cluster, 0, NULL, updateTlsCfgBool),
createBoolConfig("tls-replication", NULL, MODIFIABLE_CONFIG, g_pserver->tls_replication, 0, NULL, updateTlsCfgBool),
createEnumConfig("tls-auth-clients", NULL, MODIFIABLE_CONFIG, tls_auth_clients_enum, g_pserver->tls_auth_clients, TLS_CLIENT_AUTH_YES, NULL, NULL),
createBoolConfig("tls-prefer-server-ciphers", NULL, MODIFIABLE_CONFIG, g_pserver->tls_ctx_config.prefer_server_ciphers, 0, NULL, updateTlsCfgBool),
createBoolConfig("tls-session-caching", NULL, MODIFIABLE_CONFIG, g_pserver->tls_ctx_config.session_caching, 1, NULL, updateTlsCfgBool),
createStringConfig("tls-cert-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.cert_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-key-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.key_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-key-file-pass", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.key_file_pass, NULL, NULL, updateTlsCfg),
createStringConfig("tls-client-cert-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.client_cert_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-client-key-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.client_key_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-client-key-file-pass", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.client_key_file_pass, NULL, NULL, updateTlsCfg),
createStringConfig("tls-dh-params-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.dh_params_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-ca-cert-file", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.ca_cert_file, NULL, NULL, updateTlsCfg),
createStringConfig("tls-ca-cert-dir", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.ca_cert_dir, NULL, NULL, updateTlsCfg),
createStringConfig("tls-protocols", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.protocols, NULL, NULL, updateTlsCfg),
createStringConfig("tls-ciphers", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.ciphers, NULL, NULL, updateTlsCfg),
createStringConfig("tls-ciphersuites", NULL, MODIFIABLE_CONFIG, EMPTY_STRING_IS_NULL, g_pserver->tls_ctx_config.ciphersuites, NULL, NULL, updateTlsCfg),
#endif
/* NULL Terminator */

View File

@ -1895,6 +1895,31 @@ void replicationCreateMasterClient(redisMaster *mi, connection *conn, int dbid)
if (dbid != -1) selectDb(mi->master,dbid);
}
void replicationCreateCachedMasterClone(redisMaster *mi) {
serverAssert(mi->master != nullptr);
serverLog(LL_NOTICE, "Creating cache clone of our master");
client *c = createClient(nullptr, ielFromEventLoop(serverTL->el));
c->flags |= mi->master->flags;
c->authenticated = mi->master->authenticated;
c->reploff = mi->master->reploff;
c->read_reploff = mi->master->read_reploff;
c->user = mi->master->user;
memcpy(c->uuid, mi->master->uuid, UUID_BINARY_LEN);
memcpy(c->replid, mi->master->replid,
sizeof(mi->master->replid));
selectDb(c, mi->master->db->id);
// Free the old one
mi->master->flags &= ~CLIENT_MASTER;
freeClientAsync(mi->master);
// Now make this one the cache
mi->master = c;
replicationCacheMaster(mi, c);
}
/* This function will try to re-enable the AOF file after the
* master-replica synchronization: if it fails after multiple attempts
* the replica cannot be considered reliable and exists with an
@ -2708,6 +2733,10 @@ void syncWithMaster(connection *conn) {
int psync_result;
redisMaster *mi = (redisMaster*)connGetPrivateData(conn);
if (mi == nullptr) {
// We're about to be closed, bail
return;
}
/* If this event fired after the user turned the instance into a master
* with SLAVEOF NO ONE we must just return ASAP. */
@ -3066,6 +3095,7 @@ write_error: /* Handle sendCommand() errors. */
int connectWithMaster(redisMaster *mi) {
serverAssert(mi->master == nullptr);
mi->repl_transfer_s = g_pserver->tls_replication ? connCreateTLS() : connCreateSocket();
mi->ielReplTransfer = serverTL - g_pserver->rgthreadvar;
connSetPrivateData(mi->repl_transfer_s, mi);
if (connConnect(mi->repl_transfer_s, mi->masterhost, mi->masterport,
NET_FIRST_BIND_ADDR, syncWithMaster) == C_ERR) {
@ -3089,7 +3119,11 @@ int connectWithMaster(redisMaster *mi) {
* Never call this function directly, use cancelReplicationHandshake() instead.
*/
void undoConnectWithMaster(redisMaster *mi) {
connClose(mi->repl_transfer_s);
auto conn = mi->repl_transfer_s;
connSetPrivateData(conn, nullptr);
aePostFunction(g_pserver->rgthreadvar[mi->ielReplTransfer].el, [conn]{
connClose(conn);
});
mi->repl_transfer_s = NULL;
}
@ -3171,9 +3205,17 @@ struct redisMaster *replicationAddMaster(char *ip, int port) {
sdsfree(mi->masterhost);
mi->masterhost = nullptr;
if (mi->master) {
freeClientAsync(mi->master);
mi->master = nullptr;
if (FCorrectThread(mi->master)) {
// This will cache the master and do all that fancy stuff
if (!freeClient(mi->master) && mi->master)
replicationCreateCachedMasterClone(mi);
} else {
// We're not on the same thread so we can't use the freeClient method, instead we have to clone the master
// and cache that clone
replicationCreateCachedMasterClone(mi);
}
}
serverAssert(mi->master == nullptr);
if (!g_pserver->fActiveReplica)
disconnectAllBlockedClients(); /* Clients blocked in master, now replica. */
@ -3248,10 +3290,15 @@ void replicationUnsetMaster(redisMaster *mi) {
sdsfree(mi->masterhost);
mi->masterhost = NULL;
if (mi->master) {
if (FCorrectThread(mi->master))
freeClient(mi->master);
else
freeClientAsync(mi->master);
if (FCorrectThread(mi->master)) {
// This will cache the master and do all that fancy stuff
if (!freeClient(mi->master) && mi->master)
replicationCreateCachedMasterClone(mi);
} else {
// We're not on the same thread so we can't use the freeClient method, instead we have to clone the master
// and cache that clone
replicationCreateCachedMasterClone(mi);
}
}
replicationDiscardCachedMaster(mi);
cancelReplicationHandshake(mi,false);
@ -3666,7 +3713,8 @@ void replicationResurrectCachedMaster(redisMaster *mi, connection *conn) {
/* Re-add to the list of clients. */
linkClient(mi->master);
serverAssert(connGetPrivateData(mi->master->conn) == mi->master);
serverAssert(mi->master->iel == ielFromEventLoop(serverTL->el));
serverAssert(mi->master->conn == conn);
AssertCorrectThread(mi->master);
if (connSetReadHandler(mi->master->conn, readQueryFromClient, true)) {
serverLog(LL_WARNING,"Error resurrecting the cached master, impossible to add the readable handler: %s", strerror(errno));
freeClientAsync(mi->master); /* Close ASAP. */
@ -4002,10 +4050,15 @@ void replicationCron(void) {
(time(NULL)-mi->master->lastinteraction) > g_pserver->repl_timeout)
{
serverLog(LL_WARNING,"MASTER timeout: no data nor PING received...");
if (FCorrectThread(mi->master))
freeClient(mi->master);
else
freeClientAsync(mi->master);
if (FCorrectThread(mi->master)) {
// This will cache the master and do all that fancy stuff
if (!freeClient(mi->master) && mi->master)
replicationCreateCachedMasterClone(mi);
} else {
// We're not on the same thread so we can't use the freeClient method, instead we have to clone the master
// and cache that clone
replicationCreateCachedMasterClone(mi);
}
}
/* Check if we should connect to a MASTER */

View File

@ -1528,6 +1528,7 @@ struct redisMaster {
uint64_t mvccLastSync;
/* During a handshake the server may have stale keys, we track these here to share once a reciprocal connection is made */
std::map<int, std::vector<robj_sharedptr>> *staleKeyMap;
int ielReplTransfer = -1;
};
// Const vars are not changed after worker threads are launched
@ -2406,6 +2407,7 @@ void replicationCron(void);
void replicationStartPendingFork(void);
void replicationHandleMasterDisconnection(struct redisMaster *mi);
void replicationCacheMaster(struct redisMaster *mi, client *c);
void replicationCreateCachedMasterClone(redisMaster *mi);
void resizeReplicationBacklog(long long newsize);
struct redisMaster *replicationAddMaster(char *ip, int port);
void replicationUnsetMaster(struct redisMaster *mi);

View File

@ -233,7 +233,7 @@ void tlsCleanup(void) {
static int tlsPasswordCallback(char *buf, int size, int rwflag, void *u) {
UNUSED(rwflag);
const char *pass = u;
const char *pass = (const char*)u;
size_t pass_len;
if (!pass) return -1;
@ -253,7 +253,6 @@ static SSL_CTX *createSSLContext(redisTLSContextConfig *ctx_config, int protocol
const char *key_file_pass = client ? ctx_config->client_key_file_pass : ctx_config->key_file_pass;
char errbuf[256];
SSL_CTX *ctx = NULL;
int protocols;
ctx = SSL_CTX_new(SSLv23_method());
@ -331,6 +330,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
char errbuf[256];
SSL_CTX *ctx = NULL;
SSL_CTX *client_ctx = NULL;
int protocols;
if (!ctx_config->cert_file) {
serverLog(LL_WARNING, "No tls-cert-file configured!");
@ -342,13 +342,13 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
goto error;
}
if (((server.tls_auth_clients != TLS_CLIENT_AUTH_NO) || server.tls_cluster || server.tls_replication) &&
if (((g_pserver->tls_auth_clients != TLS_CLIENT_AUTH_NO) || g_pserver->tls_cluster || g_pserver->tls_replication) &&
!ctx_config->ca_cert_file && !ctx_config->ca_cert_dir) {
serverLog(LL_WARNING, "Either tls-ca-cert-file or tls-ca-cert-dir must be specified when tls-cluster, tls-replication or tls-auth-clients are enabled!");
goto error;
}
int protocols = parseProtocolsConfig(ctx_config->protocols);
protocols = parseProtocolsConfig(ctx_config->protocols);
if (protocols == -1) goto error;
/* Create server side/generla context */
@ -359,7 +359,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);
SSL_CTX_sess_set_cache_size(ctx, ctx_config->session_cache_size);
SSL_CTX_set_timeout(ctx, ctx_config->session_cache_timeout);
SSL_CTX_set_session_id_context(ctx, (void *) "redis", 5);
SSL_CTX_set_session_id_context(ctx, (const unsigned char *) "KeyDB", 5);
} else {
SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
}
@ -413,6 +413,7 @@ int tlsConfigure(redisTLSContextConfig *ctx_config) {
SSL_CTX_free(redis_tls_client_ctx);
redis_tls_ctx = ctx;
redis_tls_client_ctx = client_ctx;
}
return C_OK;
@ -496,14 +497,6 @@ connection *connCreateTLS(void) {
return createTLSConnection(1);
}
/* 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.
*