From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id B80167D89B for ; Tue, 9 Nov 2021 12:28:23 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8DDECAFB5 for ; Tue, 9 Nov 2021 12:27:26 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id EB459AF71 for ; Tue, 9 Nov 2021 12:27:24 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id C10CA42CF2 for ; Tue, 9 Nov 2021 12:27:24 +0100 (CET) From: Wolfgang Bumiller To: pve-devel@lists.proxmox.com Date: Tue, 9 Nov 2021 12:26:59 +0100 Message-Id: <20211109112721.130935-11-w.bumiller@proxmox.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211109112721.130935-1-w.bumiller@proxmox.com> References: <20211109112721.130935-1-w.bumiller@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.549 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [accesscontrol.pm] Subject: [pve-devel] [PATCH access-control 04/10] handle yubico authentication in new path X-BeenThere: pve-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox VE development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Nov 2021 11:28:23 -0000 Signed-off-by: Wolfgang Bumiller --- src/PVE/AccessControl.pm | 60 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/src/PVE/AccessControl.pm b/src/PVE/AccessControl.pm index d61d7f4..29d22ac 100644 --- a/src/PVE/AccessControl.pm +++ b/src/PVE/AccessControl.pm @@ -624,6 +624,7 @@ sub check_token_exist { return undef; } +# deprecated sub verify_one_time_pw { my ($type, $username, $keys, $tfa_cfg, $otp) = @_; @@ -715,7 +716,7 @@ sub authenticate_2nd_old : prototype($$$) { sub authenticate_2nd_new : prototype($$$$) { my ($username, $realm, $otp, $tfa_challenge) = @_; - return lock_tfa_config(sub { + my $result = lock_tfa_config(sub { my ($tfa_cfg, $realm_tfa) = user_get_tfa($username, $realm, 1); if (!defined($tfa_cfg)) { @@ -724,11 +725,28 @@ sub authenticate_2nd_new : prototype($$$$) { my $realm_type = $realm_tfa && $realm_tfa->{type}; if (defined($realm_type) && $realm_type eq 'yubico') { - $tfa_cfg->set_yubico_config({ - id => $realm_tfa->{id}, - key => $realm_tfa->{key}, - url => $realm_tfa->{url}, - }); + # Yubico auth will not be supported in rust for now... + if (!defined($tfa_challenge)) { + my $challenge = { yubico => JSON::true }; + # Even with yubico auth we do allow recovery keys to be used: + if (my $recovery = $tfa_cfg->recovery_state($username)) { + $challenge->{recovery} = $recovery; + } + return to_json($challenge); + } + + if ($otp =~ /^yubico:(.*)$/) { + $otp = $1; + # Defer to after unlocking the TFA config: + return sub { + authenticate_yubico_new($tfa_cfg, $username, $realm_tfa, $tfa_challenge, $otp); + }; + } + + # Beside the realm configured auth we only allow recovery keys: + if ($otp !~ /^recovery:/) { + die "realm requires yubico authentication\n"; + } } configure_u2f_and_wa($tfa_cfg); @@ -755,6 +773,36 @@ sub authenticate_2nd_new : prototype($$$$) { return $tfa_challenge; }); + + # Yubico auth returns the authentication sub: + if (ref($result) eq 'CODE') { + $result = $result->(); + } + + return $result; +} + +sub authenticate_yubico_new : prototype($$$) { + my ($tfa_cfg, $username, $realm, $tfa_challenge, $otp) = @_; + + $tfa_challenge = verify_ticket($tfa_challenge, 0, $username); + $tfa_challenge = from_json($tfa_challenge); + + if (!$tfa_challenge->{yubico}) { + die "no such challenge\n"; + } + + my $keys = $tfa_cfg->get_yubico_keys($username); + die "no keys configured\n" if !defined($keys) || !length($keys); + + # Defer to after unlocking the TFA config: + + # fixme: proxy support? + my $proxy; + PVE::OTP::yubico_verify_otp($otp, $keys, $realm->{url}, $realm->{id}, $realm->{key}, $proxy); + + # return `undef` to clear the tfa challenge. + return undef; } sub configure_u2f_and_wa : prototype($) { -- 2.30.2