Move SSL context code to get/set_ssl_context methods
- Move code setting up SSL context from accept_new() to new get/set_ssl_context() methods - set_ssl_context() will allow setting context only if not already set, or force re-setting context even if already present - set_ssl_context() will return 1 if SSL context has been set - if getting the new SSL context fails, set_ssl_context() will not break current SSL context This is preparatory work for reloading SSL certificates/key on BIP reload. Signed-off-by: Loïc Gomez <bip@animanova.fr>
This commit is contained in:
parent
400b0d66de
commit
f2443aaf23
121
src/connection.c
121
src/connection.c
@ -34,6 +34,7 @@ extern char *conf_client_ciphers;
|
||||
extern char *conf_client_dh_file;
|
||||
static int SSLize(connection_t *cn, int *nc);
|
||||
static SSL_CTX *SSL_init_context(char *ciphers);
|
||||
SSL_CTX *get_ssl_context(void);
|
||||
/* SSH like trust management */
|
||||
int link_add_untrusted(void *ls, X509 *cert);
|
||||
#endif
|
||||
@ -1231,6 +1232,77 @@ static int ctx_set_dh(SSL_CTX *ctx)
|
||||
conf_client_dh_file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int set_ssl_context(int force)
|
||||
{
|
||||
SSL_CTX *newctx = NULL;
|
||||
if (sslctx) {
|
||||
if (force == SSLCTX_FORCE_UPDATE) {
|
||||
mylog(LOG_DEBUG, "SSL context already set, forcing update");
|
||||
} else {
|
||||
mylog(LOG_DEBUG, "SSL context is already set, not updating");
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
mylog(LOG_DEBUG, "Initializing SSL context for accepted connections");
|
||||
}
|
||||
|
||||
newctx = get_ssl_context();
|
||||
if (!newctx) {
|
||||
mylog(LOG_ERROR, "Failed to get new SSL context");
|
||||
if (sslctx)
|
||||
mylog(LOG_WARN, "Keeping old SSL context");
|
||||
return 0;
|
||||
}
|
||||
sslctx = newctx;
|
||||
return 1;
|
||||
}
|
||||
|
||||
SSL_CTX *get_ssl_context(void)
|
||||
{
|
||||
SSL_CTX *newctx = NULL;
|
||||
if (!(newctx = SSL_init_context(conf_client_ciphers))) {
|
||||
mylog(LOG_ERROR, "SSL context initialization failed");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!conf_client_dh_file) {
|
||||
// try with a default path but don't fail if it doesn't exist
|
||||
conf_client_dh_file = default_path(conf_biphome, "dh.pem",
|
||||
"DH parameters");
|
||||
|
||||
struct stat st_buf;
|
||||
if (stat(conf_client_dh_file, &st_buf) != 0) {
|
||||
free(conf_client_dh_file);
|
||||
conf_client_dh_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf_client_dh_file) {
|
||||
if (!ctx_set_dh(newctx)) {
|
||||
SSL_CTX_free(newctx);
|
||||
mylog(LOG_ERROR, "SSL Unable to load DH parameters");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
mylog(LOG_DEBUG, "Loading SSL cert from %s", conf_ssl_certfile);
|
||||
if (!SSL_CTX_use_certificate_chain_file(newctx, conf_ssl_certfile)) {
|
||||
mylog(LOG_WARN, "SSL: Unable to load certificate file");
|
||||
SSL_CTX_free(newctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mylog(LOG_DEBUG, "Loading SSL key from %s", conf_ssl_certfile);
|
||||
if (!SSL_CTX_use_PrivateKey_file(newctx, conf_ssl_certfile,
|
||||
SSL_FILETYPE_PEM)) {
|
||||
mylog(LOG_WARN, "SSL: Unable to load key file");
|
||||
SSL_CTX_free(newctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return newctx;
|
||||
}
|
||||
#endif
|
||||
|
||||
connection_t *accept_new(connection_t *cn)
|
||||
@ -1266,52 +1338,11 @@ connection_t *accept_new(connection_t *cn)
|
||||
conn->client = 1;
|
||||
#ifdef HAVE_LIBSSL
|
||||
if (cn->ssl) {
|
||||
if (!sslctx)
|
||||
set_ssl_context(SSLCTX_NO_REPLACE);
|
||||
if (!sslctx) {
|
||||
mylog(LOG_DEBUG,
|
||||
"No SSL context available for "
|
||||
"accepted connections. "
|
||||
"Initializing...");
|
||||
if (!(sslctx = SSL_init_context(conf_client_ciphers))) {
|
||||
mylog(LOG_ERROR,
|
||||
"SSL context initialization "
|
||||
"failed");
|
||||
connection_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!conf_client_dh_file) {
|
||||
// try with a default path but don't fail if it
|
||||
// doesn't exist
|
||||
conf_client_dh_file =
|
||||
default_path(conf_biphome, "dh.pem",
|
||||
"DH parameters");
|
||||
|
||||
struct stat st_buf;
|
||||
if (stat(conf_client_dh_file, &st_buf) != 0) {
|
||||
free(conf_client_dh_file);
|
||||
conf_client_dh_file = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (conf_client_dh_file) {
|
||||
if (!ctx_set_dh(sslctx)) {
|
||||
mylog(LOG_ERROR,
|
||||
"SSL Unable to load DH "
|
||||
"parameters");
|
||||
connection_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SSL_CTX_use_certificate_chain_file(
|
||||
sslctx, conf_ssl_certfile))
|
||||
mylog(LOG_WARN,
|
||||
"SSL: Unable to load "
|
||||
"certificate file");
|
||||
if (!SSL_CTX_use_PrivateKey_file(sslctx,
|
||||
conf_ssl_certfile,
|
||||
SSL_FILETYPE_PEM))
|
||||
mylog(LOG_WARN, "SSL: Unable to load key file");
|
||||
connection_free(conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn->ssl_h = SSL_new(sslctx);
|
||||
|
@ -60,6 +60,9 @@
|
||||
#define SSL_CHECK_NONE (0)
|
||||
#define SSL_CHECK_BASIC (1)
|
||||
#define SSL_CHECK_CA (2)
|
||||
|
||||
#define SSLCTX_NO_REPLACE 0
|
||||
#define SSLCTX_FORCE_UPDATE 1
|
||||
#endif
|
||||
|
||||
struct connecting_data;
|
||||
@ -113,4 +116,9 @@ uint16_t connection_localport(connection_t *cn);
|
||||
uint16_t connection_remoteport(connection_t *cn);
|
||||
char *connection_localip(connection_t *cn);
|
||||
char *connection_remoteip(connection_t *cn);
|
||||
#ifdef HAVE_LIBSSL
|
||||
/* Set SSL context, force update if already set and force is 1
|
||||
* Return 1 if SSL context has been set */
|
||||
int set_ssl_context(int force);
|
||||
#endif
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user