# Archivists note:
This script requires perl5
#!/usr/bin/perl -T
##
## rjsemail.cgi - Simple, Safe, Generic CGI backend mail script.
##
## by Robert Seymour <
[email protected]>.
## Copyright (c) 1995, 1996 Robert Seymour and Springer-Verlag.
## All rights reserved, this script may be distributed in
## electronic format and/or modified under the same terms as Perl
## itself.
##
## CPAN menu entry:
#
# File Name: rjsemail.cgi
# File Size in BYTES: 5981
# Sender/Author/Poster: Robert J. Seymour <
[email protected]>
# Subject: rjsemail.cgi - Simple, Safe, Generic CGI backend mail script.
#
# rjsemail.cgi provides a simple, safe, and generic backend for sending
# electronic mail from a CGI program. This script is taint checked and
# does not allow insipid commands to be executed or information to be
# divulged through user inputted strings. You can use this script as a
# common backend for all your mail sending (HTML page example included)
# or use it as a guide to safe use of subprocesses in CGI programs.
## To use this script, you should create an HTML page (or script which
## generates an HTML page) with a submission form pointing to this
script.
## An example of this is shown below:
##
## <HTML><HEAD><TITLE>Submit Feedback</TITLE></HEAD>
## <BODY><H1>Submit Feedback</H1>
## <p>Please feel free to enter in feedback below:</p>
## <FORM METHOD="POST" ACTION="/cgi-bin/email.cgi">
## <INPUT TYPE="HIDDEN" NAME="to" VALUE="
[email protected]">
## <P>Please enter in your email address:<BR>
## <INPUT TYPE="TEXT" NAME="from" SIZE="40">
## </P>
## <P>Please input the subject of your message:<BR>
## <INPUT TYPE="TEXT" NAME="subject" SIZE="40">
## </P>
## <P>Please input the body of the message:<BR>
## <TEXTAREA NAME="body" ROWS="50" COLS="70">
## </TEXTAREA>
## <P><INPUT TYPE="SUBMIT" VALUE="Send Email">
## <INPUT TYPE="RESET" VALUE="Reset Form">
## </P>
## </FORM>
## </BODY>
##
## You can also fix the subject header by making it a hidden field as
## well (and similarly for the other entries). Note also that you need
## not use the exact elements shown here, any HTML forms element which
## generates a string as a value (i.e. selection lists, popup menus, or
## others) will work. Don't forget to the set the "to" email address
## properly in your HTML page.
## Use the CGI::* modules for CGI, log, and HTML processing.
use CGI::Carp;
use CGI::Form;
use strict;
## Variable initializations (for use strict).
my($to,$admin,$from,$subject,$body,$sendmail,$query);
## Where is sendmail located.
$sendmail = "/usr/lib/sendmail";
## Set the path for security and taint checking.
$ENV{'PATH'} = "/usr/bin:/bin";
## Create a new query object for CGI and HTML parsing.
$query = new CGI::Form();
## If you want to hardcode any of these, just set them up by $sendmail
## in the constants section, they will only be overriden if unset by
## these statements. You might also choose to append to the message
## here to indicate that the from address is not verified. In general,
## I would advise you to set them in your pages, this lets the program
## work for many different pages or submissions.
$to ||= $query->param("to");
$admin = $admin || $query->param("admin") || $query->param("to");
$from ||= $query->param("from");
$subject ||= $query->param("subject");
$body ||= $query->param("body");
## Append a warning to the message about forgery and origin.
$body .= <<"EOHF";
--
Message sent via rjsemail.cgi, sender's address may be forged.
EOHF
## Start sendmail taking input on STDIN to be sent off. By using
## sendmail -oit and writing to it with a here file (as below), we
## avoid sh -c gotchas that backticks, system, or "| $mail $addr"
## can fall victim to. Searching for semi-colons isn't safe enough
## and trying to scrub user inputted fields is both difficult and
## hazardous.
open(MAIL,"| $sendmail -oi -t") || do {
print $query->header();
print $query->start_html(-title => "Error Sending Mail",
-author => $admin);
print "<h1>Error Sending Mail</h1>\n";
print "<p>Sendmail exited with error: $!, please go back in your\n";
print " browser and resubmit the email form or report the error\n";
print qq/ to the administrator, <a
href="mailto:$admin">$admin<\/a>"\n/;
print "</p>\n";
print $query->end_html(), "\n";
## CGI::Carp makes semi-useful error entries in the httpd error log.
die "Sendmail exited with error: $!\n";
};
## Print message to sendmail filehandle. Note that you can't create
## a shell or escape out of this by entering in code to the text block
## or email fields (even backticks). The to address is taken from the
## submission form (use a hidden field) so that this same backend script
## can service any number of HTML submission forms.
print MAIL <<"EOHF";
To: $to
From: $from
Subject: $subject
X-Mailer: rjsemail.cgi 1.0
$body
EOHF
close(MAIL);
## Check exit status (the latter uses CGI::Carp). Give the user
## feedback through a HTML response.
if($?) {
print $query->header();
print $query->start_html(-title => "Error Sending Mail",
-author => $admin);
print "<h1>Error Sending Mail</h1>\n";
print "<p>Sendmail exited with error: $!, please go back in your\n";
print " browser and correct the email form or report the error\n";
print qq/ to the administrator, <a
href="mailto:$admin"><$admin><\/a>"\n/;
print "</p>\n";
print $query->end_html(), "\n";
## CGI::Carp makes semi-useful error logs in the httpd log.
croak "Sendmail exited with error: $!\n";
} else {
print $query->header();
print $query->start_html(-title => "Thank You For Your Feedback",
-author => $admin);
print "<h1>Thank Your For Your Feedback</h1>\n";
print "<p>I appreciate your comments and will try to respond to\n";
print " your email shortly.\n</p>\n";
print $query->end_html(), "\n";
}
## End of rjsemail.cgi.