systime-fix: Add timeout option to stop waiting for valid system time
authorTobias Brunner <tobias@strongswan.org>
Tue, 26 Sep 2017 08:32:04 +0000 (10:32 +0200)
committerTobias Brunner <tobias@strongswan.org>
Wed, 8 Nov 2017 15:20:35 +0000 (16:20 +0100)
A certificate check is forced once the timeout is reached even if the
system time appears to be invalid.

conf/plugins/systime-fix.opt
src/libcharon/plugins/systime_fix/systime_fix_plugin.c

index 7abd036..714981a 100644 (file)
@@ -10,3 +10,7 @@ charon.plugins.systime-fix.threshold =
 
 charon.plugins.systime-fix.threshold_format = %Y
        **strptime**(3) format used to parse threshold option.
+
+charon.plugins.systime-fix.timeout = 0s
+       How long to wait for a valid system time if an interval is configured. 0 to
+       recheck indefinitely.
index c1594b0..3209c91 100644 (file)
@@ -1,6 +1,6 @@
 /*
- * Copyright (C) 2013 Tobias Brunner
- * Hochschule fuer Technik Rapperswil
+ * Copyright (C) 2013-2017 Tobias Brunner
+ * HSR Hochschule fuer Technik Rapperswil
  *
  * Copyright (C) 2013 Martin Willi
  * Copyright (C) 2013 revosec AG
@@ -55,6 +55,11 @@ struct private_systime_fix_plugin_t {
        u_int interval;
 
        /**
+        * How long to wait for a valid system time, 0 to wait indefinitely
+        */
+       time_t timeout;
+
+       /**
         * Timestamp where we start considering system time valid
         */
        time_t threshold;
@@ -118,6 +123,23 @@ static bool has_invalid_certs(ike_sa_t *ike_sa)
 }
 
 /**
+ * Check if we reached the timeout
+ */
+static inline bool timeout_reached(private_systime_fix_plugin_t *this)
+{
+       if (this->timeout == 0)
+       {       /* disabled */
+               return FALSE;
+       }
+       if (this->timeout <= this->interval)
+       {
+               return TRUE;
+       }
+       this->timeout -= this->interval;
+       return FALSE;
+}
+
+/**
  * Check system time, reevaluate certificates
  */
 static job_requeue_t check_systime(private_systime_fix_plugin_t *this)
@@ -129,15 +151,23 @@ static job_requeue_t check_systime(private_systime_fix_plugin_t *this)
 
        if (time(NULL) < this->threshold)
        {
-               DBG2(DBG_CFG, "systime not valid, rechecking in %ds", this->interval);
-               lib->scheduler->schedule_job(lib->scheduler, (job_t*)
-                                       callback_job_create((callback_job_cb_t)check_systime, this,
-                                                                               NULL, NULL), this->interval);
-               return JOB_REQUEUE_NONE;
+               if (!timeout_reached(this))
+               {
+                       DBG2(DBG_CFG, "system time not valid, rechecking in %us",
+                                this->interval);
+                       return JOB_RESCHEDULE(this->interval);
+               }
+               DBG1(DBG_CFG, "timeout reached while waiting for valid system time, "
+                        "force rechecking certificates");
+               /* force regular lifetime checks for new connections */
+               lib->credmgr->remove_validator(lib->credmgr,
+                                                                          &this->validator->validator);
+       }
+       else
+       {
+               DBG1(DBG_CFG, "system time got valid, rechecking certificates");
        }
 
-       DBG1(DBG_CFG, "system time got valid, rechecking certificates");
-
        enumerator = charon->ike_sa_manager->create_enumerator(
                                                                                                charon->ike_sa_manager, TRUE);
        while (enumerator->enumerate(enumerator, &ike_sa))
@@ -225,7 +255,7 @@ static bool plugin_cb(private_systime_fix_plugin_t *this,
                lib->credmgr->add_validator(lib->credmgr, &this->validator->validator);
                if (this->interval != 0)
                {
-                       DBG1(DBG_CFG, "starting systime check, interval: %ds",
+                       DBG1(DBG_CFG, "starting system time check, interval: %us",
                                 this->interval);
                        lib->scheduler->schedule_job(lib->scheduler, (job_t*)
                                        callback_job_create((callback_job_cb_t)check_systime,
@@ -275,6 +305,8 @@ plugin_t *systime_fix_plugin_create()
                },
                .interval = lib->settings->get_int(lib->settings,
                                                "%s.plugins.%s.interval", 0, lib->ns, get_name(this)),
+               .timeout = lib->settings->get_time(lib->settings,
+                                               "%s.plugins.%s.timeout", 0, lib->ns, get_name(this)),
                .reauth = lib->settings->get_bool(lib->settings,
                                                "%s.plugins.%s.reauth", FALSE, lib->ns, get_name(this)),
        );