pltunnel.pl - Web proxy bypass for applications
#!/usr/bin/perl

# This code is GPL V2.0 and all that... ;-)

use strict;
use IO::Socket;
use IO::File;
use IO::Select;

sub b64 {
	local($_) = pack("u", shift);
	tr# -_#A-Za-z0-9+/#;
	s/.(.*)/\1/;
	chomp;
	$_;
}

# Setup constants
my($LISTEN_PORT, $DEST_HOST, $DEST_PORT, $USERNAME, $PASSWORD, 
$OPENING_LINE, $SWALLOW_HEADER);
$LISTEN_PORT		=  22; # Local listening port - nice for ssh
$DEST_HOST		= "your webproxy ip";
$DEST_PORT		=  your webproxy port;
$USERNAME		= "yourproxyaccountname";
$PASSWORD		= "yourproxypassword";
$OPENING_LINE		= "CONNECT www.verisign.com:443 HTTP/1.0\r\n" .
			  "Proxy-authorization: Basic " . b64("$USERNAME:$PASSWORD") . 
"\r\n" .
			  "User-Agent: Mozilla/4.7 [en-gb] (Win98; U)\r\n" 

			  "\r\n";
$SWALLOW_HEADER = 1;
				  
my($relaySock) = IO::Socket::INET->new(
		Listen		=> 1,
		LocalPort	=> $LISTEN_PORT,
		Proto		=> 'tcp'
) || die "Cannot listen on $LISTEN_PORT\n";

for (;;) 
{
	my($client, $server, $feed, $in, $sel, @ready);

	print "Listening for a connection on $LISTEN_PORT\n";
	$client = $relaySock->accept();		# Listen for a connection
	print "Connection accepted from ", $client->peerhost(), "\n";

	# Open socket to the server
	$server = IO::Socket::INET->new(
			PeerAddr => $DEST_HOST,
			PeerPort => $DEST_PORT,
			Proto    => 'tcp'
	) || die "Can't open socket to $DEST_HOST:$DEST_PORT\n";
	
	if ($SWALLOW_HEADER) {
		$server->send($OPENING_LINE, 0);		# Send opening line
		$feed = 0;
		do {								# Skip header
			$server->recv($in, 1, 0);
			if ($in eq "\n") {
				$feed++ 	
			} elsif ($in ne "\r") {
				$feed = 0;
			}
			chomp $in;
			print $in;
		} while ($feed < 2);
	}

	my $mon = "\r|";
	print "\n|";
	$sel = IO::Select->new($client, $server);			# Init select object
	do {
		$in = undef;
		@ready = $sel->can_read(undef);
		foreach (@ready) {
			if ($_ == $client) {
				$client->recv($in, 8192, 0);
				$server->send($in, 0);
			} elsif ($_ == $server) {
				$server->recv($in, 8192, 0);
				$client->send($in, 0);
			} else {
				print "Should never be able to get here!\n";
			}
			#print $in;
		}
		$mon =~ tr#|/\-\\#/\-\\|#;
		print $mon;
	} while (length($in) > 0);
	$client->close();
	$server->close();
	print "\n";
}

1;