partially fix #2825: authkey: rotate if it was generated in the future master
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 3 Jul 2020 09:06:55 +0000 (11:06 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Sat, 4 Jul 2020 16:22:51 +0000 (18:22 +0200)
Can happen if the RTC is in the future during installation and first
boot, when during key generation the clock is in the future and then,
after the key was already generated, jumps back in time.

Allow a fuzz of $auth_graceperiod, which is currently 5 minutes, as
that fuzz allows some minor, not really problematic, time sync
disparity in clusters.

If an old authkey exists, meaning we rotated at least once, check it's
time too. Only rotate if it'd not be valid for any tickets in the
cluster anymore, i.e., if it difference between the current key is >
$ticket_lifetime (2 hours)..

Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
PVE/AccessControl.pm

index 78e5cc5..6a85c1a 100644 (file)
@@ -149,9 +149,22 @@ sub check_authkey {
        warn "auth key pair missing, generating new one..\n"  if !$quiet;
        return 0;
     } else {
-       if (time() - $mtime >= $authkey_lifetime) {
+       my $now = time();
+       if ($now - $mtime >= $authkey_lifetime) {
            warn "auth key pair too old, rotating..\n" if !$quiet;;
            return 0;
+       } elsif ($mtime > $now + $auth_graceperiod) {
+           # a nodes RTC had a time set in the future during key generation -> ticket
+           # validity is clamped to 0+5 min grace period until now >= mtime again
+           my (undef, $old_mtime) = get_pubkey(1);
+           if ($old_mtime && $mtime >= $old_mtime && $mtime - $old_mtime < $ticket_lifetime) {
+               warn "auth key pair generated in the future (key $mtime > host $now),"
+                   ." but old key still exists and in valid grace period so avoid automatic"
+                   ." fixup. Cluster time not in sync?\n" if !$quiet;
+               return 1;
+           }
+           warn "auth key pair generated in the future (key $mtime > host $now), rotating..\n" if !$quiet;
+           return 0;
        } else {
            warn "auth key new enough, skipping rotation\n" if !$quiet;;
            return 1;