use POSIX qw(strftime);
###UNLOCK_LOG;
-###DATA_PATH;
+###UNLOCK_LOG;
+###CURL_PATH;
###PASS_PATH;
###ACCESS_PATH;
###UNLOCK_PROXY_URL;
###UNLOCK_PROXY_PATH;
###TIMEOUT_UNLOCK;
###TIMEOUT_INACT;
+###BLOCK_HOST;
+###BLOCK_PORT;
+###TEMP_PATH;
+
+use constant REQUEST_HEADER_BLOCK => qr/^(accept-encoding|connection|te|transfer-encoding|via)$/;
+use constant RESPONSE_HEADER_BLOCK => qr/^(connection|content-encoding|content-length|trailer|transfer-encoding)$/;
$accesstime = time();
$timeout_unlock = TIMEOUT_UNLOCK*60;
unlock();
}
else {
- if(access()) {
- debag();
+# if(access()) {
+ proxy();
+# }
+# else {
+# noaccess();
+# }
+}
+
+sub proxy {
+ srand(time()+$$);
+
+ if ($ENV{'REQUEST_METHOD'} !~ /^(HEAD|GET|POST)$/) {
+ return fail("Status: 405 Method Not Allowed\nAllow: GET, POST, HEAD\n","405 Method Not Allowed","The proxy does not support the $ENV{'REQUEST_METHOD'} method.");
+ }
+
+ if ($ENV{'REQUEST_URI'} =~ /^([a-z]*(:[0-9]*)?:\/\/.*)$/){
+ $URL=$1;
+ }
+ else{
+ $URL=($ENV{'HTTPS'} eq 'on' ? 'https://' : 'http://');.$ENV{'HTTP_HOST'}.$ENV{'REQUEST_URI'};
+ }
+
+ #HTTP_HOST might theoretically not agree with REQUESR_URI.
+ if ($URL =~ /^https*:\/\/(.*)$/) {
+ $host= $1;
+ $host =~ s/\/.*$//;
+ if($host =~ /^(.*):([0-9]+)$/) {
+ $host=$1;
+ $port=$2;
+ }
+ else {
+ $port=($ENV{'HTTPS'} eq 'on' ? '443' : '80');
+ }
}
else {
- noaccess();
+ return fail("Status: 400 Bad Request\n","400 Bad Request","The proxy couldn't understand this URL: $URL.");
+ }
+
+ if ($host =~ /^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/) {#IP instead of hostname
+ if ($host =~ /^((0*10\..*)|(0*127\..*)|(0*172\.0*((1[6-9])|(2[0-9])|(3[0-1]))\..*)|(0*192\.0*168\..*))$/) {
+ return fail("Status: 403 Forbidden\n","403 Forbidden","The proxy does not accept a private IP address $host as hostname.");
+ }
+ }
+
+ if ($host =~ BLOCK_HOST) {
+ return fail("Status: 403 Forbidden\n","403 Forbidden","The proxy does not accept $host as hostname.");
+ }
+
+ if ($port =~ BLOCK_PORT) {
+ return fail("Status: 403 Forbidden\n","403 Forbidden","The proxy does not accept port number $port because of infinite loop prevention.");
+ }
+
+ do {
+ $temppath=TEMP_PATH.int(rand(100000000)).'_';
+ $headpath=$temppath.'h';
+ $downpath=$temppath.'d';
+ $uppath=$temppath.'u';
+ } while (( -e $headpath) or ( -e $downpath) or ( -e $uppath));
+
+ @curl_arg=(CURL_PATH,'-s','-o',$downpath,'-D',$headpath); #-s
+ if ($ENV{'REQUEST_METHOD'} eq 'HEAD'){
+ push @curl_arg, '-I';
+ }
+
+ if ($ENV{'REQUEST_METHOD'} eq 'POST'){
+ binmode(STDIN) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to switch STDIN to binary mode.");
+ open($upfile,">",$uppath) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to create temporary file.");
+ binmode ($upfile) or return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to switch temporary file to binary mode.");
+
+ $buffer;
+ while (read (STDIN,$buffer,65536)) {
+ unless (print ($upfile $buffer)) {
+ return fail("Status: 500 Internal Server Error\n","500 Internal Server Error","Failed to write to temporary file.");
+ }
+ }
+ close ($upfile);
+
+ push @curl_arg, '--data-binary';
+ push @curl_arg, '@'.$uppath;
+ }
+ # foreach $envk (keys %ENV) {
+ # if ($envk =~ /^HTTP_/) {
+ # $headname=formatheader($envk);
+ # $headval=$ENV{$envk};
+ # if ($headname !~ /^[A-Za-z\-]+$/) {
+ # next;
+ # }
+ # if(lc($headname) =~ REQUEST_HEADER_BLOCK) {
+ # next;
+ # }
+ # unless (exists $ENV{'HTTP_USER_AGENT'}) {
+ # push @curl_arg, '-H';
+ # push @curl_arg, 'User-Agent:';
+ # }
+ # unless (exists $ENV{'HTTP_ACCEPT'}) {
+ # push @curl_arg, '-H';
+ # push @curl_arg, 'ACCEPT:';
+ # }
+ # $headval=~ s/[\r\n]//g;
+ # $headarg=$headname.(($headval eq '')?';':': '.$headval);
+ # push @curl_arg, '-H';
+ # push @curl_arg, $headarg;
+ # }
+ # }
+
+ push @curl_arg, $URL;
+
+
+ ##DO REAL WORK HERE!
+
+
+ print "Content-type: text/plain\n\n";
+ print "host: $host\nport: $port\n\n";
+ foreach $yyyb (@curl_arg) {
+ print "$yyyb\n";
}
+ #print "\n".(system @curl_arg)."\n";
+
+ unlink $headpath;
+ unlink $downpath;
+ unlink $uppath;
+
+
+ print "\nDEBUGINFO:\n";
+
+ return debag();
+
}
sub access { #kind of doubles the functionality of access.pl but for http
$unlocktime=<$accessfile>;
$lasttime=<$accessfile>;
close($accessfile);
- $unlocktime =~ s/\n//g;
- $lasttime =~ s/\n//g;
+ $unlocktime =~ s/[\r\n]//g;
+ $lasttime =~ s/[\r\n]//g;
if ((abs($accesstime-$unlocktime)>$timeout_unlock) or (abs($accesstime-$unlocktime)>$timeout_inact)){
unlink $accesspath;
return 0;
}
}
+
sub unlock {
if ($ENV{'REMOTE_ADDR'} =~ /^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$/) {
$IP=$1;
open($passfile, "<", $passpath) or return unlockpage('Wrong username or password.',"Status: 403 Forbidden\n");
$pass = <$passfile>;
close($passfile);
- $pass =~ s/\n//g;
+ $pass =~ s/[\r\n]//g;
$pass = urldecode($pass);
if ($pass ne $CGI{'password'}){
my $varl;
my %cgi;
my $i = $_[0];
- $i =~ s/\n//g;
+ $i =~ s/[\r\n]//g;
my @s = split('&',$i);
foreach my $l ( @s) {
($arg,$val)=split('=',$l);
return $t;
}
+sub formatheader {
+ my $t = $_[0];
+ $t =~ s/^HTTP_//;
+ $t = lc($t);
+ $t =~ s/^([a-z])/uc($1)/e;
+ $t =~ s/_([a-z])/'-'.uc($1)/eg;
+ return $t;
+}
+
sub unlockpage {
(my $message, my $header)=@_;
if($header ne ''){
print "</ul></body></html>\n";
}
+sub fail {
+ (my $header, my $title, my $message)=@_;
+ if($header ne ''){
+ print $header;
+ }
+ print "Content-type: text/html\n\n";
+ print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">';
+ print '<html lang="en"><head>';
+ if($title ne ''){
+ print "<title>$title</title>";
+ }
+ print '<meta http-equiv="Content-type" content="text/html; charset=UTF-8">';
+ print '</head><body>';
+ if($title ne ''){
+ print "<h1>$title</h1>";
+ }
+ if($message ne ''){
+ print $message;
+ }
+ print "</body></html>\n";
+}
+
sub unlockedpage {
print "Content-type: text/html\n\n";
print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "">';
$URL=$ENV{'REQUEST_URI'}
}
else{
- $URL='http://'.$ENV{'HTTP_HOST'}.$ENV{'REQUEST_URI'};
+ $URL=($ENV{'HTTPS'} eq 'on' ? 'https://' : 'http://').$ENV{'HTTP_HOST'}.$ENV{'REQUEST_URI'};
}
print 'URL: ',$URL,"\n";
}