paper-token/paper-token.pl

153 lines
4 KiB
Perl
Raw Normal View History

#!/usr/bin/perl -w
#
# paper token is a software to generate paper-based OTP
#
# Copyright (C) 2010 Alexandre Dulaunoy, http://www.foo.be/
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
use Authen::HOTP qw(hotp);
use PDF::API2;
use PDF::Table;
use Data::Dumper;
use Getopt::Compact;
# default value is the test vector from RFC 4226
my $secret = "3132333435363738393031323334353637383930";
# starting counter
my $counter = 0;
# ending counter
my $end = 500;
my $digits = 6;
my @tokentable = [];
# window value (shown on one line and window of accepted token)
my $window = 14;
my $when = localtime();
my $opt = new Getopt::Compact(
name => 'paper token - http://www.foo.be/paper-token/',
modes => '',
version => '0.1',
struct => [
[
[qw(s secret)],
qq(secret of the token in hex format - default is RFC 4226 test vector),
':s'
],
[ [qw(o output)], qq(output filename), ':s' ],
[ [qw(c counter)], qq(starting counter - default is 0), ':i' ],
[ [qw(e end)], qq(ending counter - default is 500), ':i' ],
[
[qw(w window)],
qq(window of authentication (one line) - default is 14), ':i'
],
[
[qw(d digits)],
qq(digits showed per OTP value - default is 6 - dec31.6), ':i'
],
]
);
my $opts = $opt->opts;
if ( !( defined( $opts->{output} ) ) ) {
print $opt->usage;
exit();
}
if ( defined( $opts->{counter} ) ) {
$counter = $opts->{counter};
}
if ( defined( $opts->{end} ) ) {
$end = $opts->{end};
}
if ( defined( $opts->{window} ) ) {
$window = $opts->{window};
}
if ( defined( $opts->{secret} ) ) {
$secret = $opts->{secret};
}
my $sn = substr( $secret, 0, 10 );
if ( defined( $opts->{digits} ) ) {
$digits = $opts->{digits};
}
for ( $count = $counter ; $count < $counter + $end ; $count = $count + $window )
{
my @tj;
for ( $j = $count ; $j < $count + $window ; $j = $j + 1 ) {
my $pass = hotp( $secret, $j, $digits );
push( @tj, "$pass" );
}
@val = ["@tj"];
push( @{ $tokentable[0] }, @val );
}
my $pdftable = new PDF::Table;
my $pdf = new PDF::API2( -file => $opts->{output} );
my $page = $pdf->page;
my $gfx = $page->gfx;
my $tokeninfo = "Paper token for HOTP token S/N : " . $sn;
my $tokenhowto =
"How to use? Read from left to right and when you use a token, strikethrough the used value.";
my $tokenadv =
"Generated by paper token - http://www.foo.be/paper-token/ at " . $when;
$pdf->info(
'Author' => "Alexandre Dulaunoy - http://www.foo.be/",
'Creator' => "Paper Token - http://www.foo.be/paper-token/",
'Producer' => "PDF::API2",
'Title' => $tokeninfo,
);
$fnt = $pdf->corefont('Helvetica-Bold');
$fntlow = $pdf->corefont('Helvetica');
$gfx->textlabel( 10, 750, $fnt, 11, $tokeninfo );
$gfx->textlabel( 10, 739, $fntlow, 11, $tokenhowto );
$gfx->textlabel( 10, 728, $fntlow, 11, $tokenadv );
$pdftable->table(
$pdf,
$page,
@tokentable,
-x => 1,
-w => 40,
-start_y => 700,
-next_y => 700,
-start_h => 700,
-next_h => 700,
-w => 600,
-padding => 2,
-padding_right => 1,
-background_color_odd => "lightgray",
-background_color_even => "gray",
font => $pdf->corefont( "Helvetica", -encoding => "utf8" ),
font_size => 11,
border => 0
);
$pdf->save();