]> bicyclesonthemoon.info Git - yplom/proxy/commitdiff
Proxying preparing.
authorb <b@05ce6ebb-7522-4a6e-a768-0026ae12be9f>
Thu, 12 Nov 2015 20:31:49 +0000 (20:31 +0000)
committerb <b@05ce6ebb-7522-4a6e-a768-0026ae12be9f>
Thu, 12 Nov 2015 20:31:49 +0000 (20:31 +0000)
git-svn-id: svn://botcastle1b/yplom/proxy@5 05ce6ebb-7522-4a6e-a768-0026ae12be9f

access.1.pl
configure.pl
proxy.1.pl
settings

index 2d0cf82ff8f4a23363cf9afddbb2941fb5ca5524..dbbd195c9f75c5dd0b83baae66154abd4eadc2a8 100644 (file)
@@ -24,8 +24,8 @@ while (<STDIN>) {
                        $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)){
                                print "ERR too long\n";
index 0daff92878d335206cad56ff9c8d62a34182eb2c..b4a7b39dfd63d3c60a7ce88cf2049a95f7f77347 100755 (executable)
@@ -23,13 +23,17 @@ while ($line = <$configfile>) {
 close ($configfile);
 
 $def{'UNLOCK_LOG'}        = "use constant UNLOCK_LOG         => '".$set{'log_path'}."unlock.log';";
+$def{'CURL_PATH'}         = "use constant CURL_PATH          => '".$set{'curl'}."';";
 $def{'DATA_PATH'}         = "use constant DATA_PATH          => '".$set{'data_path'}."';";
+$def{'TEMP_PATH'}         = "use constant TEMP_PATH          => '".$set{'tmp_path'}."';";
 $def{'PASS_PATH'}         = "use constant PASS_PATH          => '".$set{'data_path'}."pass/';";
 $def{'ACCESS_PATH'}       = "use constant ACCESS_PATH        => '".$set{'data_path'}."access/';";
 $def{'UNLOCK_PROXY_URL'}  = "use constant UNLOCK_PROXY_URL   => 'http://".$set{'unlock_domain'}.$set{'unlock_path'}."';";
 $def{'UNLOCK_PROXY_URL_S'}= "use constant UNLOCK_PROXY_URL_S => 'https://".$set{'unlock_domain'}.$set{'unlock_path'}."';";
 $def{'UNLOCK_PROXY_HOST'} = "use constant UNLOCK_PROXY_HOST  => qr/".$set{'unlock_domain_regex'}."/;";
 $def{'UNLOCK_PROXY_PATH'} = "use constant UNLOCK_PROXY_PATH  => qr/".$set{'unlock_path_regex'}."/;";
+$def{'BLOCK_HOST'}        = "use constant BLOCK_HOST         => qr/".$set{'block_host_regex'}."/;";
+$def{'BLOCK_PORT'}        = 'use constant BLOCK_PORT         => qr/^((0*'.$set{'http_proxy_port'}.')|('.$set{'https_proxy_port'}.')|('.$set{'ssl_proxy_port'}.'))$/;';
 $def{'TIMEOUT_UNLOCK'}    = "use constant TIMEOUT_UNLOCK     => ".$set{'timeout_unlock'}.";";
 $def{'TIMEOUT_INACT'}     = "use constant TIMEOUT_INACT      => ".$set{'timeout_inact'}.";";
 $def{'REWRITE_URL'}       = "use constant REWRITE_URL        => '".$set{'https_proxy_domain'}.":".$set{'https_proxy_port'}."';";
index 5655ebd6a187d08e67239d7c2ab7330b31216a4c..bf614ac4d9f4af8a1e76491d5801e37f18b8fd75 100755 (executable)
@@ -3,7 +3,8 @@
 use POSIX qw(strftime);
 
 ###UNLOCK_LOG;
-###DATA_PATH;
+###UNLOCK_LOG;
+###CURL_PATH;
 ###PASS_PATH;
 ###ACCESS_PATH;
 ###UNLOCK_PROXY_URL;
@@ -12,6 +13,12 @@ use POSIX qw(strftime);
 ###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;
@@ -24,12 +31,133 @@ if (($ENV{'HTTP_HOST'} =~ UNLOCK_PROXY_HOST) and ($ENV{'PATH_INFO'} =~ UNLOCK_PR
        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
@@ -46,8 +174,8 @@ 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;
@@ -69,6 +197,7 @@ sub access { #kind of doubles the functionality of access.pl but for http
                return 0;
        }
 }
+
 sub unlock {
        if ($ENV{'REMOTE_ADDR'} =~ /^([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)$/) {
                $IP=$1;
@@ -114,7 +243,7 @@ sub unlock {
        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'}){
@@ -139,7 +268,7 @@ sub getcgi {
        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);
@@ -155,6 +284,15 @@ sub urldecode {
        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 ''){
@@ -187,6 +325,28 @@ sub unlockpage {
        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" "">';
@@ -234,7 +394,7 @@ sub debag {
                $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";
 }
index 39b4a7ab941f4e7145fd37471472eb3dc5f33618..09502afc116b611cf82653747712c8a74477fccd 100644 (file)
--- a/settings
+++ b/settings
@@ -9,6 +9,7 @@ www_path  = /yplom/www/proxy/  #for the www server (unused)
 
 #the server must recognise these domains as itself (127.0.0.1)
 #http and ssl proxy ports must be accessible from outside
+#Don't set the ports to default values of non-proxy http(s): 80, 443!
 http_proxy_domain  = bicyclesonthemoon.info
 https_proxy_domain = bicyclesonthemoon.info
 ssl_proxy_domain   = bicyclesonthemoon.info
@@ -28,12 +29,17 @@ unlock_path         = /proxy/unlock
 unlock_domain_regex = ^yplom\.bicyclesonthemoon\.info(:[0-9]*)?$
 unlock_path_regex   = ^\/proxy\/unlock\/?$
 
+# A regex to catch hostnames that are, for example, defined in /etc/hosts and
+# link to your local network and you don't want them to be proxied.
+block_host_regex = ^(localhost|(botcastle[0-9]*))$
+
 #Time in minutes
 timeout_unlock = 90
 timeout_inact  = 15
 
 path    = /usr/local/bin:/usr/bin:/bin
 perl    = /usr/bin/perl
+curl    = /usr/bin/curl
 chmod   = /bin/chmod
 cp      = /bin/cp
 mv      = /bin/mv