File Coverage

blib/lib/LWP/Authen/Digest.pm
Criterion Covered Total %
statement 49 49 100.0
branch 10 14 71.4
condition 4 5 80.0
subroutine 3 3 100.0
pod 0 1 0.0
total 66 72 91.6


line stmt bran cond sub pod time code
1             package LWP::Authen::Digest;
2             $LWP::Authen::Digest::VERSION = '6.29';
3 1     1   7 use strict;
  1         2  
  1         33  
4 1     1   5 use base 'LWP::Authen::Basic';
  1         2  
  1         828  
5              
6             require Digest::MD5;
7              
8             sub auth_header {
9 8     8 0 21 my($class, $user, $pass, $request, $ua, $h) = @_;
10              
11 8         13 my $auth_param = $h->{auth_param};
12              
13 8         34 my $nc = sprintf "%08X", ++$ua->{authen_md5_nonce_count}{$auth_param->{nonce}};
14 8         20 my $cnonce = sprintf "%8x", time;
15              
16 8         19 my $uri = $request->uri->path_query;
17 8 50       165 $uri = "/" unless length $uri;
18              
19 8         50 my $md5 = Digest::MD5->new;
20              
21 8         13 my(@digest);
22 8         37 $md5->add(join(":", $user, $auth_param->{realm}, $pass));
23 8         28 push(@digest, $md5->hexdigest);
24 8         20 $md5->reset;
25              
26 8         13 push(@digest, $auth_param->{nonce});
27              
28 8 50       18 if ($auth_param->{qop}) {
29 8 50       29 push(@digest, $nc, $cnonce, ($auth_param->{qop} =~ m|^auth[,;]auth-int$|) ? 'auth' : $auth_param->{qop});
30             }
31              
32 8         23 $md5->add(join(":", $request->method, $uri));
33 8         105 push(@digest, $md5->hexdigest);
34 8         20 $md5->reset;
35              
36 8         28 $md5->add(join(":", @digest));
37 8         25 my($digest) = $md5->hexdigest;
38 8         19 $md5->reset;
39              
40 8         13 my %resp = map { $_ => $auth_param->{$_} } qw(realm nonce opaque);
  24         58  
41 8         34 @resp{qw(username uri response algorithm)} = ($user, $uri, $digest, "MD5");
42              
43 8 50 50     44 if (($auth_param->{qop} || "") =~ m|^auth([,;]auth-int)?$|) {
44 8         25 @resp{qw(qop cnonce nc)} = ("auth", $cnonce, $nc);
45             }
46              
47 8         21 my(@order) = qw(username realm qop algorithm uri nonce nc cnonce response);
48 8 100       17 if($request->method =~ /^(?:POST|PUT)$/) {
49 2         24 $md5->add($request->content);
50 2         28 my $content = $md5->hexdigest;
51 2         6 $md5->reset;
52 2         9 $md5->add(join(":", @digest[0..1], $content));
53 2         5 $md5->reset;
54 2         5 $resp{"message-digest"} = $md5->hexdigest;
55 2         5 push(@order, "message-digest");
56             }
57 8         63 push(@order, "opaque");
58 8         10 my @pairs;
59 8         15 for (@order) {
60 82 100       146 next unless defined $resp{$_};
61              
62             # RFC2617 says that qop-value and nc-value should be unquoted.
63 74 100 100     175 if ( $_ eq 'qop' || $_ eq 'nc' ) {
64 16         40 push(@pairs, "$_=" . $resp{$_});
65             }
66             else {
67 58         138 push(@pairs, "$_=" . qq("$resp{$_}"));
68             }
69             }
70              
71 8         30 my $auth_value = "Digest " . join(", ", @pairs);
72 8         65 return $auth_value;
73             }
74              
75             1;