[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

No Subject

How to Make an Automated Remailer in Your Copious Spare Time with Easy
to Find and Inexpensive Software Tools You May Have Lying Around.

<reprinted from Popular Cryptography, September 1992. Used with permission>

The basic remailer illustrates how to hook in automated software
processing into the Unix mail system.  Here are the basic elements.

1. .forward
2. slocal and .maildelivery
3. remail.perl
4. /usr/lib/sendmail

1. .forward

Unix mail provides a way to have accounts on many different machines
but to receive all your mail in one place.  That facility is the
.forward file, which resides in the home directory.  The file is one
line long and contains the email address to which the mail will be

But the .forward file has another mode of operation.  If the string
begins with the pipe character '|', the mail will be piped through the
program listed.  Enclose the string with double quotes if you need
spaces included.  Here is my .forward file:

"| /usr/local/lib/mh/slocal -user hughes"

Thus all my mail gets processed by the slocal program, described next.

I don't know where the man page for .forward is.  Perhaps someone
could provide a reference.


2. slocal and .maildelivery

The software system MH contains a bunch of useful tools for handling
mail, only one of which we need.  For details on MH, do 'man mh'.

MH has a nice little mail hook processor called slocal.  Its docs can
be found by 'man mhook'.  slocal can conditionally perform operations
on mail messages and consider them either delivered or not.  It allows
multiple operations on individual mail messages.

slocal reads the file .maildelivery when it starts up for
instructions. Here is my .maildelivery file:

# field			pattern	action/	string 
#				result	(quote included spaces)
Request-Remailing-To	""	pipe R	"perl remail.perl" 
Request-Remailing-To	""	file R	archive.remailer

The various pieces of the .maildelivery file are fully documented in
the man page.  I'll just explain what mine does.  Each line describes
one operation to be performed on each incoming mail message.  Fields
are separated by whitespace, so if you need to include spaces, use

The first field, labelled field, is the mail header field to look for.
slocal can selectively process on any header line.  If the header line
does not exist, then the mail does not match this line and no
operation is performed.  If the header line does exist, processing

The second field, pattern, is a text string to match with the contents
of that header line, i.e. with everything after the colon.  In my
case, I put the empty string in, which matches everything.  You need
the pair of quotes to have a placeholder for the field contents.

The next field, action, tells what to do with the message.  'pipe'
sends the message to the standard input of the named program.  'file'
appends the message to an archive or log file.  A useful pipe command
for testing is "tee foo", which makes a copy of the message in file
foo, but does not append, so that you get an exact copy of what slocal
is going to pass to your pipe.  This allows testing of the pipe
program without sending yourself mail all the time.

The next field, result, tells what to do with the message after
processing.  I am currently using R for Regardless to indicate that
this action should always be performed no matter what.  The code R
indicates that the mail should be considered not delivered after
processing; thus slocal writes the mail back into my local spool and I
see it as normal.  Later, after I'm sick of looking at all the
forwarded mail, I'll change this code to A, meaning if the processing
succeeds, then the mail is considered delivered.  The archive file
will always remain R.

The last field, string, is the parameter to the action.  It is a file
name or program.  Use quotes to include spaces.  The name of my mail
processor is "perl remail.perl", which is to run the perl script
remail.perl on the mail.

The .maildelivery file is also the place to put encryption hooks to
automatically decrypt the bodies of messages.  More on that in a
future version.


3. remail.perl

Perl is a wonderful language for doing all sorts of useful work like
processing mail headers.  Do 'man perl' for details, or get the
O'Reilly book and really learn how to use it.

The perl script, in summary, strips off the mail headers, saving the
Subject: line, rewrites a new header, and appends the body of the
previous message.  Here is the script:

--------- cut here ---------
while (<>) {
	last if /^$/ ;
	$subject = $_ if /^Subject:/ ;
	if (/^Request-Remailing-To:/) {
		chop ;
		s/^.*:// ;
		$addressee = $_ ;

#open( OUTPUT, ">foo" ) || die "Cannot open 'foo'." ;
open( OUTPUT, "| /usr/lib/sendmail " . $addressee ) ;
select( OUTPUT ) ;

print "To:" . $addressee . "\n" ;
print "From: nobody\n" ;
print $subject ;
print "Remailed-By: Eric Hughes <[email protected]>\n" ;
print "\n" ;

while (<>) {
} continue {
	print ;
--------- cut here ---------

Here is a summary of the operation.  To really understand this, you'll
have to learn perl.

The while loop processes standard input.  'last' terminates the loop
as soon as a blank line is seen.  A blank line separates the header
from the body.  The subject line, if seen, sets the subject variable
to the whole subject line.  The Request- header line has its final
newline removed, the contents up to the colon substituted into
nonexistence, and saves the rest in the addressee variable.

Next the pipe to sendmail is opened and its output is selected so that
all print commands will go to the pipe.  There is a comment for a
different output channel to the file foo which can be commented in for

Next the remailed header is constructed out of print statements.

Lastly the rest of the standard input is passed through unmodified to
the output channel.  The while loop terminates when there is no more


4. sendmail

sendmail is the backend mailer; it expects complete mail messages and
does not usually generate any line itself except for the first "From"
(with no colon) line.  Any header you construct will thus get passed
through mostly unmodified.  Hence you can put in any "From:" line you
want and any other header info, such as my "Remailed-By:" line.

sendmail expects the name of the addressee on its command line,
otherwise it puts an "Apparently-To:" line in the header.

Any mail processor which remails should probably go through sendmail,
although it would also be possible to talk to an SMTP port directly,
were you so motivated.  MH also has some remailing programs; see 'man


A few words for tinkerers.

-- You can always send mail to yourself.  Especially after you've done
one kind of mail processing and want to pass the mail through the
filters again.

-- When getting started, create an empty .maildelivery file first and
then get your .forward file working.  Test it by sending messages to
yourself.  If you're not getting them, they are going into the bit
bucket.  All your other mail will as well, in this case, so if you
can't afford to lose mail, do it right the first time or work on a
spare account.  

-- Any mail slocal does not process will get delivered as normal.
Running a remailer will not interfere with your other work.

-- Remember to use quote marks.

-- You don't need to be a sysadmin to run this kind of remailer.
There is nothing, however, to prevent a sysadmin from running this
sofware under an alias.  The sysadmin is also a 'trusted user' to
sendmail and can get rid of pesky "From"-no-colon lines.

-- Perl has a random function which could be used to automatically
choose various "From:" lines from a database.  Remember to include
[email protected]

-- postnews or inews could be substituted for sendmail.  Different
header lines would have to be created.  Such a service could run in
parallel with a remailer.  You too can now repost to alt.sex.bondage!

Enjoy.  And watch for interesting improvements like encryption.