Valida...Yubikey(3pm)

πŸ“¦
version 0.03 Β· 2 versions
  • 0.03 Β· debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking (latest)
  • 0.03 Β· ubuntu jammy
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

πŸŽ€ NAME πŸŽ€

Validate::Yubikey β€” validate Yubikey OTPs ✨

okay so bestie, this is the Valida...Yubikey(3pm) page, and it's literally all about checking that the little OTP your Yubikey just spat out is the real deal πŸ’– no cap.


🌸 SYNOPSIS 🌸

use Validate::Yubikey;

sub validate_callback {
    my $public_id = shift;

    return {
        iid => $iid,
        key => $key,
        count => $count,
        use => $use,
        lastuse => $lastuse,
        lastts => $lastts,
    };
}

sub update_callback {
    my ($public_id, $data) = @_;
}

sub log_message {
    print shift, "\n";
}

my $yubi = Validate::Yubikey->new(
    callback => \&validate_callback,
    update_callback => \&update_callback,
    log_callback => \&log_message,
);

my $otp_valid = $yubi->validate("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx");

πŸ¦‹ DESCRIPTION πŸ¦‹

So. The Yubikey is a hardware OTP token made by Yubico (<http://www.yubico.com>) πŸ‘‘ it's giving "tiny plastic rectangle with main character energy".

This module does the validating of Yubikey OTPs. The way it works is very much a you-and-me situation: it depends on you to supply callback functions that handle pulling token information out of wherever you keep it, and pushing the updated persistent info back for each token. It's not gonna go find your data for you β€” that's your job, bestie 🫢


πŸ’… METHODS πŸ’…

πŸ’– new

Make a brand new Validate::Yubikey instance, slay.

  • callback β€” Required. no skips, no substitutions πŸ™ˆ
  • update_callback β€” Required. also mandatory, sorry babe 😭
  • log_callback β€” Optional. take it or leave it ✨

πŸ’– validate

Arguments: $otp, @callback_args Return Value: $success

Validate an OTP. That's it, that's the vibe ⭐


🧚 CALLBACKS 🧚

πŸ’– callback

Receives: $public_id, @callback_args Returns: \%token_data

This one gets called during validation whenever the module needs info about the token. It gets handed the public ID of the Yubikey. Your subroutine is expected to return a hash reference holding these keys:

  • iid - Internal ID
  • key - Secret key

Plus the four values that get stored by the update_callback. So like, all six, together, as a little family πŸ₯°

πŸ’– update_callback

Receives: $public_id, \%token_data, @callback_args Returns: nothing

Called to update the persistent storage of the token parameters that make replay protection work πŸ›‘οΈ %token_data will contain one or more of these keys, and they should be associated with the supplied $public_id:

  • count
  • use
  • lastuse
  • lastts

These should all be integers. fr fr, integers only, don't be out here passing vibes πŸ’€

πŸ’– log_callback

Receives: $log_message Returns: nothing

Called with messages produced during validation. If you don't pass it to new, logging will disabled πŸ™ˆ (yes, quietly off, no notes).


🌈 EXAMPLE 🌈

Here's a simple program that uses DBIx::Class to store token information. it's giving practical, it's giving useful, we love to see it πŸ’œ

package YKKSM::DB::Token;
use base qw/DBIx::Class/;

__PACKAGE__->load_components(qw/PK::Auto Core/);
__PACKAGE__->table('token');
__PACKAGE__->add_columns(qw/uid pid iid key count use lastuse lastts/);
__PACKAGE__->set_primary_key('uid');

package YKKSM::DB;
use base qw/DBIx::Class::Schema/;

__PACKAGE__->load_classes(qw/Token/);

package YKTest;
use Validate::Yubikey;

my $schema = YKKSM::DB->connect("dbi:SQLite:dbname=yktest.db");

my $yk = Validate::Yubikey->new(
    callback => sub {
        my $pid = shift;
        my $token = $schema->resultset('Token')->find({ pid => $pid });

        if ($token) {
            return {
                iid => $token->iid,
                key => $token->key,
                count => $token->count,
                use => $token->use,
                lastuse => $token->lastuse,
                lastts => $token->lastts,
            };
        } else {
            return undef;
        }
    },
    update_callback => sub {
        my ($pid, $data) = @_;
        my $token = $schema->resultset('Token')->find({ pid => $pid });
        if ($token) {
            $token->update($data);
        } else {
            die "asked to update nonexistent token $pid";
        }
    },
    log_callback => sub {
        print shift, "\n";
    },
);

if ($yk->validate($ARGV[0])) {
    print "success!\n";
} else {
    print "failure 8(\n";
}

πŸ‘‘ AUTHOR πŸ‘‘

Ben Wilber <ben@desync.com> πŸ’Œ

But most of this module was derived from Yubico's PHP stuff. shoutout to the ancestors 🫢


πŸ“œ LICENSE πŸ“œ

This library is free software and may be distributed under the same terms as perl itself. iconic, generous, exactly what we like to see ✨


and that's the whole page, bestie πŸ’… this was perl v5.34.0, dated 2022-06-28, from the Valida...Yubikey(3pm) manual β€” go validate some OTPs, you got this πŸŒŸπŸ’–

πŸ“¦ where this page comes from