File Coverage

blib/lib/Protocol/DBus/Authn/Mechanism/DBUS_COOKIE_SHA1.pm
Criterion Covered Total %
statement 49 57 85.9
branch 3 6 50.0
condition 1 5 20.0
subroutine 14 15 93.3
pod 0 3 0.0
total 67 86 77.9


line stmt bran cond sub pod time code
1             package Protocol::DBus::Authn::Mechanism::DBUS_COOKIE_SHA1;
2              
3             # https://dbus.freedesktop.org/doc/dbus-specification.html#auth-mechanisms-sha
4              
5 5     5   2170 use strict;
  5         15  
  5         125  
6 5     5   20 use warnings;
  5         15  
  5         130  
7              
8 5     5   20 use parent qw( Protocol::DBus::Authn::Mechanism );
  5         10  
  5         25  
9              
10 5     5   180 use Protocol::DBus::Authn::Mechanism::DBUS_COOKIE_SHA1::Pieces ();
  5         10  
  5         55  
11              
12 5     5   20 use File::Spec ();
  5         10  
  5         85  
13              
14             my $sha_module;
15              
16 5     5   15 use constant must_send_initial => 0;
  5         10  
  5         215  
17              
18             use constant {
19 5         2980 DEBUG => 0,
20 5     5   25 };
  5         10  
21              
22             sub new {
23 2     2 0 13 my ($class) = @_;
24              
25 2         6 local $@;
26              
27 2 50       7 if ( eval { require Digest::SHA1; 1 } ) {
  2 50       451  
  0         0  
28 0         0 $sha_module = 'Digest::SHA1';
29             }
30 2         1645 elsif ( eval { require Digest::SHA; 1 } ) {
  2         7064  
31 2         28 $sha_module = 'Digest::SHA';
32             }
33             else {
34 0         0 die "No SHA module available!";
35             }
36              
37 2         51 return $class->SUPER::new( @_[ 1 .. $#_ ] );
38             }
39              
40             sub INITIAL_RESPONSE {
41 2     2 0 11 my ($self) = @_;
42              
43 2         11 return unpack( 'H*', ($self->_getpw())[0] );
44             }
45              
46             sub AFTER_AUTH {
47 2     2 0 56 my ($self) = @_;
48              
49             return (
50             [ 1 => sub {
51 2     2   20 _consume_data($self, @_);
52 2         62 } ],
53             [ 0 => \&_authn_respond_data ],
54             );
55             }
56              
57             sub _getpw {
58 0     0   0 my ($self) = @_;
59              
60 0   0     0 $self->{'_pw'} ||= [ getpwuid $> ];
61              
62 0         0 return @{ $self->{'_pw'} };
  0         0  
63             }
64              
65             sub _consume_data {
66 2     2   9 my ($self, $authn, $line) = @_;
67              
68 2 50       12 if (0 != index($line, 'DATA ')) {
69 0         0 die "Invalid line: [$line]";
70             }
71              
72 2         7 substr( $line, 0, 5, q<> );
73              
74 2         27 my ($ck_ctx, $ck_id, $sr_challenge) = split m< >, pack( 'H*', $line );
75              
76 2         4 if (DEBUG()) {
77             print STDERR (
78             "AUTHN/SHA1 context: $ck_ctx$/",
79             "AUTHN/SHA1 cookie ID: $ck_id$/",
80             "AUTHN/SHA1 server challenge: $sr_challenge$/",
81             );
82             }
83              
84 2         27 my $cookie = $self->_get_cookie($ck_ctx, $ck_id);
85              
86 2         12 my $cl_challenge = _create_challenge();
87              
88 2         29 my $str = join(
89             ':',
90             $sr_challenge,
91             $cl_challenge,
92             $cookie,
93             );
94              
95 2         11 my $str_digest = _sha1_hex($str);
96              
97 2         5 if (DEBUG()) {
98             print STDERR (
99             "AUTHN/SHA1 cookie: $cookie$/",
100             "AUTHN/SHA1 client challenge: $ck_id$/",
101             "AUTHN/SHA1 string: $str$/",
102             );
103             }
104              
105 2         32 $authn->{'_sha1_response'} = unpack 'H*', "$cl_challenge $str_digest";
106              
107 2         18 return;
108             }
109              
110             sub _authn_respond_data {
111             return (
112             'DATA',
113 2   33 2   28 $_[0]->{'_sha1_response'} || do {
114             die "No SHA1 DATA response set!";
115             },
116             );
117             }
118              
119             *_sha1_hex = \&Protocol::DBus::Authn::Mechanism::DBUS_COOKIE_SHA1::Pieces::sha1_hex;
120              
121             *_create_challenge = \&Protocol::DBus::Authn::Mechanism::DBUS_COOKIE_SHA1::Pieces::create_challenge;
122              
123             sub _get_cookie {
124 2     2   10 my ($self, $ck_ctx, $ck_id) = @_;
125              
126 2         12 return Protocol::DBus::Authn::Mechanism::DBUS_COOKIE_SHA1::Pieces::get_cookie(
127             ($self->_getpw())[7],
128             $ck_ctx,
129             $ck_id,
130             );
131             }
132              
133             1;