]> git.proxmox.com Git - pve-access-control.git/blobdiff - PVE/AccessControl.pm
followup: s/CUSTOM_TFA_TYPES/USER_CONTROLLED_TFA_TYPES/
[pve-access-control.git] / PVE / AccessControl.pm
index 655f306fd0d3326f0747e8512858a1f84d20db20..af1bd6a673b39434f199005b4962137a6e0018b9 100644 (file)
@@ -265,11 +265,11 @@ my $get_ticket_age_range = sub {
 };
 
 sub assemble_ticket {
-    my ($username) = @_;
+    my ($data) = @_;
 
     my $rsa_priv = get_privkey();
 
-    return PVE::Ticket::assemble_rsa_ticket($rsa_priv, 'PVE', $username);
+    return PVE::Ticket::assemble_rsa_ticket($rsa_priv, 'PVE', $data);
 }
 
 sub verify_ticket {
@@ -290,23 +290,44 @@ sub verify_ticket {
            $rsa_pub, 'PVE', $ticket, undef, $min, $max, 1);
     };
 
-    my ($username, $age) = $check->();
+    my ($data, $age) = $check->();
 
     # check with old, rotated key if current key failed
-    ($username, $age) = $check->(1) if !defined($username);
+    ($data, $age) = $check->(1) if !defined($data);
 
-    if (!defined($username)) {
+    my $auth_failure = sub {
        if ($noerr) {
            return undef;
        } else {
            # raise error via undef ticket
            PVE::Ticket::verify_rsa_ticket(undef, 'PVE');
        }
+    };
+
+    if (!defined($data)) {
+       return $auth_failure->();
+    }
+
+    my ($username, $challenge);
+    if ($data =~ m{^u2f!([^!]+)!([0-9a-zA-Z/.=_\-+]+)$}) {
+       # Ticket for u2f-users:
+       ($username, $challenge) = ($1, $2);
+       if ($challenge eq 'verified') {
+           # u2f challenge was completed
+           $challenge = undef;
+       } elsif (!wantarray) {
+           # The caller is not aware there could be an ongoing challenge,
+           # so we treat this ticket as invalid:
+           return $auth_failure->();
+       }
+    } else {
+       # Regular ticket (full access)
+       $username = $data;
     }
 
     return undef if !PVE::Auth::Plugin::verify_username($username, $noerr);
 
-    return wantarray ? ($username, $age) : $username;
+    return wantarray ? ($username, $age, $challenge) : $username;
 }
 
 # VNC tickets
@@ -1333,7 +1354,7 @@ sub remove_vm_from_pool {
     lock_user_config($delVMfromPoolFn, "pool cleanup for VM $vmid failed");
 }
 
-my $CUSTOM_TFA_TYPES = {
+my $USER_CONTROLLED_TFA_TYPES = {
     u2f => 1,
     oath => 1,
 };
@@ -1380,7 +1401,7 @@ sub user_set_tfa {
        # The 'yubico' type requires yubico server settings, which have to be configured on the
        # realm, so this is not supported here:
        die "domain '$realm' does not support TFA type '$type'\n"
-           if defined($data) && !$CUSTOM_TFA_TYPES->{$type};
+           if defined($data) && !$USER_CONTROLLED_TFA_TYPES->{$type};
     }
 
     # Custom TFA entries are stored in priv/tfa.cfg as they can be more complet: u2f uses a