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 forwarded. 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 quotes. 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 continues. 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 <hughes@soda.berkeley.edu>\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 testing. 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 input. --------- 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 mhook'. --------- 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 yeltsy@kremvax.rus. -- 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. Eric
participants (1)
-
Eric Hughes