mirror of
https://git.proxmox.com/git/pve-access-control
synced 2025-10-04 14:18:28 +00:00
use TFA authentication api v2
Previously `authentication_verify` just `die`d on error and would only return a boolean whether `priv/tfa.cfg` needs updating as a positive result. Since we want to support locking TOTP as well as a general TFA lock-out via the config, we also want to be able to tell when this occurs. Most of it is handled by the TFA rust crate already, but notifying users needs to be done on this end instead. In pve-rs we now have a different API for this: `authentication_verify2`, which, instead of die()ing on errors, always returns a hash containing the result as well as the flags 'tfa-limit-reached' and 'totp-limit-reached' which, if set, tell us to notify the user. However, doing so will introduce new fields in the `priv/tfa.cfg` in a struct marked as `deny_unknown_fields`, so in a cluster, the limits & notification handling should only be done once we can be sure that all nodes are up to date. These fields are only introduced on login errors, so for now, handle a failed result early without saving `priv/tfa.cfg`. The only case where saving the file was previously required was when *successfully* logging in with a recovery key, by which we cannot be reaching a limit, so this should still be safe. Once we can validate that all cluster nodes are up to date, we can implement the notification system. A commented-out code structure for this is included in this patch. Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
95fb22e696
commit
d9f02efe49
2
debian/control
vendored
2
debian/control
vendored
@ -30,7 +30,7 @@ Depends: libauthen-pam-perl,
|
||||
libnet-ssleay-perl,
|
||||
libpve-cluster-perl,
|
||||
libpve-common-perl (>= 6.0-18),
|
||||
libpve-rs-perl (>= 0.4.3),
|
||||
libpve-rs-perl (>= 0.7.6),
|
||||
libpve-u2f-server-perl (>= 1.0-2),
|
||||
liburi-perl,
|
||||
libuuid-perl,
|
||||
|
@ -834,24 +834,50 @@ sub authenticate_2nd_new_do : prototype($$$$) {
|
||||
|
||||
configure_u2f_and_wa($tfa_cfg);
|
||||
|
||||
my $must_save = 0;
|
||||
my ($result, $tfa_done);
|
||||
if (defined($tfa_challenge)) {
|
||||
$tfa_done = 1;
|
||||
$tfa_challenge = verify_ticket($tfa_challenge, 0, $username);
|
||||
$must_save = $tfa_cfg->authentication_verify($username, $tfa_challenge, $tfa_response);
|
||||
$result = $tfa_cfg->authentication_verify2($username, $tfa_challenge, $tfa_response);
|
||||
$tfa_challenge = undef;
|
||||
} else {
|
||||
$tfa_challenge = $tfa_cfg->authentication_challenge($username);
|
||||
if (defined($tfa_response)) {
|
||||
if (defined($tfa_challenge)) {
|
||||
$must_save = $tfa_cfg->authentication_verify($username, $tfa_challenge, $tfa_response);
|
||||
$tfa_done = 1;
|
||||
$result = $tfa_cfg->authentication_verify2($username, $tfa_challenge, $tfa_response);
|
||||
} else {
|
||||
die "no such challenge\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($must_save) {
|
||||
cfs_write_file('priv/tfa.cfg', $tfa_cfg);
|
||||
if ($tfa_done) {
|
||||
if (!$result) {
|
||||
# authentication_verify2 somehow returned undef - should be unreachable
|
||||
die "2nd factor failed\n";
|
||||
}
|
||||
|
||||
# FIXME: Remove this case when enabling the ones below!
|
||||
if (!$result->{result}) {
|
||||
die "2nd factor failed\n";
|
||||
}
|
||||
|
||||
if ($result->{'needs-saving'}) {
|
||||
cfs_write_file('priv/tfa.cfg', $tfa_cfg);
|
||||
}
|
||||
# FIXME: Switch to the code below to use the updated `priv/tfa.cfg` format!
|
||||
#if ($result->{'totp-limit-reached'}) {
|
||||
# # FIXME: send mail to the user (or admin/root if no email configured)
|
||||
# die "failed 2nd factor: TOTP limit reached, locked\n";
|
||||
#}
|
||||
#if ($result->{'tfa-limit-reached'}) {
|
||||
# # FIXME: send mail to the user (or admin/root if no email configured)
|
||||
# die "failed 1nd factor: TFA limit reached, user locked out\n";
|
||||
#}
|
||||
#if (!$result->{result}) {
|
||||
# die "failed 2nd factor\n";
|
||||
#}
|
||||
}
|
||||
|
||||
return $tfa_challenge;
|
||||
|
Loading…
Reference in New Issue
Block a user