From 46827ef45e642654dadb13b0a98ffb36bf551fb8 Mon Sep 17 00:00:00 2001 From: deuce <> Date: Sun, 4 Oct 2015 22:09:47 +0000 Subject: [PATCH] Move do_cryptInit() into ssl.c, use pthread_once() to call it. Mutex protect certificate loading/creation. --- src/sbbs3/js_cryptcon.c | 2 +- src/sbbs3/js_socket.c | 27 --------------------------- src/sbbs3/js_socket.h | 4 ---- src/sbbs3/main.cpp | 2 +- src/sbbs3/ssl.c | 41 +++++++++++++++++++++++++++++++++++++++-- src/sbbs3/ssl.h | 1 + 6 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/sbbs3/js_cryptcon.c b/src/sbbs3/js_cryptcon.c index 196961b6e5..1092154df9 100644 --- a/src/sbbs3/js_cryptcon.c +++ b/src/sbbs3/js_cryptcon.c @@ -5,7 +5,7 @@ #include "sbbs.h" #include <cryptlib.h> #include "js_request.h" -#include "js_socket.h" +#include "ssl.h" struct private_data { CRYPT_CONTEXT ctx; diff --git a/src/sbbs3/js_socket.c b/src/sbbs3/js_socket.c index 51247ee70a..6ecee94d83 100644 --- a/src/sbbs3/js_socket.c +++ b/src/sbbs3/js_socket.c @@ -45,15 +45,8 @@ #ifdef JAVASCRIPT -int cryptInitialized=0; - static const char* getprivate_failure = "line %d %s JS_GetPrivate failed"; -static void do_cryptEnd(void) -{ - cryptEnd(); -} - static int do_cryptAttribute(const CRYPT_CONTEXT session, CRYPT_ATTRIBUTE_TYPE attr, int val) { int ret; @@ -76,26 +69,6 @@ static int do_cryptAttribute(const CRYPT_CONTEXT session, CRYPT_ATTRIBUTE_TYPE a return ret; } -int DLLCALL do_cryptInit(void) -{ - int ret; - - if(!cryptInitialized) { - if((ret=cryptInit())==CRYPT_OK) { - cryptAddRandom(NULL,CRYPT_RANDOM_SLOWPOLL); - cryptInitialized=1; - atexit(do_cryptEnd); - } - else { - if (ret == -12) // This is a bit of a hack... - cryptInitialized=1; - else - lprintf(LOG_ERR,"cryptInit() returned %d", ret); - } - } - return cryptInitialized; -} - static int do_cryptAttributeString(const CRYPT_CONTEXT session, CRYPT_ATTRIBUTE_TYPE attr, void *val, int len) { int ret=cryptSetAttributeString(session, attr, val, len); diff --git a/src/sbbs3/js_socket.h b/src/sbbs3/js_socket.h index 75f7951949..ad02ad2489 100644 --- a/src/sbbs3/js_socket.h +++ b/src/sbbs3/js_socket.h @@ -26,10 +26,6 @@ typedef struct extern "C" { #endif -extern int cryptInitialized; - -DLLEXPORT int DLLCALL do_cryptInit(void); - #ifdef __cplusplus } #endif diff --git a/src/sbbs3/main.cpp b/src/sbbs3/main.cpp index 3000fd4b43..b5bd3bb984 100644 --- a/src/sbbs3/main.cpp +++ b/src/sbbs3/main.cpp @@ -41,7 +41,7 @@ #include "netwrap.h" #include "js_rtpool.h" #include "js_request.h" -#include "js_socket.h" +#include "ssl.h" #include <multisock.h> #include <limits.h> // HOST_NAME_MAX diff --git a/src/sbbs3/ssl.c b/src/sbbs3/ssl.c index 0accf74e2d..365d993c1c 100644 --- a/src/sbbs3/ssl.c +++ b/src/sbbs3/ssl.c @@ -1,7 +1,10 @@ #include <stdbool.h> #include <stdio.h> + +#include <threadwrap.h> + #include "ssl.h" -#include "js_socket.h" // TODO... move this stuff in here? +//#include "js_socket.h" // TODO... move this stuff in here? static scfg_t scfg; @@ -48,6 +51,34 @@ static bool get_error_string(int status, CRYPT_SESSION sess, char estr[SSL_ESTR_ return false; } +static pthread_once_t crypt_init_once = PTHREAD_ONCE_INIT; +static pthread_mutex_t ssl_cert_mutex; + +static void do_cryptEnd(void) +{ + cryptEnd(); +} + +static void internal_do_cryptInit(void) +{ + int ret; + + if((ret=cryptInit())==CRYPT_OK) { + cryptAddRandom(NULL,CRYPT_RANDOM_SLOWPOLL); + atexit(do_cryptEnd); + } + else { + lprintf(LOG_ERR,"cryptInit() returned %d", ret); + } + pthread_mutex_init(&ssl_cert_mutex, NULL); + return; +} + +int DLLCALL do_cryptInit(void) +{ + pthread_once(&crypt_init_once, internal_do_cryptInit); +} + #define DO(x) get_error_string(x, ssl_context, estr, __FILE__, __LINE__) CRYPT_CONTEXT DLLCALL get_ssl_cert(scfg_t *cfg, char estr[SSL_ESTR_LEN]) @@ -61,16 +92,20 @@ CRYPT_CONTEXT DLLCALL get_ssl_cert(scfg_t *cfg, char estr[SSL_ESTR_LEN]) if(!do_cryptInit()) return -1; + pthread_mutex_lock(&ssl_cert_mutex); memset(&ssl_context, 0, sizeof(ssl_context)); /* Get the certificate... first try loading it from a file... */ SAFEPRINTF2(str,"%s%s",cfg->ctrl_dir,"ssl.cert"); if(cryptStatusOK(cryptKeysetOpen(&ssl_keyset, CRYPT_UNUSED, CRYPT_KEYSET_FILE, str, CRYPT_KEYOPT_NONE))) { - if(!DO(cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, "ssl_cert", cfg->sys_pass))) + if(!DO(cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, "ssl_cert", cfg->sys_pass))) { + pthread_mutex_unlock(&ssl_cert_mutex); return -1; + } } else { /* Couldn't do that... create a new context and use the cert from there... */ if(!cryptStatusOK(i=cryptCreateContext(&ssl_context, CRYPT_UNUSED, CRYPT_ALGO_RSA))) { + pthread_mutex_unlock(&ssl_cert_mutex); sprintf(estr, "cryptlib error %d creating SSL context",i); return -1; } @@ -101,6 +136,7 @@ CRYPT_CONTEXT DLLCALL get_ssl_cert(scfg_t *cfg, char estr[SSL_ESTR_LEN]) } cryptKeysetClose(ssl_keyset); + pthread_mutex_unlock(&ssl_cert_mutex); return ssl_context; failure_return_3: @@ -109,5 +145,6 @@ failure_return_2: cryptKeysetClose(ssl_keyset); failure_return_1: cryptDestroyContext(ssl_context); + pthread_mutex_unlock(&ssl_cert_mutex); return -1; } diff --git a/src/sbbs3/ssl.h b/src/sbbs3/ssl.h index 336df99efb..439c07c066 100644 --- a/src/sbbs3/ssl.h +++ b/src/sbbs3/ssl.h @@ -37,6 +37,7 @@ DLLEXPORT void DLLCALL free_crypt_attrstr(char *attr); DLLEXPORT char* DLLCALL get_crypt_attribute(CRYPT_SESSION sess, C_IN CRYPT_ATTRIBUTE_TYPE attr); DLLEXPORT char* DLLCALL get_crypt_error(CRYPT_SESSION sess); DLLEXPORT CRYPT_CONTEXT DLLCALL get_ssl_cert(scfg_t *cfg, char estr[SSL_ESTR_LEN]); +DLLEXPORT int DLLCALL do_cryptInit(void); #if defined(__cplusplus) } -- GitLab