diff --git a/src/sbbs3/js_cryptcon.c b/src/sbbs3/js_cryptcon.c index 196961b6e5078a8b4a74225075a0b6d3e515e0fe..1092154df919a002c442154221cb86ec5963e6be 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 51247ee70a4681622a072896262c857454ac223a..6ecee94d830e29dc4ce3e0874dd018c16db80e21 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 75f79519492bdd4fb0271e7ee67831cf6454fead..ad02ad24890bac99b0722f79959845ed34e16351 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 3000fd4b4354aebaa09040a3191f63abf66d76f7..b5bd3bb9841d76de1128f2c09dedf485dfa46b0a 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 0accf74e2d15c3b695637d6acf1d854cf4949811..365d993c1ce9b93da91606b9e5ed3c97d86e3610 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 336df99efbafcef554a691b524131b368f4ac0a1..439c07c066b47985186a3a5888f5b74457ce3533 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) }