diff --git a/src/sbbs3/js_socket.c b/src/sbbs3/js_socket.c index 9ba31cccdac9bdd10d7715cc0d73cb41768e398b..9ee9730b379c2fbaf26ad566c4378f080febec15 100644 --- a/src/sbbs3/js_socket.c +++ b/src/sbbs3/js_socket.c @@ -1651,6 +1651,7 @@ static JSBool js_socket_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict BOOL b; int32 i; char ssl_estr[SSL_ESTR_LEN]; + scfg_t *scfg; if((p=(js_socket_private_t*)JS_GetPrivate(cx,obj))==NULL) { // Prototype access @@ -1714,14 +1715,21 @@ static JSBool js_socket_set(JSContext *cx, JSObject *obj, jsid id, JSBool strict do_cryptAttribute(p->session, CRYPT_OPTION_CERT_COMPLIANCELEVEL, CRYPT_COMPLIANCELEVEL_REDUCED); if (tiny == SOCK_PROP_SSL_SESSION) { ret=do_cryptAttributeString(p->session, CRYPT_SESSINFO_SERVER_NAME, p->hostname, strlen(p->hostname)); - p->context = -1; + p->tls_server = FALSE; } else { - p->context = get_ssl_cert(JS_GetRuntimePrivate(JS_GetRuntime(cx)), ssl_estr); - if (p->context == -1) - ret = CRYPT_ERROR_PARAM1; + scfg = JS_GetRuntimePrivate(JS_GetRuntime(cx)); + + if (scfg == NULL) { + ret = CRYPT_ERROR_NOTAVAIL; + } else { - ret = cryptSetAttribute(p->session, CRYPT_SESSINFO_PRIVATEKEY, p->context); + get_ssl_cert(scfg, ssl_estr); + if (scfg->tls_certificate == -1) + ret = CRYPT_ERROR_NOTAVAIL; + else { + ret = cryptSetAttribute(p->session, CRYPT_SESSINFO_PRIVATEKEY, scfg->tls_certificate); + } } } if(ret==CRYPT_OK) { @@ -1885,7 +1893,7 @@ static JSBool js_socket_get(JSContext *cx, JSObject *obj, jsid id, jsval *vp) *vp = BOOLEAN_TO_JSVAL(p->session != -1); break; case SOCK_PROP_SSL_SERVER: - *vp = BOOLEAN_TO_JSVAL(p->session != -1 && p->context != -1); + *vp = BOOLEAN_TO_JSVAL(p->session != -1 && p->tls_server); break; } diff --git a/src/sbbs3/js_socket.h b/src/sbbs3/js_socket.h index ba76daeffe0e9ff82243238cdadc68429d8b6590..faad1f7f9e79452923198c1e7338dc35cf6a3964 100644 --- a/src/sbbs3/js_socket.h +++ b/src/sbbs3/js_socket.h @@ -18,6 +18,7 @@ typedef struct int type; union xp_sockaddr remote_addr; CRYPT_SESSION session; + BOOL tls_server; char *hostname; struct xpms_set *set; size_t unflushed; diff --git a/src/sbbs3/load_cfg.c b/src/sbbs3/load_cfg.c index f97776690880bab3ef5c935517948782e7a2c363..3a97d0c2e77552a403878978949d95dd9dc55a6d 100644 --- a/src/sbbs3/load_cfg.c +++ b/src/sbbs3/load_cfg.c @@ -35,6 +35,9 @@ #include "sbbs.h" #include "text.h" /* TOTAL_TEXT */ +#ifdef USE_CRYPTLIB +#include "cryptlib.h" +#endif static void prep_cfg(scfg_t* cfg); static void free_attr_cfg(scfg_t* cfg); @@ -62,6 +65,7 @@ BOOL DLLCALL load_cfg(scfg_t* cfg, char* text[], BOOL prep, char* error) free_cfg(cfg); /* free allocated config parameters */ cfg->prepped=FALSE; /* reset prepped flag */ + cfg->tls_certificate = -1; if(cfg->node_num<1) cfg->node_num=1; @@ -272,11 +276,17 @@ void prep_cfg(scfg_t* cfg) for(i=0;i<cfg->total_xedits;i++) strlwr(cfg->xedit[i]->code); + if (!cfg->prepped) + cfg->tls_certificate = -1; cfg->prepped=TRUE; /* data prepared for run-time, DO NOT SAVE TO DISK! */ } void DLLCALL free_cfg(scfg_t* cfg) { +#ifdef USE_CRYPTLIB + if (cfg->tls_certificate != -1 && cfg->prepped) + cryptDestroyContext(cfg->tls_certificate); +#endif free_node_cfg(cfg); free_main_cfg(cfg); free_msgs_cfg(cfg); diff --git a/src/sbbs3/scfgdefs.h b/src/sbbs3/scfgdefs.h index e23cb372026796e424466dbacd907e5cd897b3df..a621866b10954afea7916934b69ce7100514c11a 100644 --- a/src/sbbs3/scfgdefs.h +++ b/src/sbbs3/scfgdefs.h @@ -601,6 +601,8 @@ typedef struct uint16_t user_backup_level; uint16_t mail_backup_level; + int tls_certificate; + } scfg_t; #endif /* Don't add anything after this line */ diff --git a/src/sbbs3/services.c b/src/sbbs3/services.c index a942366a1dd35764e68c588e27cefe5d42a1f947..175de68597e56bfa2108b3cd7d3d1872be108835 100644 --- a/src/sbbs3/services.c +++ b/src/sbbs3/services.c @@ -178,8 +178,6 @@ static BOOL winsock_startup(void) #endif -static CRYPT_CONTEXT tls_context = -1; - static ulong active_clients(void) { ulong i; @@ -1036,8 +1034,8 @@ static void js_service_thread(void* arg) } } #endif - if (tls_context != -1) { - HANDLE_CRYPT_CALL(cryptSetAttribute(service_client.tls_sess, CRYPT_SESSINFO_PRIVATEKEY, tls_context), &service_client); + if (scfg.tls_certificate != -1) { + HANDLE_CRYPT_CALL(cryptSetAttribute(service_client.tls_sess, CRYPT_SESSINFO_PRIVATEKEY, scfg.tls_certificate), &service_client); } BOOL nodelay=TRUE; setsockopt(socket,IPPROTO_TCP,TCP_NODELAY,(char*)&nodelay,sizeof(nodelay)); @@ -1615,11 +1613,6 @@ static void cleanup(int code) semfile_list_free(&recycle_semfiles); semfile_list_free(&shutdown_semfiles); - if (tls_context != -1) { - cryptDestroyContext(tls_context); - tls_context = -1; - } - update_clients(); #ifdef _WINSOCKAPI_ @@ -1847,9 +1840,9 @@ void DLLCALL services_thread(void* arg) lprintf(LOG_ERR, "Option error, TLS not yet supported for static services (%s)", service[i].protocol); continue; } - if(tls_context == -1) { - tls_context = get_ssl_cert(&scfg, ssl_estr); - if (tls_context == -1) { + if(scfg.tls_certificate == -1) { + get_ssl_cert(&scfg, ssl_estr); + if (scfg.tls_certificate == -1) { lprintf(LOG_ERR, "Error creating TLS certificate: %s", ssl_estr); continue; } diff --git a/src/sbbs3/ssl.c b/src/sbbs3/ssl.c index d17b14d5914ada11c7a2828301ffffcd4cde0a1b..bdb80b20c74fa9fbfb1c3bffa7b255eb92aa704c 100644 --- a/src/sbbs3/ssl.c +++ b/src/sbbs3/ssl.c @@ -100,6 +100,10 @@ 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); + if (cfg->tls_certificate != -1 || !cfg->prepped) { + pthread_mutex_unlock(&ssl_cert_mutex); + return cfg->tls_certificate; + } /* 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_READONLY))) { @@ -112,7 +116,8 @@ CRYPT_CONTEXT DLLCALL get_ssl_cert(scfg_t *cfg, char estr[SSL_ESTR_LEN]) /* 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); + if (estr) + sprintf(estr, "cryptlib error %d creating SSL context",i); return -1; } if(!DO(cryptSetAttributeString(ssl_context, CRYPT_CTXINFO_LABEL, "ssl_cert", 8))) @@ -159,6 +164,7 @@ CRYPT_CONTEXT DLLCALL get_ssl_cert(scfg_t *cfg, char estr[SSL_ESTR_LEN]) cryptKeysetClose(ssl_keyset); pthread_mutex_unlock(&ssl_cert_mutex); + cfg->tls_certificate = ssl_context; return ssl_context; failure_return_3: diff --git a/src/sbbs3/websrvr.c b/src/sbbs3/websrvr.c index 95176aa88c97e50284803fde7392837f354cebc8..513aa9f76247af96363f16237f36d51f513043e4 100644 --- a/src/sbbs3/websrvr.c +++ b/src/sbbs3/websrvr.c @@ -295,8 +295,6 @@ typedef struct { char peeked; } http_session_t; -static CRYPT_CONTEXT tls_context = -1; - enum { HTTP_0_9 ,HTTP_1_0 @@ -6229,9 +6227,9 @@ void http_session_thread(void* arg) } } #endif - if (tls_context != -1) { + if (scfg.tls_certificate != -1) { HANDLE_CRYPT_CALL(cryptSetAttribute(session.tls_sess, CRYPT_SESSINFO_SSL_OPTIONS, CRYPT_SSLOPTION_DISABLE_CERTVERIFY), &session); - HANDLE_CRYPT_CALL(cryptSetAttribute(session.tls_sess, CRYPT_SESSINFO_PRIVATEKEY, tls_context), &session); + HANDLE_CRYPT_CALL(cryptSetAttribute(session.tls_sess, CRYPT_SESSINFO_PRIVATEKEY, scfg.tls_certificate), &session); } BOOL nodelay=TRUE; setsockopt(session.socket,IPPROTO_TCP,TCP_NODELAY,(char*)&nodelay,sizeof(nodelay)); @@ -6482,11 +6480,6 @@ static void cleanup(int code) semfile_list_free(&recycle_semfiles); semfile_list_free(&shutdown_semfiles); - if (tls_context != -1) { - cryptDestroyContext(tls_context); - tls_context = -1; - } - if(!terminated) { /* Can this be changed to a if(ws_set!=NULL) check instead? */ xpms_destroy(ws_set, close_socket_cb, NULL); ws_set=NULL; @@ -6792,8 +6785,8 @@ void DLLCALL web_server(void* arg) if(startup->options&WEB_OPT_ALLOW_TLS) { lprintf(LOG_DEBUG,"Loading/Creating TLS certificate"); - tls_context = get_ssl_cert(&scfg, ssl_estr); - if (tls_context == -1) + get_ssl_cert(&scfg, ssl_estr); + if (scfg.tls_certificate == -1) lprintf(LOG_ERR, "Error creating TLS certificate: %s", ssl_estr); } @@ -6839,7 +6832,7 @@ void DLLCALL web_server(void* arg) * Add interfaces */ xpms_add_list(ws_set, PF_UNSPEC, SOCK_STREAM, 0, startup->interfaces, startup->port, "Web Server", open_socket, startup->seteuid, NULL); - if(tls_context != -1 && startup->options&WEB_OPT_ALLOW_TLS) { + if(scfg.tls_certificate != -1 && startup->options&WEB_OPT_ALLOW_TLS) { if(do_cryptInit()) xpms_add_list(ws_set, PF_UNSPEC, SOCK_STREAM, 0, startup->tls_interfaces, startup->tls_port, "Secure Web Server", open_socket, startup->seteuid, "TLS"); }