From e535aaac61c0e45e371144e4eeafc0f27c862727 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Deuc=D0=B5?= <shurd@sasktel.net>
Date: Mon, 8 Nov 2021 02:24:30 -0500
Subject: [PATCH] Keep track of certificate file timestamp and reload if it has
 changed

With the old method, it was possible for a certificate to remain used
eternally, and letsyncrypt.js can change it relatively often.
---
 src/sbbs3/scfgdefs.h |  1 +
 src/sbbs3/ssl.c      | 12 +++++++++---
 2 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/sbbs3/scfgdefs.h b/src/sbbs3/scfgdefs.h
index 602f147e90..29087ffae0 100644
--- a/src/sbbs3/scfgdefs.h
+++ b/src/sbbs3/scfgdefs.h
@@ -620,6 +620,7 @@ typedef struct
 
 	// Run-time state information (not configuration)
 	int				tls_certificate;
+	time_t                  tls_cert_file_date;
 
 } scfg_t;
 
diff --git a/src/sbbs3/ssl.c b/src/sbbs3/ssl.c
index 50f371dc7e..047d09b10c 100644
--- a/src/sbbs3/ssl.c
+++ b/src/sbbs3/ssl.c
@@ -290,12 +290,18 @@ CRYPT_CONTEXT get_ssl_cert(scfg_t *cfg, char **estr, int *level)
 	if(!do_cryptInit())
 		return -1;
 	pthread_mutex_lock(&ssl_cert_mutex);
+	SAFEPRINTF2(str,"%s%s",cfg->ctrl_dir,"ssl.cert");
+	time_t fd = fdate(str);
 	if (cfg->tls_certificate != -1 || !cfg->prepped) {
-		pthread_mutex_unlock(&ssl_cert_mutex);
-		return cfg->tls_certificate;
+		if (fd == cfg->tls_cert_file_date) {
+			pthread_mutex_unlock(&ssl_cert_mutex);
+			return cfg->tls_certificate;
+		}
+		cfg->tls_cert_file_date = fd;
+		cryptDestroyContext(cfg->tls_certificate);
 	}
+	cfg->tls_cert_file_date = fd;
 	/* 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))) {
 		if(!DO("getting private key", ssl_keyset, cryptGetPrivateKey(ssl_keyset, &ssl_context, CRYPT_KEYID_NAME, "ssl_cert", cfg->sys_pass))) {
 			pthread_mutex_unlock(&ssl_cert_mutex);
-- 
GitLab