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}) . "×tamp=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 )