[cvs] / cgi / mailback / mailback.pl Repository:

View of /cgi/mailback/mailback.pl

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.4 - (annotate)
Mon Feb 6 18:03:49 2006 UTC (4 years ago) by erik
Branch: MAIN
Changes since 1.3: +6 -5 lines
Returns and newslines are now removed from the subject line.
#!/usr/local/bin/taintperl

#   $Id: mailback.pl,v 1.4 2006/02/06 18:03:49 erik Exp $
#
#   Author: Erik C. Thauvin <erik@skytouch.com>
#
#   Thanks to David Walker <dwalker@eskimo.com> and Robert Dinse
#   <nanook@eskimo.com> for the great suggestions.
#
#   This script will mail the content of any HTML form to its author.
#
#   Based on "mailback.pl" by Phillip Moore <phil@erc.msstate.edu>
#   Source available at http://www.erc.msstate.edu/~phil/src/mailback.pl
#
#   Also based on "sendmail-cgi.pl" by Erik C. Thauvin <erik@skytouch.com>
#   Copyright (C) 1995-2006 Erik C. Thauvin. All rights reserved.
#
#   Date:   2006-02-06    
#
#   Usage:  You must reference this script in your HTML forms with
#           the method=POST option. Options are passed inside the
#           the document with the input tag, as follows:
#
#   <input name="variable-name" type="input-type" value="default-value">
#
#           The variable-name represents parameters for this script.
#           The following are reserved names used by the script and
#           must be specified in your HTML documents/forms:
#
#           mailitto (req)  - Full internet mail address of mail recipient.
#                             This MUST be your email address on Eskimo.
#
#           namefrom (req)  - Name of the person the submission is from.
#
#           mailfrom (req)  - Email address of the person the submission
#                             is from.
#
#           subject  (req)  - Subject of the email message.
#
#           bcc             - If defined, sends a blind carbon copy of the
#                             mail message to the person submitting the form.
#
#           showreport      - If defined, a mail status report is shown upon
#                             submission; otherwise a generic confirmation
#                             message is displayed.
#
#           returngraphic   - Inline image to be displayed at the bottom of
#                             the mail confirmation/status report.
#
#           returntext      - If "retrungraphic" is defined, the text is used
#                             as an alternate to the "returngraphic" for non-
#                             graphical browsers, such as lynx.
#                             If "returngraphic" is not defined, the text is
#                             displayed instead of the image.
#
#           returnurl       - The URL of "returngraphic" and/or "returntext".
#                             If not defined, the URL of the previous page is
#                             used.
#
#           returnmsg       - The actual confirmation message. If not defined,
#                             a generic message is used.
#
#           returntitle     - The confirmation message's title. If not defined,
#                             "Mail Confirmation" is used.
#
#           returnpage      - The URL of a custom "Mail Confirmation" page.
#                             Overrides "showreport", "returntext", "returnurl",
#                             "returngraphic", "returnmsg" and "returntitle".
#
#           subtag          - The name of one of the form's input tag. If valid,
#                             the tag's value will be affixed to the subject of
#                             the mail.
#
#           bodytags        - The HTML elements to be included in the <body> tag
#                             of the confirmation/error messages. Example:
#                             
#                             ... value="bgcolor=#FFFFFF vlink=#008000" ...
#
#           base            - The URL to be used in the <base> HTML tag of the
#                             confirmation/error messages.
#
#           nozeros         - Suppresses input tags whose values are 0.
#
#           noblanks        - Suppresses input tags whose values are blank.
#
#           notags          - Suppresses input tags from email message.
#
#           senderinfo      - Includes "namefrom" and "mailfrom" in the body
#                             of the email message.
#
#           The ones with (req) are required but may be written into the HTML
#           form so that users cannot change them. For example:
#
#           <HTML>
#           <TITLE>Mailback Sample Form</TITLE>
#           <BODY>
#           <FORM ACTION="http:/cgi-bin/mailback" METHOD="POST">
#           <INPUT TYPE="HIDDEN" NAME="mailitto" VALUE="johndoe@eskimo.com"> 
#           <INPUT TYPE="HIDDEN" NAME="returnurl" VALUE="/~johndoe/mypage.html">
#           <INPUT TYPE="HIDDEN" NAME="returntext" VALUE="Back to my Home Page.">
#           <INPUT TYPE="HIDDEN" NAME="notags">
#           <INPUT TYPE="HIDDEN" NAME="showreport">
#           Your Name:  <INPUT TYPE="TEXT" NAME="namefrom" SIZE=35><BR>
#           Your Email Address:  <INPUT TYPE="TEXT" NAME="mailfrom" SIZE=35><BR>
#           Subject: <INPUT TYPE="TEXT" NAME="subject" SIZE=35><P>
#           Your Message:<BR>
#           <TEXTAREA NAME="message" ROWS="10" COLS="60"></TEXTAREA><P>
#           <INPUT TYPE="RESET" VALUE="Clear Form">
#           <INPUT TYPE="SUBMIT" VALUE="Send Mail">
#           </FORM>
#           </BODY>
#           </HTML>
#
# This software is provided "as is" without express or implied warranties.
#
# Permission is granted to use, copy, modify and distribute this software,
# provided this disclaimer and copyright are preserved on all copies. This
# software may not, however, be sold or distributed for profit, or included
# with other software which is sold or distributed for profit, without the
# permission of the author.
#
                            
$ENV{'PATH'} = '/bin:/usr/bin:/usr/lib';
$ENV{'IFS'} = '';


#
# Mail server address & port
#
$mailserv = 'mail.eskimo.com';
$mailport = 25;


#
# CRLF
#
$eol = "\015\012";


#
# Try SMTP?
#
$trysmtp = 0;


#
# Valid mail server hosts
#
@validhosts = ( 'eskimo.com', 'skytouch.com' );


#
# Print text/html error message
#
sub error
{
    local($msg) = @_;

    &printheader('Error');
    print "<h1><hr><font size=5>Error</font><hr></h1>\n<blockquote>\n$msg\n</blockquote>\n<p>\n";
    &printfooter;
    exit 1;
}


#
# Return error if mail could not be sent
#
sub mailerror
{
    close(SOCK);
    &error("An timeout error (ID=@_) occurred while sending mail. Please try "
         . "again later or <a href=\"mailto:$posted{mailitto}\">notify</a> "
         . "the creator of this page.\n<p>\n<p>\nThank you.");
}


#
# Print detailed text/html error message 
#
sub notenoughinfo
{
    local($msg) = @_;

    if ($infoerr == 0)
    {
        &printheader("Error");
        print "<h1><hr><font size=5>Error</font><hr></h1>\n"
            . "<h2>Not Enough Information:</h2>"
            . "<blockquote>\n$msg\n</blockquote>\n";
    }
    else
    {
        print "<h3>And</h3>\n<blockquote>\n$msg\n</blockquote>\n";
    }
    $infoerr++;
}


#
# Print html header
#
sub printheader
{
    local($title) = @_;

    print "Content-Type: text/html$eol$eol"
        . "<html>\n<head>\n";

    if (defined($posted{base}))
    {
        print "<base href=\"$posted{base}\">\n";
    }
    
    print "<title>$title</title>\n";

    if (defined($posted{bodytags}))
    {
        print "</head>\n<body $posted{bodytags}>\n";
    }
    else
    {
        print "</head>\n<body bgcolor=#ffffff>\n";
    }
}


#
# Print html footer
#
sub printfooter
{
    if (!defined($posted{skipRSLlink}))
    {
        print "<a href=\"http://www.skytouch.com/\"><img align=\"right\" alt=\"Designed by...\" src=\"http://www.skytouch.com/images/skytouch-mini.gif\" border=\"0\"></a>";
    }
    else
    {
        print "<a href=\"#\" onmouseover=\"window.status = 'Designed by SkyTouch Communications'; return(true);\"><img align=\"right\" alt=\"Designed by SkyTouch Communications\" src=\"http://www.skytouch.com/images/skytouch-mini.gif\"></a>";
    }    

    print "<hr>\n";
    
    if (defined($posted{returnurl}))
    {
        if (defined($posted{returngraphic}) && defined($posted{returntext}))
        {
            print "<a href=\"$posted{returnurl}\"><img src=\"$posted{returngraphic}\" alt=\"$posted{returntext}\"></a>\n";
        }
        elsif (defined($posted{returngraphic}))
        {
            print "<a href=\"$posted{returnurl}\"><img src=\"$posted{returngraphic}\"></a>\n";
        }
        elsif (defined($posted{returntext}))
        {
            print "<a href=\"$posted{returnurl}\">$posted{returntext}</a>\n";
        }
        else
        {
            print "Follow this <a href=\"$posted{returnurl}\">link</a> to continue.\n";
        }
    }
    else
    {
        print "Back to the <a href=\"$ENV{HTTP_REFERER}\">previous</a> page.\n";
    }

    print "</body>\n</html>";
}


#
# Get mail server result code
#
sub getresultcode
{
    local($buff, $resultcode, $bits) = "";
    local($timeout, $nbr) = 0;
  
    vec($bits, fileno(SOCK), 1) = 1;
    LOOP: {
        if ($timeout <= 2)
        {
            ($nfound, $bits) = select($bits, undef, undef, 3);
            if ($nfound)
            {
                $nbr = sysread(SOCK, $buff, 1024);
                if ($nbr > 0)
                {
                    if (length($resultcode) < 3)
                    {
                        $resultcode .= substr($buff, 0, 3);
                        if ($resultcode == 220)
                        {
                            $timeout++;
                            redo LOOP;
                        }
                    }
                    if (substr($buff, -1, 1) ne "\012")
                    {
                        $timeout++;
                        redo LOOP;
                    }
                }
            }
            else
            {
                $timeout++;
                redo LOOP;
            } 
        }
        else
        {
            if ($resultcode != 220)
            {
                $resultcode = 554;
            }
        }
    }
    return $resultcode;
}


#
# Get host address
#
sub getaddress 
{
    local($host) = @_;
    local(@addrs);

    @addrs = gethostbyname($host);
    return(unpack("C4", $addrs[4]));
}


#
# Verify mail host validity
#
sub isvalidhost
{
    local($email) = @_;
    local($name, $host) = split('@', $email);
 
    foreach (@validhosts)
    {
        if ( /$host/i )
        {
             return 1;
        }
    }
    return 0;
}

#
# Ensure that the proper environment variables are defined
#
if (!defined($ENV{REQUEST_METHOD}) || $ENV{REQUEST_METHOD} ne "POST")
{
    &error("This script should be referenced with a METHOD of POST. If you "
         . "don't understand this, see the <a href=\"http://www.ncsa.uiuc.edu/SDG"
         . "/Software/Mosaic/Docs/fill-out-forms/overview.html\">forms overview"
         . "</a>.\n<p>\n<p>\nThank you.");
} 

#
# More environment variables
#
if (!defined($ENV{CONTENT_TYPE}) || $ENV{CONTENT_TYPE} ne "application/x-www-form-urlencoded")
{
    &error("This script can only be used to decode form results.");
}

#
# Read in the message based on the CONTENT_LENGTH in the header.
# If no CONTENT_LENGTH, complain about the error.
#
if (defined($ENV{CONTENT_LENGTH}) && $ENV{CONTENT_LENGTH} != 0)
{
    $bytes = read(STDIN, $all, $ENV{CONTENT_LENGTH});
    foreach $pair (split("&", $all))
    {
        ($key, $val) = split("=", $pair);
        $val =~ tr/+/ /;
        $val =~ s/%(..)/pack("c", hex($1))/eg;
#       $val =~ s/\n/\n /g;

        if (defined($posted{$key}))
        {
            $posted{$key} = "$posted{$key}\n$val";
        }
        else
        {
            $posted{$key} = $val;
            push(@keylist, $key) if (   $key ne "mailitto" &&
                                        $key ne "errorsto" &&
                                        $key ne "namefrom" &&
                                        $key ne "mailfrom" &&
                                        $key ne "subject" &&
                                        $key ne "bcc" &&
                                        $key ne "showreport" &&
                                        $key ne "returnurl" &&
                                        $key ne "returntext" &&
                                        $key ne "returngraphic" &&
                                        $key ne "skipRSLlink" &&
                                        $key ne "returnmsg" &&
                                        $key ne "returntitle" &&
                                        $key ne "returnpage" &&
                                        $key ne "subtag" &&
                                        $key ne "bodytags" &&
                                        $key ne "base" &&
                                        $key ne "nozeros" &&
                                        $key ne "noblanks" &&
                                        $key ne "senderinfo" &&
                                        $key ne "notags"    );
        }
    }
}
else
{
    &error("This script, the URL, or the fields given in the form returned "
         . "an error. Please notify the creator of this page.\n<p>\n<p>\n"
         . "Thank you.");
}

#
# Check that each of the four required fields are entered properly
# Make sure user has entered "mailitto" , "mailfrom", "namefrom"
# and "subject"
#
### To: ###
if (!defined($posted{mailitto}) || !&isvalidhost($posted{mailitto}))
{
    &notenoughinfo("The creator of the form you are using failed to provide "
                 . "a valid e-mail address. Please try again later, or send "
                 . "mail to the person who created this form.<p>");
}

### From ###
if (!defined($posted{namefrom}) || $posted{namefrom} =~ /^\s*$/)
{
    &notenoughinfo("Please provide your first and/or last name to help the "
                 . "reader of this message identify you.<p>");
}
else
{
    $posted{namefrom} =~ s/^\s*//;
    $posted{namefrom} =~ s/\s*$//;
}

### From: ###
if (!defined($posted{mailfrom}) ||
    $posted{mailfrom} !~ /^[-._%!*\/+0-9A-Za-z]+@[-0-9A-Za-z.]+\.[A-Za-z][A-Za-z]+$/)
{
    &notenoughinfo("Please provide a full internet mail address so the reader "
                 . "of this message may reply to you.<p>");
}
else
{
    $posted{mailfrom} =~ s/^\s*//;
    $posted{mailfrom} =~ s/\s*$//;
}

### Subject: ###
if (!defined($posted{subject}) || $posted{subject} =~ /^\s*$/)
{
    &notenoughinfo("Please provide a subject to give the reader of this "
                 . "message some clue as to its content.<p>");
}
else
{
    $posted{subject} =~ s/^\s*//;
    $posted{subject} =~ s/\s*$//;
    $posted{subject} =~ s/(\r|\n)//g;
}

#
# As long as those four fields are non-empty, and in a valid format, send it
#
if ($infoerr > 0)
{
    &printfooter;
    exit 1; 
}
else 
{
#
# Connect to the mail server
#
    local($sockaddr, $addr) = ("Snc4x8");
    local($mailagent) = 'sendmail';
    
    if ($trysmtp)
    {
        $addr = pack($sockaddr, 2, $mailport, &getaddress($mailserv));

        if (socket(SOCK, 2, 1, 6))
        {
            if (connect(SOCK, $addr))
            {
                select(SOCK); $| = 1;
                select(STDOUT); $| = 1;
            
                if (&getresultcode == 220)
                {       
                    $mailagent = 'smtp';
                }
            }
        }
    }

#
# Send mail message
#
    if ($mailagent eq 'sendmail')
    {
        close(SOCK);
        open(SOCK, "| /usr/lib/sendmail -t");
    }
    else
    {        
        print SOCK "HELO mailback$eol";
        do { &mailerror(1200); } if (&getresultcode != 250);

        print SOCK "RSET$eol";
        do { &mailerror(1300); } if (&getresultcode != 250);

        print SOCK "MAIL FROM:<>$eol";
        do { &mailerror(1400); } if (&getresultcode != 250);

        print SOCK "RCPT TO:<$posted{mailitto}>$eol";
        do { &mailerror(1500); } if (&getresultcode != 250);
        
        if (defined($posted{bcc}))
        {
            print SOCK "RCPT TO:<$posted{mailfrom}>$eol";
            do { &mailerror(1500); } if (&getresultcode != 250);
        }

        print SOCK "DATA$eol";
        do { &mailerror(1600); } if (&getresultcode != 354);
    }

    print SOCK "From: $posted{mailfrom} ($posted{namefrom})$eol"
             . "To: $posted{mailitto}$eol";

    if (defined($posted{bcc}))
    {
        print SOCK "Bcc: $posted{mailfrom}$eol";
    }
             
    if (defined($posted{$posted{subtag}}))
    {
        print SOCK "Subject: $posted{subject} ($posted{$posted{subtag}})$eol";
    }
    else
    {
        print SOCK "Subject: $posted{subject}$eol";
    }
    
    if (defined($ENV{REMOTE_ADDR})) { print SOCK "X-Remote-Address: $ENV{REMOTE_ADDR}$eol"; }
    if (defined($ENV{REMOTE_HOST})) { print SOCK "X-Remote-Host: $ENV{REMOTE_HOST}$eol"; }
    if (defined($ENV{REMOTE_IDENT})) { print SOCK "X-Remote-Ident: $ENV{REMOTE_IDENT}$eol"; }
    if (defined($ENV{REMOTE_USER})) { print SOCK "X-Remote-User: $ENV{REMOTE_USER}$eol"; }
    if (defined($ENV{HTTP_REFERER})) { print SOCK "X-URL: $ENV{HTTP_REFERER}$eol"; }
    
    print SOCK "X-Mailback-Agent: $mailagent$eol";

    if (defined($posted{senderinfo}))
    {
        if (defined($posted{notags}))
        {
            print SOCK "$eol$posted{namefrom}$eol"
                     . "$eol$posted{mailfrom}$eol";
        }
        else
        {
            print SOCK "$eol--- Sender's Name ---$eol$posted{namefrom}$eol"
                     . "$eol--- Sender's Email Address ---$eol$posted{mailfrom}$eol";
        }
    }
    
    foreach $key (@keylist)
    {
        $keyval = $posted{$key};
     
        if (!(defined($posted{noblanks}) && (length($keyval) == 0)))
        {
            $keyval =~ s/\012\.\015/\012\.\.\015/g;
            $keyval =~ s/\012\.$/\012\.\./;
        
            if (!(defined($posted{nozeros}) && ($keyval eq "0")))
            {
                if (defined($posted{notags}))
                {
                    print SOCK "$eol$keyval$eol";
                }
                else
                {
                    print SOCK "$eol--- $key ---$eol$keyval$eol";
                }
            }
        }
    }

    print SOCK ".$eol";

    if ($mailagent eq 'smtp')
    {
        do { &mailerror(1700); } if (&getresultcode != 250);

        print SOCK "QUIT$eol";
    }
    
    close(SOCK);
}


#
# If "returnpage" is defined...
#
if (defined($posted{returnpage}))
{
    print "Location: $posted{returnpage}$eol$eol";
}
#
# If "showreport" is defined then show the mail report and have a link
# to return back to some page
#
elsif (defined($posted{showreport}))
{
    &printheader("Mail Status Report");
    print "<h1><hr><font size=5>Mail Status Report</font><hr></h1>\n\n<p>\n"
        . "<b>From:</b> $posted{mailfrom} ($posted{namefrom})\n<br>\n"
        . "<b>Sent To:</b> <a href=\"mailto:$posted{mailitto}\">"
        . "$posted{mailitto}</a><br>\n";
        
    if (defined($posted{$posted{subtag}}))
    {
        print "<b>Subject:</b> $posted{subject} ($posted{$posted{subtag}})$eol";
    }
    else
    {
        print "<b>Subject:</b> $posted{subject}$eol";
    }

    print "<blockquote>\n<pre>";
    
    foreach $key (@keylist)
    {
        $keyval = $posted{$key};

        if (!(defined($posted{noblanks}) && (length($keyval) == 0)))
        {
            $keyval =~ s/\&/\&amp\;/g;
            $keyval =~ s/\</\&lt\;/g;
            $keyval =~ s/\>/\&gt\;/g;

            if (!(defined($posted{nozeros}) && ($keyval eq "0")))
            {
                if (defined($posted{notags}))
                {
                    print "$keyval\n";
                }
                else
                {
                    print "$key: $keyval\n";
                }
            }
        }
    }
    print "</pre></blockquote><h2>Thank You!</h2>\n";
    &printfooter;
}
#
# If "showreport" is not defined then just show a message
# of confirmation and have a link to another page
#
else
{
    if (defined($posted{returntitle}))
    {
        &printheader($posted{returntitle});
        print "<h1><hr><font size=5>$posted{returntitle}</font><hr></h1>\n<p>\n";
    }
    else
    { 
        &printheader("Mail Confirmation");
        print "<h1><hr><font size=5>Mail Confirmation</font><hr></h1>\n<p>\n";
    }

    if (defined($posted{returnmsg}))
    {
        print $posted{returnmsg};
    }
    else
    {
        print "<blockquote>\nYour message was sent to <b><a href=\"mailto:$posted{mailitto}\">"
            . "$posted{mailitto}</a></b>\n</blockquote>\n<h2>Thank You!</h2>\n";
    }
    print "\n<p>\n";
    &printfooter;
}
exit 0;

mail

Powered by ViewVC 1.1-dev
Help
svn.thauvin.net
cvs.thauvin.net
ViewVC