[pve-devel] [PATCH common] fix #2023: try out all available yubico api endpoints

Dominik Csapak d.csapak at proxmox.com
Tue Apr 9 09:21:24 CEST 2019


one comment inline

On 4/9/19 9:11 AM, Thomas Lamprecht wrote:
> While we moved to the new v2 API a bit ago we still only ever tried
> a single hard coded endpoint, but yubico say:
> 
>> To ensure high-availability, configure your client to
>> simultaneously issue requests to all five addresses and accept the
>> first successful reply.
> -- yubico server status site [0]
> 
> For now I ommitted the initial parallel requesting, it's a best
> effort try, serialized.
> That could be added on top of this later one, if desired, either by
> just forking and starting connections in parallel, or some anyevent
> like async request.
> 
> But lets hope we can save this complexity completely and wait out
> until yubico sets up a single highly-available API endpoint. Until
> then this is a cheap "one can only win" approach.
> 
> [0]: https://status.yubico.com/2018/11/26/deprecating-yubicloud-v1-protocol-plain-text-requests-and-old-tls-versions/
> 
> Signed-off-by: Thomas Lamprecht <t.lamprecht at proxmox.com>
> ---
> 
> best (re)viewed with git's ignore all space option (-w) to ignore indentation
> only changes
> 
>   src/PVE/OTP.pm | 38 +++++++++++++++++++++++++++++---------
>   1 file changed, 29 insertions(+), 9 deletions(-)
> 
> diff --git a/src/PVE/OTP.pm b/src/PVE/OTP.pm
> index 019076b..f9b6654 100644
> --- a/src/PVE/OTP.pm
> +++ b/src/PVE/OTP.pm
> @@ -46,7 +46,7 @@ sub yubico_compute_param_sig {
>   }
>   
>   sub yubico_verify_otp {
> -    my ($otp, $keys, $url, $api_id, $api_key, $proxy) = @_;
> +    my ($otp, $keys, $api_url, $api_id, $api_key, $proxy) = @_;
>   
>       die "yubico: missing password\n" if !defined($otp);
>       die "yubico: missing API ID\n" if !defined($api_id);
> @@ -55,7 +55,17 @@ sub yubico_verify_otp {
>   
>       die "yubico: wrong OTP length\n" if (length($otp) < 32) || (length($otp) > 48);
>   
> -    $url = 'https://api2.yubico.com/wsapi/2.0/verify' if !defined($url);
> +    my $urls;
> +    if (!defined($api_url)) {
> +	# see https://status.yubico.com/2018/11/26/deprecating-yubicloud-v1-protocol-plain-text-requests-and-old-tls-versions/
> +	$urls = [
> +	    map { "https://api${_}.yubico.com/wsapi/2.0/verify" } (''), (2..5)
> +	];
> +    } elsif (!ref($api_url)) {
> +	$urls = [ $api_url ];
> +    } else {
> +	$urls = $api_url;
> +    }
>   
>       my $params = {
>   	nonce =>  Digest::SHA::hmac_sha1_hex(time(), rand()),
> @@ -68,8 +78,6 @@ sub yubico_verify_otp {
>   
>       $paramstr .= "&h=$sig" if $api_key;
>   
> -    my $req = HTTP::Request->new('GET' => "$url?$paramstr");
> -
>       my $ua = LWP::UserAgent->new(protocols_allowed => ['http', 'https'], timeout => 30);
>   
>       if ($proxy) {
> @@ -78,13 +86,25 @@ sub yubico_verify_otp {
>   	$ua->env_proxy;
>       }
>   
> -    my $response = $ua->request($req);
> -    my $code = $response->code;
> +    my ($response, $lasterr);
> +    for my $url (@$urls) {
> +	my $req = HTTP::Request->new('GET' => "$url?$paramstr");
>   
> -    if ($code != 200) {
> -	my $msg = $response->message || 'unknown';
> -	die "Invalid response from server: $code $msg\n";
> +	$response = $ua->request($req);
> +	my $code = $response->code;
> +
> +	if ($code != 200) {
> +	    $lasterr = $response->message || 'unknown';
> +	    warn "Invalid response from '$url': $code $lasterr\n";
> +	    next;
> +	} else {
> +	    $lasterr = undef;
i guess there is a 'last' missing here?
else we always try all even if we already had a successful attempt ? or 
am i missing something?

> +	}
>       }
> +    # just report last error to user, don't throw > 5, possible identical, errors
> +    # at him, they're logged above for an admin already..
> +    die "Could not connect to any yubico OTP API server specified: $lasterr\n"
> +	if defined($lasterr);
>   
>       my $raw = $response->decoded_content;
>   
> 





More information about the pve-devel mailing list