line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Session::Token; |
2
|
|
|
|
|
|
|
|
3
|
6
|
|
|
6
|
|
3517
|
use strict; |
|
6
|
|
|
|
|
10
|
|
|
6
|
|
|
|
|
171
|
|
4
|
|
|
|
|
|
|
|
5
|
6
|
|
|
6
|
|
28
|
use Carp qw/croak/; |
|
6
|
|
|
|
|
10
|
|
|
6
|
|
|
|
|
371
|
|
6
|
6
|
|
|
6
|
|
4607
|
use POSIX qw/ceil/; |
|
6
|
|
|
|
|
47043
|
|
|
6
|
|
|
|
|
33
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
our $VERSION = '1.501'; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
require XSLoader; |
12
|
|
|
|
|
|
|
XSLoader::load('Session::Token', $VERSION); |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
my $default_alphabet = join('', ('0'..'9', 'a'..'z', 'A'..'Z',)); |
16
|
|
|
|
|
|
|
my $default_entropy = 128; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
my $is_windows; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
if ($^O =~ /mswin/i) { |
21
|
|
|
|
|
|
|
require Crypt::Random::Source::Strong::Win32; |
22
|
|
|
|
|
|
|
$is_windows = 1; |
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
sub new { |
27
|
16
|
|
|
16
|
0
|
28068
|
my ($class, @args) = @_; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
## support arguments in a hash ref |
30
|
16
|
100
|
66
|
|
|
81
|
@args = %{$args[0]} if @args == 1 && ref $args[0] eq 'HASH'; |
|
1
|
|
|
|
|
5
|
|
31
|
|
|
|
|
|
|
|
32
|
16
|
|
|
|
|
51
|
my %args = @args; |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
## Init seed |
36
|
|
|
|
|
|
|
|
37
|
16
|
|
|
|
|
24
|
my $seed; |
38
|
|
|
|
|
|
|
|
39
|
16
|
100
|
|
|
|
54
|
if (defined $args{seed}) { |
40
|
|
|
|
|
|
|
croak "seed argument should be a 1024 byte long bytestring" |
41
|
5
|
50
|
|
|
|
19
|
unless length($args{seed}) == 1024; |
42
|
5
|
|
|
|
|
12
|
$seed = $args{seed}; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
16
|
100
|
|
|
|
39
|
if (!defined $seed) { |
46
|
11
|
50
|
|
|
|
20
|
if ($is_windows) { |
47
|
0
|
|
|
|
|
0
|
my $windows_rng_source = Crypt::Random::Source::Strong::Win32->new; |
48
|
0
|
|
|
|
|
0
|
$seed = $windows_rng_source->get(1024); |
49
|
0
|
0
|
|
|
|
0
|
die "Win32 RNG source didn't provide 1024 bytes" unless length($seed) == 1024; |
50
|
|
|
|
|
|
|
} else { |
51
|
11
|
|
|
|
|
12
|
my ($fh, $err1, $err2); |
52
|
|
|
|
|
|
|
|
53
|
11
|
50
|
|
|
|
289
|
open($fh, '<:raw', '/dev/urandom') || ($err1 = $!); |
54
|
11
|
50
|
0
|
|
|
25
|
open($fh, '<:raw', '/dev/arandom') || ($err2 = $!) |
55
|
|
|
|
|
|
|
unless defined $fh; |
56
|
|
|
|
|
|
|
|
57
|
11
|
50
|
|
|
|
23
|
if (!defined $fh) { |
58
|
0
|
|
|
|
|
0
|
croak "unable to open /dev/urandom ($err1) or /dev/arandom ($err2)"; |
59
|
|
|
|
|
|
|
} |
60
|
|
|
|
|
|
|
|
61
|
11
|
50
|
|
|
|
1422
|
sysread($fh, $seed, 1024) == 1024 || croak "unable to read from random device: $!"; |
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
## Init alphabet |
67
|
|
|
|
|
|
|
|
68
|
16
|
100
|
|
|
|
56
|
my $alphabet = defined $args{alphabet} ? $args{alphabet} : $default_alphabet; |
69
|
16
|
100
|
|
|
|
58
|
$alphabet = join('', @$alphabet) if ref $alphabet eq 'ARRAY'; |
70
|
|
|
|
|
|
|
|
71
|
16
|
50
|
33
|
|
|
90
|
croak "alphabet must be between 2 and 256 bytes long" |
72
|
|
|
|
|
|
|
if length($alphabet) < 2 || length($alphabet) > 256; |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
## Init token length |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
croak "you can't specify both length and entropy" |
78
|
16
|
50
|
66
|
|
|
57
|
if defined $args{length} && defined $args{entropy}; |
79
|
|
|
|
|
|
|
|
80
|
16
|
|
|
|
|
20
|
my $token_length; |
81
|
|
|
|
|
|
|
|
82
|
16
|
100
|
|
|
|
47
|
if (defined $args{length}) { |
83
|
4
|
50
|
33
|
|
|
40
|
croak "bad value for length" unless $args{length} =~ m/^\d+$/ && $args{length} > 0; |
84
|
4
|
|
|
|
|
8
|
$token_length = $args{length}; |
85
|
|
|
|
|
|
|
} else { |
86
|
12
|
|
66
|
|
|
47
|
my $entropy = $args{entropy} || $default_entropy; |
87
|
12
|
50
|
|
|
|
25
|
croak "bad value for entropy" unless $entropy > 0; |
88
|
12
|
|
|
|
|
44
|
my $alphabet_entropy = log(length($alphabet)) / log(2); |
89
|
12
|
|
|
|
|
81
|
$token_length = ceil($entropy / $alphabet_entropy); |
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
|
93
|
16
|
|
|
|
|
378
|
return _new_context($seed, $alphabet, $token_length); |
94
|
|
|
|
|
|
|
} |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
1; |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
__END__ |