// COMPLETE THREAD

Exit Remailer Suggestion

6 expanded posts ยท every known parent and child

NODE c1371576Exit Remailer Suggestion
Someone wrote:

 > What about AOL disks?  We need shorter lived, disposable
 > remailers as exit remailers...  Let them take the heat,
 > while the real remailers walk.  Lets see a series of
 > "exitman" remailers.  Exitman remailers are walking targets
 > left to fend for themselves as long as they may.

We already have a preconfigured set of exit remailers.  They have
names like "hotmail", "rocketmail", etc...  These are the
web-based email services which will instantly create accounts for
anyone, no questions asked or authentication required, and permit
access to these accounts with the chosen password from anywhere
on the Net.  You can even chain them, using an account on one to
apply for an instant account on another, leaving few bread crumbs
for anyone to follow.

Most of these services don't care, don't log, and rarely read
their email to abuse@. Even if pressure does cause an occasional
account to be deleted, you can easily create ten more in as many
seconds.

By reconfiguring current remailers to use a public Email service
as the last link in the chain, we tap a potentially infinite
supply of disposable accounts, on advertising-supported service
providers with skins as thick as those of the bulk emailers.

Sounds like a plan to me.

--
     Mike Duvos         $    PGP 2.6 Public Key available     $
     enoch@zipcon.com   $    via Finger                       $
         {Free Cypherpunk Political Prisoner Jim Bell}
NODE 2452ea2cRe: Exit Remailer Suggestion
Mike Duvos <enoch@zipcon.net> writes:
> Someone wrote:

(That someone was me).

>  > What about AOL disks?  We need shorter lived, disposable
>  > remailers as exit remailers...  Let them take the heat,
>  > while the real remailers walk.  Lets see a series of
>  > "exitman" remailers.  Exitman remailers are walking targets
>  > left to fend for themselves as long as they may.
> 
> By reconfiguring current remailers to use a public Email service
> as the last link in the chain, we tap a potentially infinite
> supply of disposable accounts, on advertising-supported service
> providers with skins as thick as those of the bulk emailers.
> 
> Sounds like a plan to me.

OK, lets _do_ it!

Sounds much easier and less risky than relying on a recreational
cracker to provide a stream of short lived remailers as I was
suggesting.

Adam
-- 
Have *you* exported RSA today? --> http://www.dcs.ex.ac.uk/~aba/rsa/

print pack"C*",split/\D+/,`echo "16iII*o\U@{$/=$z;[(pop,pop,unpack"H*",<>
)]}\EsMsKsN0[lN*1lK[d2%Sa2/d0<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<J]dsJxp"|dc`
NODE 0b011f80Re: Exit Remailer Suggestion
In article <199708080936.KAA01816@server.test.net>,
Adam Back  <aba@dcs.ex.ac.uk> wrote:
>
>Mike Duvos <enoch@zipcon.net> writes:
>> Someone wrote:
>
>(That someone was me).
>
>>  > What about AOL disks?  We need shorter lived, disposable
>>  > remailers as exit remailers...  Let them take the heat,
>>  > while the real remailers walk.  Lets see a series of
>>  > "exitman" remailers.  Exitman remailers are walking targets
>>  > left to fend for themselves as long as they may.
>> 
>> By reconfiguring current remailers to use a public Email service
>> as the last link in the chain, we tap a potentially infinite
>> supply of disposable accounts, on advertising-supported service
>> providers with skins as thick as those of the bulk emailers.
>> 
>> Sounds like a plan to me.
>
>OK, lets _do_ it!

Sounds good to me.  Hotmail makes a note of the IP address that connected
to it, but luckily there's no shortage of HTTP proxies out there...

   - Ian

#!/usr/bin/perl -w

##
## sendhotmail: pipe an RFC822 mail message into this, and it will send it
##              out from a hotmail account via an HTTP proxy
##
## Initial revision 19970808 by Ian Goldberg <ian@cypherpunks.ca>
##

## Set the following to your proxy host and port.
##  Look at the files pointed at by
##   http://ircache.nlanr.net/Cache/Tracker/caches/
##  for sample entries, but most of them don't allow just anyone to connect
##  to hotmail through them.

$proxyhost = 'proxy.slt.lk';
$proxyport = 8080;

## This is your hotmail login name and password
$login = ## Fill this in yourself
$passwd = ## Fill this in yourself

## End Configuration

sub escapetext {
    my $t = $_[0];
    $t =~ s/([\000-\037\200-\377\{\}\|\\\^\[\]\`\"\<\>\:\@\/\;\?\=\&\%\.\#])/"%".unpack('H2',$1)/eg;
    $t =~ s/ /+/g;
    $t;
}

## Parse the incoming mail (note that we don't handle continuation headers)
## Also, the To, Cc, and Bcc headers ought to be in a form hotmail understands
## (no full names, etc.).  We try to do the stripping properly.

$to = '';
$subject = '';
$cc = '';
$bcc = '';
while(<STDIN>) {
    if (/^To:\s+(.*)/io) {
	$to = $1;
	$to =~ s/\(.*?\)//g;
	$to =~ s/\".*?\"//g;
	$to = &escapetext($to);
    } elsif (/^Subject:\s+(.*)/io) {
	$subject = &escapetext($1);
    } elsif (/^Cc:\s+(.*)/io) {
	$cc = $1;
	$cc =~ s/\(.*?\)//g;
	$cc =~ s/\".*?\"//g;
	$cc = &escapetext($cc);
    } elsif (/^Bcc:\s+(.*)/io) {
	$bcc = $1;
	$bcc =~ s/\(.*?\)//g;
	$bcc =~ s/\".*?\"//g;
	$bcc = &escapetext($bcc);
    }
    last if /^$/;
}
$msg = &escapetext(join("\r\n", <STDIN>));

use LWP;

## Begin magic

$ua = new LWP::UserAgent;
$ua->proxy('http', "http://${proxyhost}:${proxyport}/");

$url = new URI::URL 'http://www.hotmail.com/cgi-bin/password.cgi';
$request = new HTTP::Request('POST', $url);
$request->header(Pragma => 'no-cache');
$request->content("login=${login}&curmbox=ACTIVE");

$response = $ua->request($request);
$body = $response->content;
$body =~ /\<\s*form\s+[^>]*action=\"(.*?)\"/io or die "Cannot log in";

$url = new URI::URL $1, $url;
$body = $';
$body =~ s/\<\s*\/form\s*\>.*//;
$body =~ /\<\s*input\s+[^>]*name=\"disk\"\s+value(=\"(.*?)\")?/io or die "Cannot give passwd";
$disk = $2 || "";

$request = new HTTP::Request('POST', $url);
$request->header(Pragma => 'no-cache');
$request->content("passwd=${passwd}&frames=no&disk=${disk}&curmbox=ACTIVE&login=${login}&js=no");
$response = $ua->request($request);
$body = $response->content;

$body =~ /\<\s*area\s+[^>]*href=\"(\/cgi-bin\/compose.*?)\"/io or die "Cannot compose";
$composeurl = new URI::URL $1, $url;
$body =~ /\<\s*area\s+[^>]*href=\"(\/cgi-bin\/logout.*?)\"/io or die "Cannot compose";
$logouturl = new URI::URL $1, $url;

$request = new HTTP::Request('GET', $composeurl);
$request->header(Pragma => 'no-cache');
$response = $ua->request($request);
$body = $response->content;

$body =~ /\<\s*form\s+[^>]*action=\"(.*?)\".*?\>/io or die "Cannot send message";
$url = new URI::URL $1, $composeurl;
$body = $';
$data = '';
while(1) {
    $body =~ /^\s*\<\s*input\s+type=\"?hidden\"?\s+name=\"(.*?)\"\s+value(=\"(.*?)\")?\s*\>/io or last;
    $name = $1; $value = $3 || ""; $body = $';
    $data .= $name."=".$value."&";
}
$data .= "to=${to}&subject=${subject}&cc=${cc}&bcc=${bcc}&body=${msg}&Send.x=1&Send.y=1";

$request = new HTTP::Request('POST', $url);
$request->header(Pragma => 'no-cache');
$request->content($data);
$response = $ua->request($request);
$body = $response->content;

$request = new HTTP::Request('GET', $logouturl);
$request->header(Pragma => 'no-cache');
$response = $ua->request($request);
NODE 7f1b7a6esendhotmail, version 1.3
And here's 1.3.  It uses the same config file as 1.2.

New:

o fixes a bug involving + in email addresses
o handles continuation headers properly
o Can be used as a drop-in replacement for sendmail (though it may get confused
  if you pass weird sendmail options); it will keep trying random hotmail
  accounts and proxies until it succeeds in delivering the mail.  Note that,
  depending on your connectivity, this can take a while...

   - Ian

#!/usr/bin/perl -w

##
## sendhotmail: pipe an RFC822 mail message into this, and it will send it
##              out from a hotmail account via an HTTP proxy
##
## Version 1.3: 19970813
##
## Program by Ian Goldberg <ian@cypherpunks.ca>
##

sub Usage {
    die "Usage: $0 -t | addr\@host ...\n";
}

## Check options
$cmdlineto = '';
while ($#ARGV >= 0 && $ARGV[0] =~ /^-/o) {
    $_ = shift @ARGV;
    if ($_ eq "-t") {
	$cmdlineto = '';
    } elsif ($_ eq "-f") {
	shift @ARGV;
    } else {
	## Ignore option
    }
}
if ($#ARGV >= 0) {
    $cmdlineto = join(", ", @ARGV);
}

use LWP;

$uadirect = new LWP::UserAgent;

## The filename of the configuration file
$configfile = '/home/iang/sendhotmail/config';

## Read the config file
open(CONFIG, $configfile) or die "Cannot open $configfile: $!\n";
while(<CONFIG>) {
    next if /^\s*$/o;
    next if /^\s*\#/o;
    next unless /^([^:]+):\s*(.*)$/o;
    $value = $2;
    $name = "\L$1\E";
    $name =~ s/[^a-z0-9]//iog;
    $config{$name} = $value;
}
close(CONFIG);

sub escapetext {
    my $t = $_[0];
    $t =~ s/([\000-\037\200-\377\{\}\|\\\^\[\]\`\"\<\>\:\@\/\;\?\=\&\%\.\#\+])/"%".unpack('H2',$1)/eg;
    $t =~ s/ /+/g;
    $t;
}

sub getaddrs {
    my @addrlist = split(/,\s*/, $_[0]);
    my ($a, $ra);
    my @r;

    foreach $a (@addrlist) {
	$ra = '';
	if ($a =~ /\<(.*?)\>/) {
	    $ra = $1;
	} else {
	    $a =~ s/\(.*?\)//g;
	    $a =~ s/\".*?\"//g;
	    $ra = $1 if $a =~ /(\S+\@\S+)/;
	}
	push (@r, $ra) if $ra ne '';
    }
    join(', ', @r);
}

## Parse the incoming mail.  We need to put the To, Cc, and Bcc headers
## into a simple format that hotmail can understand.

$header{'to'} = '';
$header{'subject'} = '';
$header{'cc'} = '';
$header{'bcc'} = '';
$curheader = '';
while(<STDIN>) {
    last if /^$/;
    chomp;
    if (/^\S/) {
	## Start a new header
	if (s/^To:\s*//io) {
	    $curheader = 'to';
	    $header{'to'} .= ', ' if $header{'to'} ne '';
	} elsif (s/^Cc:\s*//io) {
	    $curheader = 'cc';
	    $header{'cc'} .= ', ' if $header{'cc'} ne '';
	} elsif (s/^Bcc:\s*//io) {
	    $curheader = 'bcc';
	    $header{'bcc'} .= ', ' if $header{'bcc'} ne '';
	} elsif (s/^Subject:\s*//io) {
	    $curheader = 'subject';
	} else {
	    $curheader = '';
	}
    }
    if ($curheader ne '') {
	s/^\s*//;
	$header{$curheader} .= ' ' if $header{$curheader} ne '';
	$header{$curheader} .= $_;
    }
}
## If we were given command-line addresses, that overrides the headers
$header{'to'} = &getaddrs($cmdlineto eq '' ? $header{'to'} : $cmdlineto);
$header{'cc'} = &getaddrs($cmdlineto eq '' ? $header{'cc'} : '');
$header{'bcc'} = &getaddrs($cmdlineto eq '' ? $header{'bcc'} : '');

$msg = &escapetext(join('', <STDIN>));

srand(time ^ $$);

## Keep trying until the message is successfully delivered
RETRYLOOP: while (1) {

## Get the proxy list
$proxylisturl = new URI::URL ($config{'proxylisturl'} ||
		'http://www.publius.net/~remailer/proxy_list.txt');
if (defined $config{'proxylistcachefile'}) {
    ## Check if the locally cached copy is new enough
    $maxage = $config{'proxylistcacheage'} || 1;
    if (! -e $config{'proxylistcachefile'} ||
	    -M $config{'proxylistcachefile'} > $maxage) {
	## Fetch a new copy
	$request = new HTTP::Request('GET', $proxylisturl);
	$request->header(Pragma => 'no-cache');
	$response = $uadirect->request($request);
	$body = $response->content;
	$newfname = $config{'proxylistcachefile'}.".new.$$";
	open(CACHE, ">$newfname") or die "Cannot write $newfname: $!\n";
	print CACHE $body;
	close(CACHE);
	rename($newfname, $config{'proxylistcachefile'}) or
	    die "Cannot rename $newfname: $!\n";
    }
    ## Read the proxy list
    open(CACHE, $config{'proxylistcachefile'}) or
	die "Cannot open $config{'proxylistcachefile'}: $!\n";
    @proxylist = grep (s/\n// && /^[^#]/, <CACHE>);
    close(CACHE);
} else {
    ## Just fetch from the net
    $request = new HTTP::Request('GET', $proxylisturl);
    $request->header(Pragma => 'no-cache');
    $response = $uadirect->request($request);
    @proxylist = grep (/^[^#]/, split("\n", $response->content));
}

@proxylist = ('secure.escape.ca:80') if $#proxylist == -1;

## Get the account list
if (defined $config{'accountlistfile'}) {
    open(ACC, $config{'accountlistfile'}) or
	die "Cannot open $config{'accountlistfile'}: $!\n";
    @accountlist = grep (s/\n// && /^[^#]/, <ACC>);
    close(ACC);
}

@accountlist = ('ldeliverer:xxxx') if $#accountlist == -1;

## Choose a proxy and account at random

$proxy = $proxylist[int rand ($#proxylist+1)];
($login, $passwd) =
    $accountlist[int rand ($#accountlist+1)] =~ /^([^:]*):(.*)$/;

#print STDERR "Trying $login through $proxy\n";

## Begin hotmail-specific magic

$ua = new LWP::UserAgent;
$ua->proxy('http', "http://${proxy}/");

$url = new URI::URL 'http://www.hotmail.com/cgi-bin/password.cgi';
$request = new HTTP::Request('POST', $url);
$request->header(Pragma => 'no-cache');
$request->content("login=${login}&curmbox=ACTIVE");

$response = $ua->request($request);
$body = $response->content;
$body =~ /\<\s*form\s+[^>]*action=\"(.*?)\"/io or next RETRYLOOP;

$url = new URI::URL $1, $url;
$body = $';
$body =~ s/\<\s*\/form\s*\>.*//;
$body =~ /\<\s*input\s+[^>]*name=\"disk\"\s+value(=\"(.*?)\")?/io or next RETRYLOOP;
$disk = $2 || "";

$request = new HTTP::Request('POST', $url);
$request->header(Pragma => 'no-cache');
$request->content("passwd=${passwd}&frames=no&disk=${disk}&curmbox=ACTIVE&login=${login}&js=no");
$response = $ua->request($request);
$body = $response->content;

$body =~ /\<\s*area\s+[^>]*href=\"(\/cgi-bin\/compose.*?)\"/io or next RETRYLOOP;
$composeurl = new URI::URL $1, $url;
$body =~ /\<\s*area\s+[^>]*href=\"(\/cgi-bin\/logout.*?)\"/io or next RETRYLOOP;
$logouturl = new URI::URL $1, $url;

$request = new HTTP::Request('GET', $composeurl);
$request->header(Pragma => 'no-cache');
$response = $ua->request($request);
$body = $response->content;

$body =~ /\<\s*form\s+[^>]*action=\"(.*?)\".*?\>/io or next RETRYLOOP;
$url = new URI::URL $1, $composeurl;
$body = $';
$data = '';
while(1) {
    $body =~ /^\s*\<\s*input\s+type=\"?hidden\"?\s+name=\"(.*?)\"\s+value(=\"(.*?)\")?\s*\>/io or last;
    $name = $1; $value = $3 || ""; $body = $';
    $data .= $name."=".$value."&";
}
$data .= "to=$header{'to'}&subject=$header{'subject'}&cc=$header{'cc'}&bcc=$header{'bcc'}&body=${msg}&Send.x=1&Send.y=1";

$request = new HTTP::Request('POST', $url);
$request->header(Pragma => 'no-cache');
$request->content($data);
$response = $ua->request($request);
$body = $response->content;
$body =~ /\<\s*title\s*\>\s*Hotmail\s*-\s*Mailbox/io or next RETRYLOOP;

$request = new HTTP::Request('GET', $logouturl);
$request->header(Pragma => 'no-cache');
$response = $ua->request($request);
last RETRYLOOP;  ## Success
}
NODE 72402040sendhotmail, version 1.2
Here's version 1.2 of sendhotmail.

Now the only configuration option in the perl script itself is the location
of a config file.  That file should have the following form (you should change
the pathnames of the local files, of course):

---8<--- sample config file ---8<---
## The URL from which to fetch the current list of active proxies
Proxy List URL: http://www.publius.net/~remailer/proxy_list.txt

## The file in which to cache the above list
Proxy List Cache File: /home/iang/sendhotmail/proxy_list.txt

## How many days to cache the proxy list
Proxy List Cache Age: 1

## The file containing the list of hotmail accounts
Account List File: /home/iang/sendhotmail/accountlist
---8<--- sample config file ---8<---

Also, you'll need a list of valid hotmail account names/passwords in the
account list file to which you pointed, above.  This file contains a number
of lines, each of the form "login:password".  For example:

---8<--- sample accountlist file ---8<---
ldeliverer:xxxx
---8<--- sample accountlist file ---8<---

sendhotmail now picks a proxy and hotmail account at random.  I'll try to
keep the proxy list relatively up-to-date, and you need to keep your
account list up-to-date (in case Hotmail shuts one down, or something).

The perl program will "die" if something unexpected happens (such as the
proxy it chose didn't work, or the hotmail account was suddenly invalid).
Just try running it again (future versions will likely automatically
retry with different random choices for the proxy and the hotmail login).

   - Ian

#!/usr/bin/perl -w

##
## sendhotmail: pipe an RFC822 mail message into this, and it will send it
##              out from a hotmail account via an HTTP proxy
##
## Program by Ian Goldberg <ian@cypherpunks.ca>
##

use LWP;

$uadirect = new LWP::UserAgent;

## The filename of the configuration file
$configfile = '/home/iang/sendhotmail/config';

## Read the config file
open(CONFIG, $configfile) or die "Cannot open $configfile: $!\n";
while(<CONFIG>) {
    next if /^\s*$/o;
    next if /^\s*\#/o;
    next unless /^([^:]+):\s*(.*)$/o;
    $value = $2;
    $name = "\L$1\E";
    $name =~ s/[^a-z0-9]//iog;
    $config{$name} = $value;
}
close(CONFIG);

## Get the proxy list
$proxylisturl = new URI::URL ($config{'proxylisturl'} ||
		'http://www.publius.net/~remailer/proxy_list.txt');
if (defined $config{'proxylistcachefile'}) {
    ## Check if the locally cached copy is new enough
    $maxage = $config{'proxylistcacheage'} || 1;
    if (! -e $config{'proxylistcachefile'} ||
	    -M $config{'proxylistcachefile'} > $maxage) {
	## Fetch a new copy
	$request = new HTTP::Request('GET', $proxylisturl);
	$request->header(Pragma => 'no-cache');
	$response = $uadirect->request($request);
	$body = $response->content;
	$newfname = $config{'proxylistcachefile'}.".new.$$";
	open(CACHE, ">$newfname") or die "Cannot write $newfname: $!\n";
	print CACHE $body;
	close(CACHE);
	rename($newfname, $config{'proxylistcachefile'}) or
	    die "Cannot rename $newfname: $!\n";
    }
    ## Read the proxy list
    open(CACHE, $config{'proxylistcachefile'}) or
	die "Cannot open $config{'proxylistcachefile'}: $!\n";
    @proxylist = grep (s/\n// && /^[^#]/, <CACHE>);
    close(CACHE);
} else {
    ## Just fetch from the net
    $request = new HTTP::Request('GET', $proxylisturl);
    $request->header(Pragma => 'no-cache');
    $response = $uadirect->request($request);
    @proxylist = grep (/^[^#]/, split("\n", $response->content));
}

@proxylist = ('secure.escape.ca:80') if $#proxylist == -1;

## Get the account list
if (defined $config{'accountlistfile'}) {
    open(ACC, $config{'accountlistfile'}) or
	die "Cannot open $config{'accountlistfile'}: $!\n";
    @accountlist = grep (s/\n// && /^[^#]/, <ACC>);
    close(ACC);
}

@accountlist = ('ldeliverer:xxxx') if $#accountlist == -1;

sub escapetext {
    my $t = $_[0];
    $t =~ s/([\000-\037\200-\377\{\}\|\\\^\[\]\`\"\<\>\:\@\/\;\?\=\&\%\.\#])/"%".unpack('H2',$1)/eg;
    $t =~ s/ /+/g;
    $t;
}

sub getaddrs {
    my @addrlist = split(/,\s*/, $_[0]);
    my ($a, $ra);
    my @r;

    foreach $a (@addrlist) {
	$ra = '';
	if ($a =~ /\<(.*?)\>/) {
	    $ra = $1;
	} else {
	    $a =~ s/\(.*?\)//g;
	    $a =~ s/\".*?\"//g;
	    $ra = $1 if $a =~ /(\S+\@\S+)/;
	}
	push (@r, $ra) if $ra ne '';
    }
    join(', ', @r);
}

## Parse the incoming mail.  We need to put the To, Cc, and Bcc headers
## into a simple format that hotmail can understand.

$header{'to'} = '';
$header{'subject'} = '';
$header{'cc'} = '';
$header{'bcc'} = '';
$curheader = '';
while(<STDIN>) {
    last if /^$/;
    chomp;
    if (/^\S/) {
	## Start a new header
	if (s/^To:\s*//io) {
	    $curheader = 'to';
	    $header{'to'} .= ', ' if $header{'to'} ne '';
	} elsif (s/^Cc:\s*//io) {
	    $curheader = 'cc';
	    $header{'cc'} .= ', ' if $header{'cc'} ne '';
	} elsif (s/^Bcc:\s*//io) {
	    $curheader = 'bcc';
	    $header{'bcc'} .= ', ' if $header{'bcc'} ne '';
	} elsif (s/^Subject:\s*//io) {
	    $curheader = 'subject';
	} else {
	    $curheader = '';
	}
    }
    if ($curheader ne '') {
	s/^\s*//;
	$header{$curheader} .= ' ' if $header{$curheader} ne '';
	$header{$curheader} .= $_;
    }
}
$header{'to'} = &getaddrs($header{'to'});
$header{'cc'} = &getaddrs($header{'cc'});
$header{'bcc'} = &getaddrs($header{'bcc'});
$msg = &escapetext(join('', <STDIN>));

## Choose a proxy and account at random

srand(time ^ $$);
$proxy = $proxylist[int rand ($#proxylist+1)];
($login, $passwd) =
    $accountlist[int rand ($#accountlist+1)] =~ /^([^:]*):(.*)$/;

## Begin hotmail-specific magic

$ua = new LWP::UserAgent;
$ua->proxy('http', "http://${proxy}/");

$url = new URI::URL 'http://www.hotmail.com/cgi-bin/password.cgi';
$request = new HTTP::Request('POST', $url);
$request->header(Pragma => 'no-cache');
$request->content("login=${login}&curmbox=ACTIVE");

$response = $ua->request($request);
$body = $response->content;
$body =~ /\<\s*form\s+[^>]*action=\"(.*?)\"/io or die "Cannot log in";

$url = new URI::URL $1, $url;
$body = $';
$body =~ s/\<\s*\/form\s*\>.*//;
$body =~ /\<\s*input\s+[^>]*name=\"disk\"\s+value(=\"(.*?)\")?/io or die "Cannot give passwd";
$disk = $2 || "";

$request = new HTTP::Request('POST', $url);
$request->header(Pragma => 'no-cache');
$request->content("passwd=${passwd}&frames=no&disk=${disk}&curmbox=ACTIVE&login=${login}&js=no");
$response = $ua->request($request);
$body = $response->content;

$body =~ /\<\s*area\s+[^>]*href=\"(\/cgi-bin\/compose.*?)\"/io or die "Cannot compose";
$composeurl = new URI::URL $1, $url;
$body =~ /\<\s*area\s+[^>]*href=\"(\/cgi-bin\/logout.*?)\"/io or die "Cannot compose";
$logouturl = new URI::URL $1, $url;

$request = new HTTP::Request('GET', $composeurl);
$request->header(Pragma => 'no-cache');
$response = $ua->request($request);
$body = $response->content;

$body =~ /\<\s*form\s+[^>]*action=\"(.*?)\".*?\>/io or die "Cannot send message";
$url = new URI::URL $1, $composeurl;
$body = $';
$data = '';
while(1) {
    $body =~ /^\s*\<\s*input\s+type=\"?hidden\"?\s+name=\"(.*?)\"\s+value(=\"(.*?)\")?\s*\>/io or last;
    $name = $1; $value = $3 || ""; $body = $';
    $data .= $name."=".$value."&";
}
$data .= "to=$header{'to'}&subject=$header{'subject'}&cc=$header{'cc'}&bcc=$header{'bcc'}&body=${msg}&Send.x=1&Send.y=1";

$request = new HTTP::Request('POST', $url);
$request->header(Pragma => 'no-cache');
$request->content($data);
$response = $ua->request($request);
$body = $response->content;

$request = new HTTP::Request('GET', $logouturl);
$request->header(Pragma => 'no-cache');
$response = $ua->request($request);
NODE 13f1756bRe: sendhotmail, version 1.2
Ian writes:

> Here's version 1.2 of sendhotmail.

This is truly beautiful.  How long until hotmail is the default for
everything coming out of a mixmaster that isn't going to another
remailer?

--
     Mike Duvos         $    PGP 2.6 Public Key available     $
     enoch@zipcon.com   $    via Finger                       $
         {Free Cypherpunk Political Prisoner Jim Bell}