A Simple CGI Email Handler

Notice

This code is based on the post_query.c code provided with
the NCSA httpd 1.1 package, released to the public domain
(see their policy, which follows).

Original portions Copyright 1994 Cold Spring Harbor Labs.
Permission granted to copy, modify and otherwise use
this code in whatever manner you see fit, with no warranty
expressed or implied. Plesae retain this notice; this is
the only restriction. We also ask that you credit
yourself for any changes so we are not asked to maintain
versions of the code that are no longer recognizable to us.

Original portions by Thomas Boutell.

Portions developed at the National Center for Supercomputing
Applications at the University of Illinois at Urbana-Champaign.

THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED,
FOR THE SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT
LIMITATION, WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A
PARTICULAR PURPOSE.

Why Would I Want This?

Many server administrators have noticed the email- sending forms that are present on our server and on others. Our own email forms are serviced by a simple CGI-compliant C program, based on the post-query program provided in the NCSA httpd 1.1 distribution. It delivers email only to users specified by the maintainer and provides a convenient interface, avoiding the need to "step out of" Mosaic to send short notes.

Our email handler is extremely simple and so I hadn't previously thought of releasing it, but a recent security problem with other email handlers (no doubt fixed by now in all of them) and a rash of requests led me to decide to release the code.

Requirements

To use this code, you will need to obtain the file "util.c" from the NCSA httpd 1.1 distribution, which is found in the directory httpd_1.1/cgi-src. This does not mean you can't use this package with another CGI- compliant server; the program just relies on convienience functions found in this file. You can also obtain the util.c code here.

You will also, of course, need a CGI- compliant server, such as the NCSA httpd or the CERN httpd (to my knowledge; I have no direct experience with the latter-- corrections and additions appreciated). If you are offering pages over ftp or another access method aside from true server, you will not be able to use this package.

Finally, you will need an ANSI C compiler, which hopefully won't bring many tears in 1994.

Obtaining email.c

You can obtain the email.c code here.

Compiling email.c

Move email.c and util.c to the same directory and enter the command:

gcc email.c util.c -o email

If all goes well the binary "email" will be the result.

Installing email

Create a email-bin subdirectory beneath your cgi-bin directory, and move the email binary to this location. It is recommended that you do this instead of placing the binary in your cgi-bin directory to guarantee that it cannot be run directly by users.

To provide access to the program for legitimate purposes, create scripts in your cgi-bin directory for each user who can legitimately receive email through forms. The following example script is used to send mail to me (be sure to make it executable):

(The name of this file is "eboutell", and I keep it in my cgi-bin directory.)

#!/bin/sh
echo boutell > /tmp/email.web
echo /boutell.html >> /tmp/email.web
/home/www/ncsa/cgi-bin/email-bin/email $*
rm /tmp/email.web

Note that a temporary file is generated containing the user- specific information. The first such item is of course my username (boutell). The second is the relative path of my personal home page, from which email is typically sent using this script (/boutell.html). To allow for a new user, it is sufficient simply copy this file to a new name and globally replace the old name with the new.

Why do you use a temporary file?

If I had an email handler program in the cgi-bin directory itself and passed this information on the command line, users could potentially spoof dangerous commands by exploiting the fact that this information is passed to the shell.

Installing an email form

The last step is to create an actual email form for each user. Use the following form as a template, simply modifying my name and the URL of my email script.

<TITLE>Email to Thomas Boutell</TITLE>
<H1>Email to Thomas Boutell</H1>
<P><EM>Note:</EM>This is an HTML form. You MUST have a
browser that supports forms in order to use it. Currently
Mac Mosaic and Windows Mosaic do not support forms. If you have
difficulties, send email directly to boutell@netcom.com.

<P>Enter your message in the areas provided below. Be sure to
fill out all of the fields.
<HR>
<FORM METHOD="POST" ACTION="http:/cgi-bin/eboutell">
<INPUT NAME="name">Your Name<P>
<INPUT NAME="email">Your Email Address<P>
<INPUT NAME="subject">Subject<P>
<P>Text:<P>
<TEXTAREA NAME="content" ROWS=10 COLS=60></TEXTAREA> <P>
Click <INPUT TYPE="submit" VALUE="submit"> to submit your
message. Click <INPUT TYPE="reset" VALUE="reset"> to clear
your message and start over. Click 
<A HREF="http:/boutell.html">here</A> if you wish to abandon your 
message and return to Tom's homepage.
</FORM>
<HR>

Why don't you use sendmail?

Or, to put it differently, "why does mail arrive From: my web server account with a Really-From: line set to the correct user?"

I originally used /usr/bin/mail because I was unfamiliar with sendmail. But I have since decided I like it this way because there is no way to be sure email sent through a web form is really from the user it claims to be from. This serves to remind me that I should take the Really-From: line with a grain of salt, and I set the Reply-To: line correctly so responding to letters is no problem. If you don't care for this philosophy, change the code to spawn sendmail instead.

That should do it!

This should be enough information to allow you to set up your own email-handling forms. Please contact Thomas Boutell if you have any difficulties.

Up to the Quest Home Page