File Coverage

blib/lib/Apache2/AuthAny/Cookie.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package Apache2::AuthAny::Cookie;
2              
3 1     1   1366 use strict;
  1         3  
  1         104  
4              
5 1     1   963 use CGI::Cookie ();
  1         23808  
  1         34  
6 1     1   1058 use Apache2::Cookie ();
  0            
  0            
7             use Apache2::Request ();
8             use Digest::MD5 qw(md5_hex);
9              
10             use Apache2::AuthAny::DB ();
11             use Apache2::AuthAny::AuthUtil ();
12             use Data::Dumper qw(Dumper);
13              
14             use Apache2::Const -compile => qw(HTTP_UNAUTHORIZED REDIRECT OK);
15             our $aaDB;
16             our $VERSION = '0.201';
17              
18             sub post_login {
19             my $r = shift;
20             my $uri = $r->uri;
21              
22             my ($authProvider) = ($uri =~ m{/aa_auth/(.*?)/});
23             $authProvider =~ s/_aa-key_.*//;
24              
25             my $get_params = Apache2::Request->new($r);
26             my $location = $get_params->param('req');
27             unless ($location) {
28             $r->log->warn("Apache2::AuthAny::Cookie: missing req redirect after login with $authProvider");
29             $location = "/";
30             }
31              
32             $aaDB = Apache2::AuthAny::DB->new() unless $aaDB;
33             unless ($aaDB) {
34             my $msg = "Cannot connect to database.";
35             $r->log->crit("AuthAny::Cookie: $msg");
36             return Apache2::AuthAny::AuthUtil::goToGATE($r, 'tech', {msg => $msg});
37             }
38              
39             my $authId = $ENV{REMOTE_USER} || $r->user;
40             if ($authId) {
41             my $map_file = "$ENV{AUTH_ANY_CONFIG_ROOT}/provider-mapping.pl";
42             if (-f $map_file) {
43             open(MAPPING, "<$map_file") || die "$map_file ?? $!";
44             my @cts = ;
45             my $contents = "@cts";
46             close(MAPPING);
47             my $mapping = eval $contents;
48             if ($mapping->{$authProvider}) {
49             my $orig = $authId;
50             $authId =~ s/$mapping->{$authProvider}//;
51             if ($authId eq $orig) {
52             $r->log->error("AuthAny::Cookie: mapping had no effect");
53             }
54             }
55             }
56             } else {
57             my $msg = 'Please try another login method';
58             $r->log->error("Cookie: Auth method at '$uri' did not set REMOTE_USER");
59             return Apache2::AuthAny::AuthUtil::goToGATE($r, 'authen', {msg => $msg});
60             }
61              
62             ######################################################################
63             # Cookie
64             ######################################################################
65              
66             my $pid = $r->pnotes('pid');
67             my $sCookie = md5_hex(time . rand);
68             if ($aaDB->loginPCookie($pid->{PID}, $sCookie, $authId, $authProvider)) {
69             my $new_sid_cookie = CGI::Cookie->new(-name => 'AA_SID',
70             -value => $sCookie,
71             );
72             $r->err_headers_out->add('Set-Cookie' => $new_sid_cookie);
73             } else {
74             my $msg = "Could not write to DB";
75             $r->log->crit("Apache2::AuthAny::Cookie: " . $msg);
76             return Apache2::AuthAny::AuthUtil::goToGATE($r, 'authen', {msg => $msg});
77             }
78              
79             blank_shibsession($r);
80              
81             $r->headers_out->set(Location => $location);
82             $r->log->info("Apache2::AuthAny::Cookie: Location => $location");
83             return Apache2::Const::REDIRECT;
84              
85             }
86              
87             # NOTE: These are not a handlers
88             sub cookie_util {
89             my $r = shift;
90             $aaDB = Apache2::AuthAny::DB->new() unless $aaDB;
91             my $jar = Apache2::Cookie::Jar->new($r);
92             my @cookies;
93             my ($pidCookie, $sidCookie);
94              
95             eval {
96             if ($jar && $jar->cookies) {
97             $sidCookie = $jar->cookies->get('AA_SID')->value if $jar->cookies->get('AA_SID');
98             $pidCookie = $jar->cookies->get('AA_PID')->value if $jar->cookies->get('AA_PID');
99             @cookies = $jar->cookies;
100             }
101             };
102             if ($@) {
103             $r->log->error("Cookie error $@");
104             }
105             my $shibsession_name;
106             my $shibsession_value;
107             foreach my $cookie (@cookies) {
108             if ($cookie =~ /_shibsession_/) {
109             $r->log->error("Cookie: duplicate shibsession cookies found") if $shibsession_name;
110             $shibsession_name = $cookie;
111             $shibsession_value = $jar->cookies($shibsession_name);
112             }
113             }
114              
115             return {pidCookie => $pidCookie,
116             sidCookie => $sidCookie,
117             shibsession_name => $shibsession_name,
118             shibsession_value => $shibsession_value,
119             };
120             }
121              
122             sub blank_shibsession {
123             my $r = shift;
124              
125             my $cookies = cookie_util($r);
126             if ($cookies->{shibsession_value}) {
127             my $shib_empty = CGI::Cookie->new(-name => $cookies->{shibsession_name},
128             -value => '',
129             );
130             $r->err_headers_out->add('Set-Cookie' => $shib_empty);
131             }
132             }
133              
134             sub pid {
135             my $r = shift;
136             my $cookies = cookie_util($r);
137             my $pid;
138             my $pCookie = $cookies->{pidCookie};
139             my $sCookie = $cookies->{sidCookie};
140              
141             if ($pCookie) {
142             $pid = $aaDB->getUserCookieByPID($pCookie) || {};
143             if ($pid && $pid->{PID}) {
144             unless ($sCookie && $pid->{SID} && $sCookie eq $pid->{SID}) {
145             # There has been no login during this session
146             $pid->{SID} = '';
147             }
148             } else {
149             $r->log->error("AuthAny: " . "PID, '$pCookie' missing from DB");
150             $pid = generate_pid($r);
151             }
152             } else {
153             $pid = generate_pid($r);
154             }
155             # warn $r->uri . " --- " . Dumper($pid);
156             return $pid;
157             }
158              
159             sub generate_pid {
160             my $r = shift;
161              
162             my $pCookie = md5_hex(time . rand);
163             my $sCookie = md5_hex(time . rand);
164             my $logout_key = md5_hex(time . rand);
165              
166             if ($aaDB->insertPCookie($pCookie, $sCookie, $logout_key)) {
167             my $new_pid_cookie = CGI::Cookie->new(-name => 'AA_PID',
168             -value => $pCookie,
169             -expires => '+3y',
170             );
171             my $new_sid_cookie = CGI::Cookie->new(-name => 'AA_SID',
172             -value => $sCookie,
173             );
174             $r->err_headers_out->add('Set-Cookie' => $new_pid_cookie);
175             $r->err_headers_out->add('Set-Cookie' => $new_sid_cookie);
176             return {PID => $pCookie,
177             SID => $sCookie,
178             logoutKey => $logout_key,
179             state => 'logged_out',
180             };
181             } else {
182             die "AuthAny::Cookie: Could not write to DB";
183             }
184             }
185              
186              
187             1;