connect-tunnel is my first script on CPAN (latest version available here). I am studying HTTP and CONNECT tunnels at work (to find a way to detect or defeat them), so I first started by writing a tool to create one of those two kinds of tunnels. Naturally, this is not the first Perl program to do this: I found several of them with Google after I had the first version working. {grin}
So I went a little further, and looked into the
depths of libwww-perl. Did I say this is a
wonderful library? Did you know that LWP::UserAgent actually supports the CONNECT
method? It simply returns the opened socket
in $response->{client_socket}
.
Ain't that neat?
my $request = HTTP::Request->new( CONNECT => 'http://ssh.example.com:443/' ); my $response = $ua->request($request); my $socket = $response->{client_socket};
The script supports tunnels to multiple destinations, as well as concurrent connections to the same destination. You can also change the User-Agent string (ok, that bit is quite easy). But most of all, since it's LWP::UserAgent that handles the authentication, the script supports Basic, Digest and NTLM authentication. And I only had to subclass LWP::UserAgent like this:
package TunnelAgent; use vars qw( @ISA ); @ISA = qw(LWP::UserAgent); sub get_basic_credentials { return ( $user, $pass ) };
Couldn't be any simpler.
I had to dive in libwww-perl's source code, which is not that easy to follow (lots of modules, lots of indirections), but it was well worth it. I built myself some experience with libwww-perl while writing HTTP::Proxy, and it helped a little.
Until I find a way to block myself from tunneling outside, I'll use this tool rather than any other when I need more than just HTTP.
I would have written the first version so much faster if I had known the difference between
read()
and sysread()
...