#!/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 or # the Artistic License # # # 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, L, L =head1 MAINTAINERS The NMS project, Ehttp://nms-cgi.sourceforge.net/E To request support or report bugs, please email Enms-cgi-support@lists.sourceforge.netE =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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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: $!";