X-Git-Url: https://git.proxmox.com/?p=pve-access-control.git;a=blobdiff_plain;f=PVE%2FAPI2%2FAccessControl.pm;h=f01180d138863ee50c21c25bf5f32b9868efb00b;hp=1679ed45eb4c0d6ff81682eb967fbce3c5521cfd;hb=96f8ebd62506bc7126d58400004101ef6a13ca71;hpb=437be042c2497a1956b359bb9e2797f838a37340 diff --git a/PVE/API2/AccessControl.pm b/PVE/API2/AccessControl.pm index 1679ed4..f01180d 100644 --- a/PVE/API2/AccessControl.pm +++ b/PVE/API2/AccessControl.pm @@ -88,7 +88,7 @@ __PACKAGE__->register_method ({ my $verify_auth = sub { - my ($rpcenv, $username, $pw_or_ticket, $path, $privs) = @_; + my ($rpcenv, $username, $pw_or_ticket, $otp, $path, $privs) = @_; my $normpath = PVE::AccessControl::normalize_path($path); @@ -99,7 +99,7 @@ my $verify_auth = sub { } elsif (PVE::AccessControl::verify_vnc_ticket($pw_or_ticket, $username, $normpath, 1)) { # valid vnc ticket } else { - $username = PVE::AccessControl::authenticate_user($username, $pw_or_ticket); + $username = PVE::AccessControl::authenticate_user($username, $pw_or_ticket, $otp); } my $privlist = [ PVE::Tools::split_list($privs) ]; @@ -111,14 +111,14 @@ my $verify_auth = sub { }; my $create_ticket = sub { - my ($rpcenv, $username, $pw_or_ticket) = @_; + my ($rpcenv, $username, $pw_or_ticket, $otp) = @_; my $ticketuser; if (($ticketuser = PVE::AccessControl::verify_ticket($pw_or_ticket, 1)) && ($ticketuser eq 'root@pam' || $ticketuser eq $username)) { # valid ticket. Note: root@pam can create tickets for other users } else { - $username = PVE::AccessControl::authenticate_user($username, $pw_or_ticket); + $username = PVE::AccessControl::authenticate_user($username, $pw_or_ticket, $otp); } my $ticket = PVE::AccessControl::assemble_ticket($username); @@ -206,6 +206,18 @@ my $compute_api_permission = sub { return $res; }; +__PACKAGE__->register_method ({ + name => 'get_ticket', + path => 'ticket', + method => 'GET', + permissions => { user => 'world' }, + description => "Dummy. Useful for formaters which want to priovde a login page.", + parameters => { + additionalProperties => 0, + }, + returns => { type => "null" }, + code => sub { return undef; }}); + __PACKAGE__->register_method ({ name => 'create_ticket', path => 'ticket', @@ -231,6 +243,11 @@ __PACKAGE__->register_method ({ description => "The secret password. This can also be a valid ticket.", type => 'string', }, + otp => { + description => "One-time password for Two-factor authentication.", + type => 'string', + optional => 1, + }, path => { description => "Verify ticket, and check if user have access 'privs' on 'path'", type => 'string', @@ -264,22 +281,22 @@ __PACKAGE__->register_method ({ my $rpcenv = PVE::RPCEnvironment::get(); my $res; - eval { # test if user exists and is enabled $rpcenv->check_user_enabled($username); if ($param->{path} && $param->{privs}) { - $res = &$verify_auth($rpcenv, $username, $param->{password}, + $res = &$verify_auth($rpcenv, $username, $param->{password}, $param->{otp}, $param->{path}, $param->{privs}); } else { - $res = &$create_ticket($rpcenv, $username, $param->{password}); + $res = &$create_ticket($rpcenv, $username, $param->{password}, $param->{otp}); } }; if (my $err = $@) { my $clientip = $rpcenv->get_client_ip() || ''; syslog('err', "authentication failure; rhost=$clientip user=$username msg=$err"); - die $err; + # do not return any info to prevent user enumeration attacks + die PVE::Exception->new("authentication failure\n", code => 401); } $res->{cap} = &$compute_api_permission($rpcenv, $username);