#!/usr/bin/perl -wT
#
# NMS FormMail Version 3.14c1
#
use strict;
use vars qw(
$DEBUGGING $emulate_matts_code $secure %more_config
$allow_empty_ref $max_recipients $mailprog @referers
@allow_mail_to @recipients %recipient_alias
@valid_ENV $date_fmt $style $send_confirmation_mail
$confirmation_text $locale $charset $no_content
$double_spacing $wrap_text $wrap_style $postmaster
$address_style
);
# PROGRAM INFORMATION
# -------------------
# FormMail.pl Version 3.14c1
#
# This program is licensed in the same way as Perl
# itself. You are free to choose between the GNU Public
# License <http://www.gnu.org/licenses/gpl.html> or
# the Artistic License
# <http://www.perl.com/pub/a/language/misc/Artistic.html>
#
# For help on configuration or installation see the
# README file or the POD documentation at the end of
# this file.
# USER CONFIGURATION SECTION
# --------------------------
# Modify these to your own settings. You might have to
# contact your system administrator if you do not run
# your own web server. If the purpose of these
# parameters seems unclear, please see the README file.
#
BEGIN
{
$DEBUGGING = 1;
$emulate_matts_code= 0;
$secure = 1;
$allow_empty_ref = 1;
$max_recipients = 5;
$mailprog = '/usr/sbin/sendmail -oi -t';
$postmaster = '';
@referrer = qw(inspirationscenter.org www.inspirationscenter.org);
@allow_mail_to = qw(form@inspirationscenter.org);
@recipients = ();
%recipient_alias = ('1' => 'form@inspirationscenter.org');
@valid_ENV = qw(REMOTE_HOST REMOTE_ADDR REMOTE_USER HTTP_USER_AGENT);
$locale = '';
$charset = 'iso-8859-1';
$date_fmt = '%A, %B %d, %Y at %H:%M:%S';
$style = '';
$no_content = 0;
$double_spacing = 1;
$wrap_text = 0;
$wrap_style = 1;
$address_style = 0;
$send_confirmation_mail = 0;
$confirmation_text = <<'END_OF_CONFIRMATION';
From: form@inspirationscenter.org
Subject: form submission
Thank you for your form submission.
END_OF_CONFIRMATION
# You may need to uncomment the line below and adjust the path.
# use lib './lib';
# USER CUSTOMISATION SECTION
# --------------------------
# Place any custom code here
# USER CUSTOMISATION << END >>
# ----------------------------
# (no user serviceable parts beyond here)
}
#
# The code below consists of module source inlined into this
# script to make it a standalone CGI.
#
# Inlining performed by NMS inline - see /v2/buildtools/inline
# in CVS at http://sourceforge.net/projects/nms-cgi for details.
#
BEGIN {
$CGI::NMS::INLINED_SOURCE::CGI_NMS_Mailer = <<'END_INLINED_CGI_NMS_Mailer';
package CGI::NMS::Mailer;
use strict;
use POSIX qw(strftime);
=head1 NAME
CGI::NMS::Mailer - email sender base class
=head1 SYNOPSYS
use base qw(CGI::NMS::Mailer);
...
=head1 DESCRIPTION
This is a base class for classes implementing low-level email
sending objects for use within CGI scripts.
=head1 METHODS
=over
=item output_trace_headers ( TRACEINFO )
Uses the print() virtual method to output email abuse tracing headers
including whatever useful information can be gleaned from the CGI
environment variables.
The TRACEINFO parameter should be a short string giving the name and
version of the CGI script.
=cut
sub output_trace_headers {
my ($self, $traceinfo) = @_;
$ENV{REMOTE_ADDR} =~ /^\[?([\d\.\:a-f]{7,100})\]?$/i or die
"failed to get remote address from [$ENV{REMOTE_ADDR}], so can't send traceable email";
$self->print("Received: from [$1]\n");
my $me = ($ENV{SERVER_NAME} =~ /^([\w\-\.]{1,100})$/ ? $1 : 'unknown');
$self->print("\tby $me ($traceinfo)\n");
my $date = strftime '%a, %e %b %Y %H:%M:%S GMT', gmtime;
$self->print("\twith HTTP; $date\n");
if ($ENV{SCRIPT_NAME} =~ /^([\w\-\.\/]{1,100})$/) {
$self->print("\t(script-name $1)\n");
}
if (defined $ENV{HTTP_HOST} and $ENV{HTTP_HOST} =~ /^([\w\-\.]{1,100})$/) {
$self->print("\t(http-host $1)\n");
}
my $ff = $ENV{HTTP_X_FORWARDED_FOR};
if (defined $ff) {
$ff =~ /^\s*([\w\-\.\[\] ,]{1,200})\s*/ or die
"malformed X-Forwarded-For [$ff], suspect attack, aborting";
$self->print("\t(http-x-forwarded-for $1)\n");
}
my $ref = $ENV{HTTP_REFERER};
if (defined $ref and $ref =~ /^([\w\-\.\/\:\;\%\@\#\~\=\+\?]{1,100})$/) {
$self->print("\t(http-referer $1)\n");
}
}
=back
=head1 VIRTUAL METHODS
Subclasses must implement the following methods:
=over
=item newmail ( TRACEINFO, SENDER, @RECIPIENTS )
Starts a new email. TRACEINFO is the script name and version, SENDER is
the email address to use as the envelope sender and @RECIPIENTS is a list
of recipients. Dies on error.
=item print ( @ARGS )
Concatenates the arguments and appends them to the email. Both the
header and the body should be sent in this way, separated by a single
blank line. Dies on error.
=item endmail ()
Finishes the email, flushing buffers and sending it. Dies on error.
=back
=head1 SEE ALSO
L<CGI::NMS::Mailer::Sendmail>, L<CGI::NMS::Mailer::SMTP>,
L<CGI::NMS::Script>
=head1 MAINTAINERS
The NMS project, E<lt>http://nms-cgi.sourceforge.net/E<gt>
To request support or report bugs, please email
E<lt>nms-cgi-support@lists.sourceforge.netE<gt>
=head1 COPYRIGHT
Copyright 2003 London Perl Mongers, All rights reserved
=head1 LICENSE
This module is free software; you are free to redistribute it
and/or modify it under the same terms as Perl itself.
=cut
1;
END_INLINED_CGI_NMS_Mailer
$CGI::NMS::INLINED_SOURCE::CGI_NMS_Mailer_SMTP = <<'END_INLINED_CGI_NMS_Mailer_SMTP';
package CGI::NMS::Mailer::SMTP;
use strict;
use IO::Socket;
BEGIN {
do {
unless (eval {local $SIG{__DIE__} ; require CGI::NMS::Mailer}) {
eval $CGI::NMS::INLINED_SOURCE::CGI_NMS_Mailer or die $@;
$INC{'CGI/NMS/Mailer.pm'} = 1;
}
undef $CGI::NMS::INLINED_SOURCE::CGI_NMS_Mailer; # to save memory
};
import CGI::NMS::Mailer }
use base qw(CGI::NMS::Mailer);
=head1 NAME
CGI::NMS::Mailer::SMTP - mail sender using SMTP
=head1 SYNOPSYS
my $mailer = CGI::NMS::Mailer::SMTP->new('mailhost.bigisp.net');
$mailer->newmail($from, $to);
$mailer->print($email_header_and_body);
$mailer->endmail;
=head1 DESCRIPTION
This implementation of the mailer object defined in L<CGI::NMS::Mailer>
uses an SMTP connection to a mail relay to send the email.
=head1 CONSTRUCTORS
=over
=item new ( MAILHOST )
MAILHOST must be the name or dotted decimal IP address of an SMTP
server that will relay mail for the web server.
=cut
sub new {
my ($pkg, $mailhost) = @_;
$mailhost .= ':25' unless $mailhost =~ /:/;
return bless { Mailhost => $mailhost }, $pkg;
}
=back
=head1 METHODS
See L<CGI::NMS::Mailer> for the user interface to these methods.
=over
=item newmail ( SCRIPTNAME, SENDER, @RECIPIENTS )
Opens the SMTP connection and sends trace headers.
=cut
This implementation of the mailer object defined in L<CGI::NMS::Mailer>
uses an SMTP connection to a mail relay to send the email.
=head1 CONSTRUCTORS
=over
=item new ( MAILHOST )
MAILHOST must be the name or dotted decimal IP address of an SMTP
server that will relay mail for the web server.
=cut
sub new {
my ($pkg, $mailhost) = @_;
$mailhost .= ':25' unless $mailhost =~ /:/;
return bless { Mailhost => $mailhost }, $pkg;
}
=back
=head1 METHODS
See L<CGI::NMS::Mailer> for the user interface to these methods.
=over
=item newmail ( SCRIPTNAME, SENDER, @RECIPIENTS )
Opens the SMTP connection and sends trace headers.
=cutThis implementation of the mailer object defined in L<CGI::NMS::Mailer>
uses an SMTP connection to a mail relay to send the email.
=head1 CONSTRUCTORS
=over
=item new ( MAILHOST )
MAILHOST must be the name or dotted decimal IP address of an SMTP
server that will relay mail for the web server.
=cut
sub new {
my ($pkg, $mailhost) = @_;
$mailhost .= ':25' unless $mailhost =~ /:/;
return bless { Mailhost => $mailhost }, $pkg;
}
=back
=head1 METHODS
See L<CGI::NMS::Mailer> for the user interface to these methods.
=over
=item newmail ( SCRIPTNAME, SENDER, @RECIPIENTS )
Opens the SMTP connection and sends trace headers.
=cutThis implementation of the mailer object defined in L<CGI::NMS::Mailer>
uses an SMTP connection to a mail relay to send the email.
=head1 CONSTRUCTORS
=over
=item new ( MAILHOST )
MAILHOST must be the name or dotted decimal IP address of an SMTP
server that will relay mail for the web server.
=cut
sub new {
my ($pkg, $mailhost) = @_;
$mailhost .= ':25' unless $mailhost =~ /:/;
return bless { Mailhost => $mailhost }, $pkg;
}
=back
=head1 METHODS
See L<CGI::NMS::Mailer> for the user interface to these methods.
=over
=item newmail ( SCRIPTNAME, SENDER, @RECIPIENTS )
Opens the SMTP connection and sends trace headers.
=cutThis implementation of the mailer object defined in L<CGI::NMS::Mailer>
uses an SMTP connection to a mail relay to send the email.
=head1 CONSTRUCTORS
=over
=item new ( MAILHOST )
MAILHOST must be the name or dotted decimal IP address of an SMTP
server that will relay mail for the web server.
=cut
sub new {
my ($pkg, $mailhost) = @_;
$mailhost .= ':25' unless $mailhost =~ /:/;
return bless { Mailhost => $mailhost }, $pkg;
}
=back
=head1 METHODS
See L<CGI::NMS::Mailer> for the user interface to these methods.
=over
=item newmail ( SCRIPTNAME, SENDER, @RECIPIENTS )
Opens the SMTP connection and sends trace headers.
=cutThis implementation of the mailer object defined in L<CGI::NMS::Mailer>
uses an SMTP connection to a mail relay to send the email.
=head1 CONSTRUCTORS
=over
=item new ( MAILHOST )
MAILHOST must be the name or dotted decimal IP address of an SMTP
server that will relay mail for the web server.
=cut
sub new {
my ($pkg, $mailhost) = @_;
$mailhost .= ':25' unless $mailhost =~ /:/;
return bless { Mailhost => $mailhost }, $pkg;
}
=back
=head1 METHODS
See L<CGI::NMS::Mailer> for the user interface to these methods.
=over
=item newmail ( SCRIPTNAME, SENDER, @RECIPIENTS )
Opens the SMTP connection and sends trace headers.
=cutThis implementation of the mailer object defined in L<CGI::NMS::Mailer>
uses an SMTP connection to a mail relay to send the email.
=head1 CONSTRUCTORS
=over
=item new ( MAILHOST )
MAILHOST must be the name or dotted decimal IP address of an SMTP
server that will relay mail for the web server.
=cut
sub new {
my ($pkg, $mailhost) = @_;
$mailhost .= ':25' unless $mailhost =~ /:/;
return bless { Mailhost => $mailhost }, $pkg;
}
=back
=head1 METHODS
See L<CGI::NMS::Mailer> for the user interface to these methods.
=over
=item newmail ( SCRIPTNAME, SENDER, @RECIPIENTS )
Opens the SMTP connection and sends trace headers.
=cutThis implementation of the mailer object defined in L<CGI::NMS::Mailer>
uses an SMTP connection to a mail relay to send the email.
=head1 CONSTRUCTORS
=over
=item new ( MAILHOST )
MAILHOST must be the name or dotted decimal IP address of an SMTP
server that will relay mail for the web server.
=cut
sub new {
my ($pkg, $mailhost) = @_;
$mailhost .= ':25' unless $mailhost =~ /:/;
return bless { Mailhost => $mailhost }, $pkg;
}
=back
=head1 METHODS
See L<CGI::NMS::Mailer> for the user interface to these methods.
=over
=item newmail ( SCRIPTNAME, SENDER, @RECIPIENTS )
Opens the SMTP connection and sends trace headers.
=cutThis implementation of the mailer object defined in L<CGI::NMS::Mailer>
uses an SMTP connection to a mail relay to send the email.
=head1 CONSTRUCTORS
=over
=item new ( MAILHOST )
MAILHOST must be the name or dotted decimal IP address of an SMTP
server that will relay mail for the web server.
=cut
sub new {
my ($pkg, $mailhost) = @_;
$mailhost .= ':25' unless $mailhost =~ /:/;
return bless { Mailhost => $mailhost }, $pkg;
}
=back
=head1 METHODS
See L<CGI::NMS::Mailer> for the user interface to these methods.
=over
=item newmail ( SCRIPTNAME, SENDER, @RECIPIENTS )
Opens the SMTP connection and sends trace headers.
=cutThis implementation of the mailer object defined in L<CGI::NMS::Mailer>
uses an SMTP connection to a mail relay to send the email.
=head1 CONSTRUCTORS
=over
=item new ( MAILHOST )
MAILHOST must be the name or dotted decimal IP address of an SMTP
server that will relay mail for the web server.
=cut
sub new {
my ($pkg, $mailhost) = @_;
$mailhost .= ':25' unless $mailhost =~ /:/;
return bless { Mailhost => $mailhost }, $pkg;
}
=back
=head1 METHODS
See L<CGI::NMS::Mailer> for the user interface to these methods.
=over
=item newmail ( SCRIPTNAME, SENDER, @RECIPIENTS )
Opens the SMTP connection and sends trace headers.
=cut
This implementation of the mailer object defined in L<CGI::NMS::Mailer>
uses an SMTP connection to a mail relay to send the email.
=head1 CONSTRUCTORS
=over
=item new ( MAILHOST )
MAILHOST must be the name or dotted decimal IP address of an SMTP
server that will relay mail for the web server.
=cut
sub new {
my ($pkg, $mailhost) = @_;
$mailhost .= ':25' unless $mailhost =~ /:/;
return bless { Mailhost => $mailhost }, $pkg;
}
=back
=head1 METHODS
See L<CGI::NMS::Mailer> for the user interface to these methods.
=over
=item newmail ( SCRIPTNAME, SENDER, @RECIPIENTS )
Opens the SMTP connection and sends trace headers.
=cut
sub newmail {
my ($self, $scriptname, $sender, @recipients) = @_;
$self->{Sock} = IO::Socket::INET->new($self->{Mailhost});
defined $self->{Sock} or die "connect to [$self->{Mailhost}]: $!";
my $banner = $self->_smtp_response;
$banner =~ /^2/ or die "bad SMTP banner [$banner] from [$self->{Mailhost}]";
my $helohost = ($ENV{SERVER_NAME} =~ /^([\w\-\.]+)$/ ? $1 : '.');
$self->_smtp_command("HELO $helohost");
$self->_smtp_command("MAIL FROM:<$sender>");
foreach my $r (@recipients) {
$self->_smtp_command("RCPT TO:<$r>");
}
$self->_smtp_command("DATA", '3');
$self->output_trace_headers($scriptname);
}
=item print ( @ARGS )
Writes some email body to the SMTP socket.
=cut
sub print {
my ($self, @args) = @_;
my $text = join '', @args;
$text =~ s#\n#\015\012#g;
$text =~ s#^\.#..#mg;
$self->{Sock}->print($text) or die "write to SMTP socket: $!";