File Coverage

blib/lib/CGI/AIS/Session.pm
Criterion Covered Total %
statement 15 98 15.3
branch 0 46 0.0
condition 0 10 0.0
subroutine 5 7 71.4
pod 0 2 0.0
total 20 163 12.2


line stmt bran cond sub pod time code
1             package CGI::AIS::Session;
2              
3 1     1   773 use strict;
  1         2  
  1         39  
4              
5 1     1   5 use vars qw{ *SOCK @ISA @EXPORT $VERSION };
  1         2  
  1         151  
6              
7             require Exporter;
8              
9             @ISA = qw(Exporter);
10             @EXPORT = qw(Authenticate);
11              
12             $VERSION = '0.02';
13              
14 1     1   6 use Carp;
  1         10  
  1         96  
15              
16              
17 1     1   1066 use Socket qw(:DEFAULT :crlf);
  1         5850  
  1         1269  
18 1     1   1100 use IO::Handle;
  1         10048  
  1         1845  
19             sub miniget($$$$){
20 0     0 0   my($HostName, $PortNumber, $Desired, $agent) = @_;
21 0   0       $PortNumber ||= 80;
22 0   0       my $iaddr = inet_aton($HostName) || die "Cannot find host named $HostName";
23 0           my $paddr = sockaddr_in($PortNumber,$iaddr);
24 0           my $proto = getprotobyname('tcp');
25            
26 0 0         socket(SOCK, PF_INET, SOCK_STREAM, $proto) || die "socket: $!";
27 0 0         connect(SOCK, $paddr) || die "connect: $!";
28 0           SOCK->autoflush(1);
29              
30 0           print SOCK
31             "GET $Desired HTTP/1.1$CRLF",
32             # Do we need a Host: header with an "AbsoluteURI?"
33             # not needed: http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.2
34             # but this is trumped by an Apache error message invoking RFC2068 sections 9 and 14.23
35             "Host: $HostName$CRLF",
36             "User-Agent: $agent$CRLF",
37             "Connection: close$CRLF",
38             $CRLF;
39              
40 0           join('',);
41              
42             };
43              
44              
45              
46             sub Authenticate{
47              
48 0     0 0   my %Param = (agent => 'AISclient', @_);
49 0           my %Result;
50             my $AISXML;
51              
52              
53 0           print STDERR "$$ Session coox: $ENV{HTTP_COOKIE}\n";
54 0           my (@Cookies) = ($ENV{HTTP_COOKIE} =~ /AIS_Session=(\w+)/g);
55 0 0         tie my %Session, $Param{tieargs}->[0],
56             $Param{tieargs}->[1],$Param{tieargs}->[2],$Param{tieargs}->[3],
57             $Param{tieargs}->[4],$Param{tieargs}->[5],$Param{tieargs}->[6],
58             $Param{tieargs}->[7],$Param{tieargs}->[8],$Param{tieargs}->[9]
59 0           or croak "failed to tie @{$Param{tieargs}}";
60              
61 0           print STDERR "Session database has ",scalar(keys %Session)," keys\n";
62              
63 0           my $Cookie;
64              
65             # make Cookie imply its validity
66 0           push @Cookies, undef;
67 0           while ($Cookie = shift @Cookies){
68             #$Session{$Cookie} and last;
69 0 0         if($Session{$Cookie}){
70 0           print STDERR "Session $Cookie exists\n";
71 0           last;
72             }else{
73 0           print STDERR "Session <$Cookie> false\n";
74              
75             };
76             };
77              
78 0           my $OTUkey;
79             my $SessionKey;
80 0           my ($PostKey) = ($ENV{QUERY_STRING} =~ /AIS_POST_key=(\w+)/);
81              
82             # if (!$Cookie and $ENV{REQUEST_METHOD} eq 'POST' ){
83             # in general, whenever we've got the wrong name for the
84             # server, it won't work. So we need to redirect ourselves
85             # back to here with the right name for the server, and
86             # then we'll get our cookie, if we have one.
87 0 0 0       if (!$Cookie and !defined($PostKey) ){
88             # print STDERR "$$ Cookieless POST caught early\n";
89 0           print STDERR "$$ possible wrong SERVER_NAME\n";
90 0 0         if ($ENV{REQUEST_METHOD} eq 'POST' ){
91 0           $PostKey = join('',time,(map {("A".."Z")[rand 26]}(0..9)));
  0            
92 0           $Session{$PostKey} = join('',(<>));
93             }else{
94 0           $PostKey = '';
95             };
96              
97 0           print "Location: http://$ENV{SERVER_NAME}$ENV{REQUEST_URI}?AIS_POST_key=$PostKey&$ENV{QUERY_STRING}$CRLF$CRLF";
98 0           exit;
99             };
100              
101 0 0         if ($PostKey){ # will be defined but false '' when servicing a GET
102 0 0         pipe(POSTREAD,POSTWRITE) or die "Cannot create pipe: $!";
103 0 0         if (fork){
104             # we are in parent
105 0           close POSTWRITE;
106 0           open STDIN, "<&POSTREAD";
107 0           $ENV{REQUEST_METHOD} = 'POST';
108              
109             }else{
110             # in child -- write POSTdata to pipe and exit
111 0           close STDOUT;
112 0           close STDIN;
113 0           close POSTREAD;
114 0           print POSTWRITE '&',$Session{$PostKey};
115 0 0         close POSTWRITE or die "$$: Error closing POSTWRITE\n";
116 0 0         $Cookie and delete $Session{$PostKey};
117             # exit;
118             #POSIX:_exit(0); # perldoc -f exit
119 0           exec '/usr/bin/true';
120             };
121             };
122              
123 0 0         if ($ENV{QUERY_STRING} =~ /AIS_OTUkey=(\w+)/){
    0          
124 0           $OTUkey = $1;
125 0 0         my ($method, $host, $port, $path) =
126             ($Param{aissri} =~ m#^(\w+)://([^:/]+):?(\d*)(.+)$#)
127             or die "Could not get meth,hos,por,pat from <$Param{aissri}>";
128 0 0         unless ($method eq 'http'){
129 0           croak "aissri parameter must begin 'http://' at this time";
130             };
131              
132             # my $Response = `lynx -source $Param{aissri}query?$OTUkey$CRLF$CRLF`
133 0           my $Response = miniget $host, $port,
134             "$Param{aissri}query?$OTUkey", $Param{agent};
135              
136 0           $SessionKey = join('',time,(map {("A".."Z")[rand 26]}(0..19)));
  0            
137             # print "Set-Cookie: AIS_Session=$SessionKey; path=$ENV{SCRIPT_NAME};$CRLF";
138 0           print "Set-Cookie: AIS_Session=$SessionKey; path=/; expires=$CRLF";
139 0 0         ($AISXML) =
140             $Response =~ m#(.+)#si
141             or die "no element from $Param{aissri}query?$OTUkey\n";
142 0           $Session{$SessionKey} = $AISXML;
143              
144             }elsif (!$Cookie){
145 0           my $PostString = '';
146             # if ($ENV{REQUEST_METHOD} eq 'POST' and !eof){
147 0 0         if ($ENV{REQUEST_METHOD} eq 'POST' ){
148 0           print STDERR "$$ Cookieless POST\n";
149 0           my $PostKey = join('',time,(map {("A".."Z")[rand 26]}(0..9)));
  0            
150 0           $Session{$PostKey} = join('',(<>));
151 0           $PostString = "AIS_POST_key=$PostKey&";
152              
153             };
154 0           print "Location: $Param{aissri}present?http://$ENV{SERVER_NAME}$ENV{REQUEST_URI}?${PostString}AIS_OTUkey=\n\n";
155 0           exit;
156             }else{ # We have a cookie
157 0           $AISXML = $Session{$Cookie};
158 0 0         delete $Session{$Cookie} if $ENV{QUERY_STRING} eq 'AIS_LOGOUT';
159             };
160              
161 0           foreach (qw{
  0            
162             identity
163             error
164             aissri
165             user_remote_addr
166             },
167             @{$Param{XML}}
168             ){
169 0 0         $AISXML =~ m#<$_>(.+)#si or next;
170 0           $Result{$_} = $1;
171             };
172              
173 0 0         if ( defined($Param{timeout})){
174 0           my $TO = $Param{timeout};
175 0           delete @Session{ grep { time - $_ > $TO } keys %Session };
  0            
176              
177             };
178              
179             #Suppress caching NULL and ERROR
180 0 0 0       if( $Result{identity} eq 'NULL' or $Result{identity} eq 'ERROR'){
181 0           print "Set-Cookie: AIS_Session=$CRLF";
182 0 0         $SessionKey and delete $Session{$SessionKey} ;
183              
184 0 0         $Param{nodie} or die "AIS: $Result{identity} identity $Result{error} error";
185              
186             };
187 0           return \%Result;
188             };
189              
190              
191             # Preloaded methods go here.
192              
193             1;
194             __END__