#!/usr/bin/perl -w
## STAMP
## Secure, Template-Aware Mail Processor
## Benjamin Trott / ben@rhumba.pair.com
# $Id: stamp.cgi,v 1.9 2001/10/01 21:09:40 btrott Exp $
use strict;
use vars qw( $VERSION );
$VERSION = '0.06';
my $CFG_FILE = "sample.cfg";
use App::Config;
use Mail::Mailer;
use CGI;
my $q = CGI->new;
my($form, $cfg);
error($q, qq(No _form parameter defined.))
unless $form = $q->param('_form');
error($q, qq(Config file does not exist or is not readable.))
unless -R $CFG_FILE;
{
my $form_matched;
$cfg = App::Config->new({ LINEPARSE => sub {
my($tag, $value) = split /\s+/, $_[3], 2;
if (lc $tag eq "form") {
$form_matched = $value eq $form ? 1 : 0;
return 1;
}
!$form_matched;
}}) or error($q, qq(Config object creation failed.));
}
$cfg->define($_) for (qw( Form Redirect MailTemplate Required
PrintBlankFields Referrers Sort
EncryptKey EncryptPublicKeyRing EncryptCompat ));
$cfg->define('To', { ALIAS => 'Recipient' });
$cfg->define('Subject', { DEFAULT => 'WWW Form Submission' });
$cfg->define('MailTransfer', { DEFAULT => 'sendmail' });
$cfg->define('SMTPServer', { DEFAULT => 'localhost' });
$cfg->cfg_file($CFG_FILE);
error($q, qq(To and Redirect are required config options.))
unless $cfg->To && $cfg->Redirect;
if (my $req = $cfg->Required) {
my @missing = grep !$q->param($_), split /\s*,\s*/, $req;
error($q, <$_", @missing ]}
HTML
}
if (my $ref = $cfg->Referrers) {
my $match = join '|', map "\Q$_\E", split /\s*,\s*/, $ref;
error($q, <$ENV{HTTP_REFERER}.
HTML
}
my($body);
if (my $tmpl_path = $cfg->MailTemplate) {
require HTML::Template;
my $tmpl = HTML::Template->new(filename => $tmpl_path, associate => $q)
or error($q, "Failed to create HTML::Template object: $!");
$body = $tmpl->output;
}
else {
my($sort, @order) = ($cfg->Sort);
$sort = '' unless defined $sort;
if ($sort eq 'alphabetical') {
@order = sort $q->param;
} elsif ($sort =~ s/^order:\s*//) {
@order = split /\s*,\s*/, $sort;
} else {
@order = $q->param;
}
for my $p (@order) {
next if $p =~ /^_/ || (!$cfg->PrintBlankFields && !$q->param($p));
$body .= $p . ": " . $q->param($p) . "\n\n";
}
}
if (my $recip = $cfg->EncryptKey) {
eval { require Crypt::OpenPGP; };
error($q, "Crypt::OpenPGP is required for PGP encryption") if $@;
my $pub = $cfg->EncryptPublicKeyRing;
error($q, "You did not set an EncryptPublicKeyRing; this is " .
"required when encrypting STAMP email messages.") unless $pub;
my $compat = $cfg->EncryptCompat or
error($q, "You did not set a compatibility mode for encryption.");
my $pgp = Crypt::OpenPGP->new( PubRing => $pub ) or
error($q, "Failed to create Crypt::OpenPGP object: " .
Crypt::OpenPGP->errstr);
$body = $pgp->encrypt(
Compat => $compat,
Data => $body,
Recipients => $recip,
Armour => 1,
) or error($q, "Error while encrypting: " . $pgp->errstr);
}
my @args = $cfg->MailTransfer eq 'smtp' ? (Server => $cfg->SMTPServer) : ();
my $mailer = Mail::Mailer->new($cfg->MailTransfer, @args);
my $from = $q->param('email'); ## XXX: add _realname
$mailer->open({
To => $cfg->To,
($from ? (From => $from) : ()),
Subject => $cfg->Subject,
});
print $mailer $body;
$mailer->close;
print $q->redirect($cfg->Redirect);
sub error {
my($q, $msg) = @_;
print $q->header, $msg;
exit;
}
__END__
=head1 NAME
STAMP - Secure, Template-Aware Mail Processor
=head1 VERSION
$Revision: 1.9 $
$Date: 2001/10/01 21:09:40 $
=head1 SYNOPSIS
I is a secure, generic HTML form mailer written in Perl. It is easy
to set up and provides security against your system being used as a spam
gateway. I also lets you customize generated email submissions using
templates, and provides optional PGP encryption of email messages.
=head1 DESCRIPTION
I provides secure form processing and email generation, and supports
using templates to control and customize the generated email message. It is
more secure than the standard I script because it relies on a
server-side configuration file to set the recipient and subject of an email
message; this makes it impossible for spammers to use your mail processing
system as a spam gateway.
I also allows you to PGP-encrypt all messages sent through the system.
This functionality requires that you have the I module
installed on your server; I provides a pure-Perl
implementation of the OpenPGP standard, and is compatible with all PGP
implementations (PGP, GnuPG, etc.).
I provides many configuration options to customize the appearance of
the email messages it generates. Foremost among these options is the ability
to use user-defined templates to control the appearance. These templates act
like form letters, in that they contain hooks to insert the values of the
fields on your form.
=head1 CONFIGURATION OPTIONS
I uses server-side configuration files with hard-coded recipient and
subject values to provide security against spammers. In addition to those
fields, configuration files are used to set many other form-specific options.
The configuration file has the following format:
Empty lines and lines starting with C<#> are comments.
All other lines are of the format I. Possible keywords are:
=over 4
=item * Form
Delimits the configuration section for one form; the following declarations,
up to the next I