File Coverage

blib/lib/AIS/client.pm
Criterion Covered Total %
statement 40 104 38.4
branch 10 48 20.8
condition 4 12 33.3
subroutine 5 7 71.4
pod 0 3 0.0
total 59 174 33.9


line stmt bran cond sub pod time code
1             package AIS::client;
2              
3 1     1   40202 use 5.006;
  1         5  
  1         124  
4             $VERSION = 0.07;
5 1     1   7 use Carp;
  1         2  
  1         558  
6              
7 1     1   6117 use DirDB 0.09; # or any other concurrent-access-safe
  1         7006  
  1         1903  
8             # persistence abstraction
9             # that can store and retreive hash references
10             # and has a working DELETE method
11             #
12             # but if you change it, you'll also need to change
13             # the lines that refer to DirDB subsequently,
14             # including the tieing of %{"caller().'::AIS_STASH'}
15              
16             sub miniget($$$$){
17 0     0 0 0 my($HostName, $PortNumber, $Desired, $agent) = @_;
18 0         0 eval <<'ENDMINIGET';
19             use Socket qw(:DEFAULT :crlf);
20             $PortNumber ||= 80;
21             $agent ||= "$ENV{SERVER_NAME}$ENV{SCRIPT_NAME}";
22             my $iaddr = inet_aton($HostName) || die "Cannot find host named $HostName";
23             my $paddr = sockaddr_in($PortNumber,$iaddr);
24             my $proto = getprotobyname('tcp');
25              
26             socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
27             connect(SOCK, $paddr) || die "connect: $!";
28              
29             # SOCK->autoflush(1);
30             my $ofh = select SOCK;
31             $| = 1;
32             select $ofh;
33             my $Query = join("\r\n", # "CRLF"
34             "GET $Desired HTTP/1.1",
35             # Do we need a Host: header with an "AbsoluteURI?"
36             # not needed: http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.2
37             # but this is trumped by an Apache error message invoking RFC2068 sections 9 and 14.23
38             "Host: $HostName",
39             "User-Agent: $agent",
40             "Connection: close",
41             '','') ;
42             print SOCK $Query or croak "could not print to miniget socket";
43              
44             join('',);
45              
46             ENDMINIGET
47              
48             }
49              
50             sub housekeeping(){
51              
52 0     0 0 0 my @deletia;
53 0         0 my $t = time;
54              
55 0         0 while(($k,$v) = each %Sessions){
56              
57 0 0       0 if ($v->{last_access} < ($t - $maxage)){
58 0         0 push @deletia, $k
59             };
60             };
61              
62 0         0 @Sessions{@deletia} = ();
63             };
64              
65             sub redirect($){
66 1     1 0 31 print <
67             Location: $_[0]
68             Content-Type: text/html
69              
70             Relocate
71            
72            
73            
74            
75            

Trying to relocate to $_[0]

please click
76             here.
77            
78              
79             EOF
80              
81             };
82              
83             sub import{
84 1     1   11 shift;
85 1         3 my %params = @_;
86              
87 1         3 my $Coo;
88              
89 1 50       8 $ssl_ext = exists($ENV{SSL_CIPHER}) ? 's' : '';
90 1 50       6 $freq = (defined($params{freq}) ? $params{freq} : 2000);
91 1   50     9 $maxage = $params{maxage} || 72*60*60;
92 1   50     6 $aissri = $params{aissri} || 'http://www.pay2send.com/cgi/ais/';
93 1   33     8 $agent = $params{agent} ||
94             "http$ssl_ext://$ENV{SERVER_NAME}$ENV{SCRIPT_NAME}";
95 1   50     7 $SessionPrefix = $params{prefix} || 'AIS'; # 'AIS_session';
96              
97 1         1 eval{
98 1         9 tie %Sessions => DirDB => "${SessionPrefix}_sessions";
99             };
100 1 50       216 if($@){
101 0         0 print <
102             Content-Type: text/plain
103              
104             AIS::client module was not able to open DirDB [${SessionPrefix}_sessions]
105              
106             eval result:
107              
108             $@
109              
110             AIS::client version $VERSION
111              
112             EOF
113              
114 0         0 exit;
115              
116             };
117 1 50       4 if($freq){
118 1 50       17 housekeeping unless ($$ % $freq)
119             };
120              
121 1 50       5 if ($ENV{QUERY_STRING} eq 'LOGOUT'){
122             # eval <<'LOGOUT';
123 0 0       0 ($Coo) = ($ENV{HTTP_COOKIE} =~ /${SessionPrefix}_session=(\w+)/)
124             and delete $Sessions{$Coo};
125              
126 0         0 print <
127             Set-Cookie:/${SessionPrefix}_session=
128             Content-Type: text/html
129              
130             LOGGED OUT
131            
132              
133             Cookie cleared, you are logged out of "${SessionPrefix}"
134            

135            
136             click here to log out of AIS service $aissri
137              
138            
139             EOF
140              
141 0         0 exit;
142             # LOGOUT
143              
144             };
145              
146              
147             # check for cookies
148 1         15 ($Coo) = ($ENV{HTTP_COOKIE} =~ /${SessionPrefix}_session=(\w+)/);
149 1 50       4 if($Coo){
150             # print "Content-Type: text/plain\n\n";
151             # print "We have a cookie: $Coo\n";
152             # print( %{$Sessions{$Coo}});
153             # exit;
154             # Do we have an identity?
155 0 0 0     0 if (exists($Sessions{$Coo}->{identity}) and $Sessions{$Coo}->{identity} ne 'ERROR'){
156             # most of the time, this is what we are expecting
157 0         0 goto HAVE_ID ; # unless $Sessions{$Coo}->{identity} eq 'ERROR';
158             }else{
159             # eval <<'NOIDENTITYEVAL';
160             # get an identity from the AIS server
161             # (process might be underway already)
162 0 0       0 if ($ENV{QUERY_STRING} =~ /^OTU_KEY=(\w+)/){
163             # eval <<'HAVEOTUKEYEVAL';
164 0         0 my $OTUkey = $1;
165             # carp "have aissri [$aissri]";
166 0 0       0 my ($method, $host, $port, $path) =
167             ($aissri =~ m#^(\w+)://([^:/]+):?(\d*)(.+)$#)
168             or die "Could not get meth,hos,por,pat from aissri <$aissri>";
169             # carp "have \$method, \$host, \$port, \$path $method, $host, $port, $path";
170 0 0       0 unless ($method eq 'http'){
171 0         0 croak "aissri parameter must begin 'http://' at this time";
172             };
173              
174             # issue the AIS QUERY request
175             # carp "doing miniget $host, $port,${aissri}query?$OTUkey, $agent";
176              
177 0         0 my $Response = miniget $host, $port,
178             "${aissri}query?$OTUkey", $agent;
179              
180             # carp "got $Response";
181 0 0       0 (my $AISXML) =
182             $Response =~ m#(.+)#si
183             or die "no element from ${aissri}query?$OTUkey\n in BEGINRESPONSE\n$Response\nENDRESPONSE";
184 0         0 $Sessions{$Coo}->{AISXML} = $AISXML;
185             # parse AISXML...
186 0         0 my %aisvar;
187 0         0 foreach (qw{
188             identity
189             error
190             aissri
191             user_remote_addr
192             }
193             # ,@{$Param{XML}}
194             ){
195 0 0       0 $AISXML =~ m#<$_>(.+)#si or next;
196 0         0 $aisvar{$_} = $1;
197             # print STDERR "ais var $_ is $1\n";
198             };
199              
200 0 0       0 if ($aisvar{identity} eq 'NULL'){
201 0         0 redirect(
202             "$aisvar{aissri}add?RU=http$ssl_ext://$ENV{SERVER_NAME}$ENV{SCRIPT_NAME}$ENV{PATH_INFO}");
203 0         0 exit;
204             };
205              
206             # hooray! we have an identity.
207 0         0 foreach (keys %aisvar){
208 0         0 $Sessions{$Coo}->{$_} = $aisvar{$_};
209             };
210              
211             #reconstruct initial form data if any
212 0         0 $ENV{QUERY_STRING} = delete $Sessions{$Coo}->{QueryString};
213 0 0       0 if(exists $Sessions{$Coo}->{PostData}){
214 0 0       0 pipe(POSTREAD,POSTWRITE) or die "Cannot create pipe: $!";
215 0 0       0 if (fork){
216             # we are in parent
217 0         0 close POSTWRITE;
218 0         0 open STDIN, "<&POSTREAD";
219 0         0 $ENV{REQUEST_METHOD} = 'POST';
220              
221             }else{
222             # in child -- write POSTdata to pipe and exit
223 0         0 close STDOUT;
224 0         0 close STDIN;
225 0         0 close POSTREAD;
226 0         0 print POSTWRITE delete $Sessions{$Coo}->{PostData};
227 0 0       0 close POSTWRITE or die "$$: Error closing POSTWRITE\n";
228             # exit;
229             #POSIX:_exit(0); # perldoc -f exit
230 0         0 exec '/usr/bin/true';
231             };
232             # HAVEOTUKEYEVAL
233             };
234 0         0 goto HAVE_ID;
235             }else{
236             # redirect us to AIS server PRESENT function
237              
238 0         0 redirect "${aissri}present?http$ssl_ext://$ENV{SERVER_NAME}$ENV{SCRIPT_NAME}$ENV{PATH_INFO}?OTU_KEY=";
239 0         0 exit;
240              
241              
242             };
243              
244             # NOIDENTITYEVAL
245             };
246             }else{
247             # no cookie.
248 1         2 my $suffix = '';
249 1 50       4 if($ENV{QUERY_STRING}eq'AIS_INITIAL'){
250             # for when the first time we were called with the wrong host name.
251 0         0 $suffix = 2;
252             };
253 1 50       3 $ENV{QUERY_STRING}eq'AIS_INITIAL2'and goto NOCOO;
254 1         60 ($Coo = localtime) =~ s/\W//g;
255 1         6 my @chars = 'A'..'Z' ;
256             substr($Coo, rand(length $Coo), 1) = $chars[rand @chars]
257 1         61 foreach 1..8;
258 1         72 print "X-Ais-Received-Request-Method: $ENV{REQUEST_METHOD}\n";
259 1         22 print "X-Ais-Received-Query-String: $ENV{QUERY_STRING}\n";
260 1         14 $Sessions{$Coo}->{QueryString} = $ENV{QUERY_STRING};
261 1 50       719 $ENV{REQUEST_METHOD} =~ /POST/i and
262             $Sessions{$Coo}->{PostData} = <>;
263              
264 1         39 print "Set-Cookie:/${SessionPrefix}_session=$Coo\n";
265 1         14 redirect "http$ssl_ext://$ENV{SERVER_NAME}$ENV{SCRIPT_NAME}$ENV{PATH_INFO}?AIS_INITIAL$suffix";
266 1         1159 exit;
267             };
268              
269 0           print <
270             Content-Type: text/plain
271              
272             internal AIS module logic error
273              
274             EOF
275              
276 0           exit;
277              
278              
279              
280              
281              
282              
283 0           NOCOO:
284             print <
285             Content-Type: text/plain
286              
287             Cookies appear to be disabled in your web browser.
288              
289             Cookie string: $ENV{HTTP_COOKIE}
290              
291             This program uses a session and authentication system
292             (AIS, the Authenticated Identity Service)
293             that relies on cookies.
294              
295             Please enable cookies and try again. (you may have to log in)
296              
297             *******************************************************************
298              
299             You appear to be using a $ENV{HTTP_USER_AGENT}
300             from $ENV{REMOTE_ADDR}
301             to access http$ssl_ext://$ENV{SERVER_NAME}$ENV{SCRIPT_NAME}
302             (this web server is adminned by $ENV{SERVER_ADMIN})
303              
304             EOF
305 0           exit;
306              
307 0           HAVE_ID:
308             $Sessions{$Coo}->{last_access} = time;
309 0           $Identity = $Sessions{$Coo}->{identity};
310 0 0         if($Identity eq 'ERROR'){
311 0           print <
312             Content-type: text/plain
313              
314             There was an error with the authentication layer
315             of this web service: $Sessions{$Coo}->{error}
316              
317             please contact $ENV{SERVER_ADMIN} to report this.
318             EOF
319              
320 0           exit;
321             };
322              
323              
324             # print STDERR "setting ",caller().'::AIS_IDENTITY', " to $Sessions{$Coo}->{identity}\n";
325             # $ENV{AIS_IDENTITY} = $Sessions{$Coo}->{identity};
326 0           $ENV{AIS_IDENTITY} =
327 0           ${caller().'::AIS_IDENTITY'} = $Sessions{$Coo}->{identity};
328 0           tie %{caller().'::AIS_STASH'}, DirDB => ${tied(%{$Sessions{$Coo}})};
  0            
  0            
  0            
329              
330             }; # import
331              
332             1;
333              
334             __END__