Auth-Yubikey_WebClient

 view release on metacpan or  search on metacpan

lib/Auth/Yubikey_WebClient.pm  view on Meta::CPAN

	print "otp            = $self->{otp}\n";
	print "publicid       = $self->{publicid}\n";
	print "t              = $self->{t}\n";
	print "sl             = $self->{sl}\n";
	print "timestamp      = $self->{timestamp}\n";
	print "sessioncounter = $self->{sessioncounter}\n";
	print "sessionuse     = $self->{sessionuse}\n";

#	print "response = $self->{response}\n";

}

=head2 yubikey_webclient

=cut

sub yubikey_webclient
{
	my ($otp,$id,$api,$nonce) = @_;

	my $yubi_tmp = new Auth::Yubikey_WebClient ( { id => $id, api => $api, nonce => $nonce } );

	return $yubi_tmp->otp($otp);
}

=head2 otp

Check a OTP for validity

	$result = $yubi->otp($otp);

Call the otp procedure with the input from the yubikey.  It will return the result.

This function will also setup a few internal variables that was returned from Yubico.

=cut

sub otp
{
        my ($self,$otp) = @_;

	chomp($otp);
	$self->{otp} = $otp;

	# lets do a basic sanity check on the otp, before we blast it off to yubico...
	if($self->{otp} !~ /[cbdefghijklnrtuv]/i || length($self->{otp}) < 32) 	{
		$self->{status} = "ERR_BAD_OTP";
		return $self->{status};
	}

	# Generate nonce unless passed
	$self->{nonce} = hmac_sha1_hex(time, rand()) unless $self->{nonce};

	# Start generating the parameters
	$self->{params} = "id=$self->{id}&nonce=$self->{nonce}&otp=" . uri_escape($self->{otp}) . "&timestamp=1";
	$self->{params} .= '&h=' . uri_escape(encode_base64(hmac_sha1($self->{params}, decode_base64($self->{api})), ''));

	# pass the request to yubico
	my $ua = LWP::UserAgent->new(ssl_opts => { verify_hostname => $self->{verify_hostname} });
	$ua->env_proxy();	# 4.02
	my $req = HTTP::Request->new(GET => $self->{url} . "?$self->{params}");
	my $res = $ua->request($req);
	if($res->is_success) {
		$self->{response} = $res->content;
	} else {
		print $res->status_line . "\n";
	}
	chomp($self->{response});

	if($self->{response} !~ /status=ok/i) {
		# If the status is not ok, let's not even go through the rest...
		$self->{response} =~ m/status=(.+)/;
		$self->{status} = "ERR_$1";
		$self->{status} =~ s/\s//g;
		return $self->{status};
	}

	#extract each of the lines, and store in a hash...

	my %result;
	foreach (split(/\n/,$self->{response})) {
		chomp;
                if($_ =~ /=/)
                {
                        ($a,$b) = split(/=/,$_,2);
                        $b =~ s/\s//g;
                        $result{$a} = $b;
			$self->{$a} = $b;
                }
        }

        # save the h parameter, that's what we'll be comparing to

        my $signatur=$result{h};
        delete $result{h};
        my $datastring='';

	my $key;
        foreach $key (sort keys %result) {
                $result{$key} =~ s/\s//g;
                $datastring .= "$key=$result{$key}&";
        }
        $datastring = substr($datastring,0,length($datastring)-1);

	# Check that nonce and OTP are the ones we asked for
	$self->{status} = "ERR_MSG_AUTH";

	return "ERR_MSG_AUTH" unless ($self->{nonce} eq $result{nonce} and $self->{otp} eq $result{otp});

  	my $hmac = encode_base64(hmac_sha1($datastring,decode_base64($self->{api})));
	chomp($hmac);
  	if($hmac eq $signatur) {
		$self->{publicid} = substr(lc($self->{otp}),0,12);
		$self->{status} = "OK";
                return "OK";
   } else {
		$self->{status} = "ERR_HMAC";
		return "ERR_HMAC";
	}
}



( run in 1.282 second using v1.01-cache-2.11-cpan-39bf76dae61 )