]> git.proxmox.com Git - pve-access-control.git/blobdiff - src/PVE/API2/TFA.pm
merge old user.cfg keys to tfa config when adding entries
[pve-access-control.git] / src / PVE / API2 / TFA.pm
index 2fbc7a8483bf7c452f9d4121864fb401d9492b3a..87d725573821ff3b408049e0a9c21a4a69739bde 100644 (file)
@@ -119,6 +119,33 @@ my sub root_permission_check : prototype($$$$) {
     return wantarray ? ($userid, $realm) : $userid;
 }
 
+# Set TFA to enabled if $tfa_cfg is passed, or to disabled if $tfa_cfg is undef,
+# When enabling we also merge the old user.cfg keys into the $tfa_cfg.
+my sub set_user_tfa_enabled : prototype($$$) {
+    my ($userid, $realm, $tfa_cfg) = @_;
+
+    PVE::AccessControl::lock_user_config(sub {
+       my $user_cfg = cfs_read_file('user.cfg');
+       my $user = $user_cfg->{users}->{$userid};
+       my $keys = $user->{keys};
+       # When enabling, we convert old-old keys,
+       # When disabling, we shouldn't actually have old keys anymore, so if they are there,
+       # they'll be removed.
+       if ($tfa_cfg && $keys && $keys !~ /^x(?:!.*)?$/) {
+           my $domain_cfg = cfs_read_file('domains.cfg');
+           my $realm_cfg = $domain_cfg->{ids}->{$realm};
+           die "auth domain '$realm' does not exist\n" if !$realm_cfg;
+
+           my $realm_tfa = $realm_cfg->{tfa};
+           $realm_tfa = PVE::Auth::Plugin::parse_tfa_config($realm_tfa) if $realm_tfa;
+
+           PVE::AccessControl::add_old_keys_to_realm_tfa($userid, $tfa_cfg, $realm_tfa, $keys);
+       }
+       $user->{keys} = $tfa_cfg ? 'x' : undef;
+       cfs_write_file("user.cfg", $user_cfg);
+    }, "enabling TFA for the user failed");
+}
+
 ### OLD API
 
 __PACKAGE__->register_method({
@@ -291,11 +318,15 @@ __PACKAGE__->register_method ({
        my $userid =
            root_permission_check($rpcenv, $authuser, $param->{userid}, $param->{password});
 
-       return PVE::AccessControl::lock_tfa_config(sub {
+       my $has_entries_left = PVE::AccessControl::lock_tfa_config(sub {
            my $tfa_cfg = cfs_read_file('priv/tfa.cfg');
-           $tfa_cfg->api_delete_tfa($userid, $param->{id});
+           my $has_entries_left = $tfa_cfg->api_delete_tfa($userid, $param->{id});
            cfs_write_file('priv/tfa.cfg', $tfa_cfg);
+           return $has_entries_left;
        });
+       if (!$has_entries_left) {
+           set_user_tfa_enabled($userid, undef, undef);
+       }
     }});
 
 __PACKAGE__->register_method ({
@@ -406,6 +437,9 @@ __PACKAGE__->register_method ({
 
        return PVE::AccessControl::lock_tfa_config(sub {
            my $tfa_cfg = cfs_read_file('priv/tfa.cfg');
+
+           set_user_tfa_enabled($userid, $realm, $tfa_cfg);
+
            PVE::AccessControl::configure_u2f_and_wa($tfa_cfg);
 
            my $response = $tfa_cfg->api_add_tfa_entry(