From 3f9c2e7ff0394163128f002647ffb3dbc5a65a4e Mon Sep 17 00:00:00 2001 From: Vladislav Grishenko Date: Tue, 25 Feb 2020 21:52:11 +0500 Subject: [PATCH] Add broken-rtc = .conf file setting HTTPS certificates are only valid within specified time windows, so on systems without hardware real-time clock and default bootup time far in the past, false-positive validation fail is expected. When this setting is enabled, i.e. true, then inadyn will only issue a warning that the certificate is not valid yet. By default this set- ting is disabled, because security matters. --- include/ssl.h | 1 + man/inadyn.conf.5 | 11 +++++++++++ src/conf.c | 2 ++ src/gnutls.c | 5 ++++- src/main.c | 1 + src/openssl.c | 5 ++++- 6 files changed, 23 insertions(+), 2 deletions(-) diff --git a/include/ssl.h b/include/ssl.h index df3d8670..7d1969b9 100644 --- a/include/ssl.h +++ b/include/ssl.h @@ -31,6 +31,7 @@ extern char *ca_trust_file; /* Cert validation is enabled by default, user can disable in .conf file */ extern int secure_ssl; +extern int broken_rtc; #ifdef ENABLE_SSL int ssl_init(void); diff --git a/man/inadyn.conf.5 b/man/inadyn.conf.5 index d1fdbc45..29ba8767 100644 --- a/man/inadyn.conf.5 +++ b/man/inadyn.conf.5 @@ -90,6 +90,17 @@ then .Nm inadyn will only issue a warning. By default this setting is enabled, because security matters. +.It Cm broken-rtc = < true | false > +HTTPS certificates are only valid within specified time windows, so on +systems without hardware real-time clock and default bootup time far in +the past, false-positive validation fail is expected. When this setting +is enabled, i.e. +.Ar true , +then +.Nm inadyn +will only issue a warning +that the certificate is not valid yet. By default this setting is +disabled, because security matters. .It Cm ca-trust-file = FILE By default .Nm inadyn diff --git a/src/conf.c b/src/conf.c index 0c4aa608..9fd3bd45 100644 --- a/src/conf.c +++ b/src/conf.c @@ -565,6 +565,7 @@ cfg_t *conf_parse_file(char *file, ddns_t *ctx) CFG_BOOL("fake-address", cfg_false, CFGF_NONE), CFG_BOOL("allow-ipv6", cfg_false, CFGF_NONE), CFG_BOOL("secure-ssl", cfg_true, CFGF_NONE), + CFG_BOOL("broken-rtc", cfg_false, CFGF_NONE), CFG_STR ("ca-trust-file", NULL, CFGF_NONE), CFG_STR ("cache-dir", NULL, CFGF_DEPRECATED | CFGF_DROP), CFG_INT ("period", DDNS_DEFAULT_PERIOD, CFGF_NONE), @@ -625,6 +626,7 @@ cfg_t *conf_parse_file(char *file, ddns_t *ctx) user_agent = DDNS_USER_AGENT; allow_ipv6 = cfg_getbool(cfg, "allow-ipv6"); secure_ssl = cfg_getbool(cfg, "secure-ssl"); + broken_rtc = cfg_getbool(cfg, "broken-rtc"); ca_trust_file = cfg_getstr(cfg, "ca-trust-file"); if (ca_trust_file && !fexist(ca_trust_file)) { logit(LOG_ERR, "Cannot find CA trust file %s", ca_trust_file); diff --git a/src/gnutls.c b/src/gnutls.c index 98e4df54..fb853244 100644 --- a/src/gnutls.c +++ b/src/gnutls.c @@ -63,8 +63,11 @@ static int verify_certificate_callback(gnutls_session_t session) if (status & GNUTLS_CERT_EXPIRED) logit(LOG_WARNING, "The certificate has expired."); - if (status & GNUTLS_CERT_NOT_ACTIVATED) + if (status & GNUTLS_CERT_NOT_ACTIVATED) { logit(LOG_WARNING, "The certificate is not yet activated."); + if (broken_rtc && (status &= ~GNUTLS_CERT_NOT_ACTIVATED) == GNUTLS_CERT_INVALID) + status = 0; + } if (status & GNUTLS_CERT_INVALID) { logit(LOG_ERR, "The certificate is not trusted."); diff --git a/src/main.c b/src/main.c index b3dfc136..b0533949 100644 --- a/src/main.c +++ b/src/main.c @@ -40,6 +40,7 @@ int ignore_errors = 0; int startup_delay = DDNS_DEFAULT_STARTUP_SLEEP; int allow_ipv6 = 0; int secure_ssl = 1; /* Strict cert validation by default */ +int broken_rtc = 0; /* Validate certificate time by default */ char *ca_trust_file = NULL; /* Custom CA trust file/bundle PEM format */ int verify_addr = 1; char *prognm = NULL; diff --git a/src/openssl.c b/src/openssl.c index a8802ef5..cc2ba6b9 100644 --- a/src/openssl.c +++ b/src/openssl.c @@ -69,9 +69,12 @@ static int verify_callback(int preverify_ok, X509_STORE_CTX *ctx) X509_STORE_CTX_set_error(ctx, err); } - if (!preverify_ok) + if (!preverify_ok) { logit(LOG_ERR, "Certificate verification error:num=%d:%s:depth=%d:%s", err, X509_verify_cert_error_string(err), depth, buf); + if (broken_rtc && err == X509_V_ERR_CERT_NOT_YET_VALID) + preverify_ok = 1; + } /* * At this point, err contains the last verification error. We can use