[pve-devel] [PATCH v4 apiclient] fix #2227: enable totp codes to be passed in cli

Oguz Bektas o.bektas at proxmox.com
Fri Aug 16 13:51:34 CEST 2019


this patch enables to pass totp codes during cluster join if tfa has
been enabled for root at pam (or any other user actually, but having it enabled on
root causes problems during cluster join).

u2f support is not yet implemented.

Co-developed-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
Co-developed-by: Wolfgang Bumiller <w.bumiller at proxmox.com>
Signed-off-by: Oguz Bektas <o.bektas at proxmox.com>
---

v3->v4:
per thomas' suggestion:
* change error messages
* use a variable for the ticket regex for improved readability

 PVE/APIClient/LWP.pm | 31 +++++++++++++++++++++++++------
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/PVE/APIClient/LWP.pm b/PVE/APIClient/LWP.pm
index c0e30ff..97fd64f 100755
--- a/PVE/APIClient/LWP.pm
+++ b/PVE/APIClient/LWP.pm
@@ -92,6 +92,23 @@ sub update_ticket {
     $agent->default_header('Cookie', $cookie);
 }
 
+sub two_factor_auth_login {
+    my ($self, $type, $challenge) = @_;
+
+    if ($type eq 'PVE:tfa') {
+	raise("TFA-enabled login currently works only with a TTY.") if !-t STDIN;
+	print "\nEnter OTP code for user $self->{username}: ";
+	my $tfa_response = <STDIN>;
+	chomp $tfa_response;
+	return $self->post('/api2/json/access/tfa', {response => $tfa_response});
+    } elsif ($type eq 'PVE:u2f') {
+	# TODO: implement u2f-enabled join
+	raise("U2F-enabled login is currently not implemented.");
+    } else {
+	raise("Authentication type '$type' not recognized, aborting!");
+    }
+}
+
 sub login {
     my ($self) = @_;
 
@@ -129,15 +146,17 @@ sub login {
     my $res = from_json($response->decoded_content, {utf8 => 1, allow_nonref => 1});
 
     my $data = $extract_data->($res);
-
-    # TODO: make it possible to use tfa
-    if ($data->{ticket} =~ m/^PVE:tfa!/) {
-	raise("Two Factor Auth is not yet implemented! Try disabling TFA for the user '$username'.\n");
-    }
-
     $self->update_ticket($data->{ticket});
     $self->update_csrftoken($data->{CSRFPreventionToken});
 
+    # handle two-factor login
+    my $tfa_ticket_re = qr/^([^\s!]+)![^!]*(!([0-9a-zA-Z\/.=_\-+]+))?$/;
+    if ($data->{ticket} =~ m/$tfa_ticket_re/) {
+	my ($type, $challenge) = ($1, $2);
+	$data = $self->two_factor_auth_login($type, $challenge);
+	$self->update_ticket($data->{ticket});
+    }
+
     return $data;
 }
 
-- 
2.20.1



More information about the pve-devel mailing list