#!/usr/bin/perl -T -w use strict; # Contact Form is a Perl script that you can run on your website that will # allow others to send you email through a web interface. # See: http://ostermiller.org/contactform/ # Copyright (C) 2002-2006 Stephen Ostermiller # http://ostermiller.org/contact.pl?regarding=Contact+Form # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # See copying.txt for details. my ($NO_DESCRIPTION, $version, $LETTER, $DIGIT, $DOSEOL, $EOL, $LETTER_DIGIT, $LETTER_DIGIT_HYPHEN, $HEX_DIGIT, $QUOTEDSTRING, $ATOM, $SUBDOMAIN, $WORD, $DOMAIN, $LOCALPART, $EMAIL, $PHONE_DIGIT, $PHONE, $ZIPCODE, $PRICE, $FLOAT, $INTEGER, $SOMETHING, $ANYTHING, $ONE_LINE_REQUIRED, $ONE_LINE_OPTIONAL, $ZIPCODE_REQUIRED, $ZIPCODE_OPTIONAL, $PHONE_REQUIRED, $PHONE_OPTIONAL, $EMAIL_REQUIRED, $EMAIL_OPTIONAL, $PRICE_REQUIRED, $PRICE_OPTIONAL, $FLOAT_REQUIRED, $FLOAT_OPTIONAL, $INTEGER_REQUIRED, $INTEGER_OPTIONAL); &initConstants(); # List of email address to which mail can be sent. # Mail cannot be sent to any email address which is not on this list. # If a single address is listed, it will be a hidden value on the # form, otherwise, the user will be presented with a pulldown menu # of aliases to which email can be sent. # The addresses listed here are never visible via served web pages. my @Aliases = ( #'administrator',&safeHeader($ENV{'SERVER_ADMIN'}), 'Contact','petermadeinpreston@gmail.com', #'postmaster','postmaster@yoursite.tld', ); # Modify the following to control how the HTML pages look # Page titles for the input and thank your pages my $input_page_title = 'Contact Made in Preston'; my $sent_page_title = 'Message Sent'; # Extra text (may be html formatted) that will be placed on # the page before the the form my $input_page_text = '

Fill out the form below to send your comments.

'; my $sent_page_text = '

Thank you for your comments!

'; my $preview_page_text = '

Please review your message before sending it. Changes can be made below.

'; # Page structure -- the look and feel of the page # This variable may be either changed directly, or if the # page_template_file variable is set, this variable is # ignored and the template file is used instead. # Contact form can place content into any of four places: # $title -- the title of the page # $css -- style rules that control how the form looks # $javascript -- client side validation rules. # $content -- the form itself. # The css and title variables are optional and can easily # be omitted and replaced with your own elements to better # suit your taste. The form will not work properly if either # the javascript or content variables are removed or duplicated. my $page_template = ' $title $css $javascript

$title

$content '; # if the template file is set, the page_template variable # is ignored and the template is loaded from the named file. # for example: # my $page_template_file = "mytemplate.html"; # or # my $page_template_file = "/home/me/contact.template"; # If this file is set, the file will be read every time this script # is called, not the most efficient, but very convenient. # The temlate file must be in the same format as page_template. my $page_template_file = ""; # Link back to contact form. # You may remove the link by setting this variable to the empty string: # my $contact_form_link = ""; # If you do remove it, please tell your friends about contact form, # link to contact form somewhere else, write a blog entry about # contact form, post in a forum about contact form, or otherwise # spread the word. my $contact_form_link = "

Contact Form $version

"; # A list of required form variables, along with a regular # expression that describes what a valid submission looks like. # If a field is not in this list, it will not be put in email. # Consider using the following pre-defined regular expressions: # $SOMETHING, $ANYTHING, $ONE_LINE_REQUIRED, $ONE_LINE_OPTIONAL, # $ZIPCODE_REQUIRED, $ZIPCODE_OPTIONAL, $PHONE_REQUIRED, # $PHONE_OPTIONAL, $EMAIL_REQUIRED, $EMAIL_OPTIONAL, $PRICE_REQUIRED, # $PRICE_OPTIONAL, $FLOAT_REQUIRED, $FLOAT_OPTIONAL, # $INTEGER_REQUIRED, $INTEGER_OPTIONAL # You may safely remove the subject, email, name, and message # from the form. The to field should not be removed. my @Form_Fields = ( 'to',$ONE_LINE_REQUIRED, 'email',$EMAIL_REQUIRED, 'name',$ONE_LINE_OPTIONAL, 'subject',$ONE_LINE_REQUIRED, 'message',$SOMETHING, 'regarding',$ANYTHING, 'referrer',$ANYTHING, #'phone',$PHONE_OPTIONAL, #'fax',$PHONE_OPTIONAL, #'address1', $ONE_LINE_OPTIONAL, #'address2', $ONE_LINE_OPTIONAL, #'city', "^(?:[a-zA-Z ]*)\$", #'state', "^(?:AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MD|MH|MA|MI|FM|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VA|VI|WA|WV|WI|WY)", #'zip',$ZIPCODE_OPTIONAL, ); # A user friendly error message for each required # element that a user gets wrong. # Just because a field name is present here, it is not # nessecarily allowed. Make sure it is also in @Form_Fields # If there is no error message, a default is used. my %Error_Messages = ( 'to','You must specify a recipient.', 'email','The email address you entered does not appear to be valid.', 'name','You must enter your name.', 'subject','You must enter a subject.', 'message','You must enter a message.', 'regarding','', 'referrer','', #'phone','The phone number you entered does not appear to be valid.', #'fax','The fax number you entered does not appear to be valid.', #'address1','Please enter your address.', #'address2','Please enter your address.', #'city','Your city does not appear to be valid.', #'state','Please choose your state.', #'zip','Your zipcode does not appear to be valid.', ); # Type of input in web pages for each field. # Currently supported are 'text', 'hidden', 'select', # and 'textarea' # Just because a field name is present here, it is not # nessecarily allowed. Make sure it is also in @Form_Fields # If there is no type, 'text' is assumed. # Setting this for the to field will have no effect since # the to field is handled specially. my %Form_Type = ( 'email','text', 'name','text', 'message','textarea', 'subject','text', 'regarding', 'hidden', 'referrer', 'hidden', #'phone','text', #'fax','text', #'address1','text', #'address2','text', #'city','text', #'state','select', #'zip','text', ); # Description to appear next to entry forms and in # the email or $NO_DESCRIPTION for none # Just because a field name is present here, it is not # nessecarily allowed. Make sure it is also in @Form_Fields # If no description is given the field name followed # by a colon is used. my %Field_Descriptions = ( 'to','To:', 'email','Your email address:', 'name','Your name:', 'subject','Subject:', 'message',$NO_DESCRIPTION, 'regarding',$NO_DESCRIPTION, 'referrer',$NO_DESCRIPTION, #'phone','Phone Number:', #'fax','Fax Number:', #'address1','Address:', #'address2',$NO_DESCRIPTION, #'city','City:', #'state','State:', #'zip','Zipcode:', ); # The names of the fields that are inserted into special places # in the email can be changed by changing these values. # Alias of the address put in the "To:" field of the email. my $field_name_to = 'to'; # Put in the "From:" field of the email. my $field_name_from_email = 'email'; # Put in the "From:" field of the email in parenthesis. my $field_name_from_name = 'name'; # Put in the "Subject:" field of the email. my $field_name_subject = 'subject'; # Put in the "Subject:" field of the email in parenthesis. my $field_name_regarding = 'regarding'; # The original referring url. my $field_name_referrer = 'referrer'; # The submit/preview action my $field_name_submit = 'do'; # Regular expression describing urls which can host forms # pointing to this program. The referral URL is generated on the # client side by the browser. Therefore it useless to prevent # unauthorized submission by mail software robots. You can # prevent somebody from reliably hosting, on another server, # a form pointing to this email software. # This form can be used from any site at all. my $allowedReferers = '.*'; # This form can only be used from pages on yoursite.tld #my $allowedReferers = '^http[s]?\\:\\/\\/yoursite\\.tld\\/'; # This form can only be used from pages on the domain or ip address #my $allowedReferers = '^http[s]?\\:\\/\\/((yoursite\\.tld)|(127\\.0\\.0\\.1))\\/'; # This form can only be used from a specific page. #my $allowedReferers = '^http[s]?\\:\\/\\/yoursite\\.tld\\/directory\\/page\\.html\\$'; # Regular expressions for text that is not allowed in any fields my %disallowed_text = ( "\\<[ \\r\\n\\t]*[Aa][ \\r\\n\\t]","You appear to be trying to include HTML formatted links. Links should not be formatted like this.", "\\[[ \\r\\n\\t]*[Uu][Rr][Ll][ \\r\\n\\t]*\\=","You appear to be trying to include message board formatted links. Links should not be formatted like this.", ); # Whether or not users are required to preview # their message before sending. # Set to 0 to disable, 1 to enable. my $require_preview = 1; # The character set for the web site. my $charset = 'ISO-8859-1'; # Command line program used to send email # '/usr/lib/sendmail -i -t' almost always works fine my $sendmail = '/usr/lib/sendmail -i -t'; # Whether or not to include javascript that checks the form # before it is submitted. # This is generally good, but it increases the page size, increases the # complexity of the page, and could alert hackers to the # regular expressions you are using for verification. # Set to 0 to disable, 1 to enable. my $use_client_side_verification = 1; # This should be either 'POST' or 'GET' my $submit_method = 'POST'; # Placed next to form elements that must be filled in my $required_marker = '*'; my $required_marker_note = "

$required_marker denotes a required field.

"; # Style rules for the input page. my $input_page_css = ''; # Style rules for thank you page my $sent_page_css = ''; # Link to favicon, placed in the head after the JavaScript my $icon_link=''; # Form copyright header placed in the head after the JavaScript my $copyright_link = ''; # Redirect to this url after the message has been sent # By default there is no redirect. The url must # be fully qualified (must start with http://) # Example: my $redirect_url_sent = "http://example.com/"; my $redirect_url_sent = ""; # Show the sent confirmation for this many seconds before redirecting # after the message has been sent if the redirect_url_sent has been defined. # If zero is specified, the message sent confirmation will not # be shown at all (you can redirect to your own) my $redirect_delay_sent = 15; #===================================================================== # You need to know Perl to and have a strong stomach to # modify much of anything below this line my(%SubmittedData, $mail_message, %AliasesMap, @AliasesOrdered, %FieldMap, @Field_Order, $template_error); &loadTemplate(); &parseInput(); &createMaps(); &sanityCheck(); &composeEmail(); &previewMessage(); &sendEmail(); &sentPage(); sub initConstants { # initialize the path to something safe so we can later call sendmail $ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin'; if (&safeHeader($ENV{'PATH_INFO'}) eq '/contactformicon.png'){ &contactformicon(); } # denotes that no description is desired. $NO_DESCRIPTION = "-"; # Version number of this software. $version = "1.3.8"; # Reqular expression building blocks $LETTER = "[a-zA-Z]"; $DIGIT = "[0-9]"; $DOSEOL = "(?:[\r][\n])"; $EOL = "(?:[\r\n]|$DOSEOL)"; $LETTER_DIGIT = "[0-9a-zA-Z]"; $LETTER_DIGIT_HYPHEN = "(?:[0-9a-zA-Z-])"; $HEX_DIGIT = "(?:[0-9a-fA-F])"; $QUOTEDSTRING = "(?:[\\\"](?:[^\\\"]|(?:[\\][\\\"]))*[\\\"])"; $ATOM = "(?:[\\!\\#-\\\\\\'\\*\\+\\-\\/-9\\=\\?A-Z\\^-\\~]+)"; $SUBDOMAIN = "(?:" . $LETTER_DIGIT . "(?:" . $LETTER_DIGIT_HYPHEN . "*" . $LETTER_DIGIT . ")?)"; $WORD = "(?:" . $ATOM . "|" . $QUOTEDSTRING . ")"; $DOMAIN = "(?:" . $SUBDOMAIN . "(?:[\\.]" . $SUBDOMAIN . ")+)"; $LOCALPART = "(?:" . $WORD . "(?:[\\.]" . $WORD . ")*)"; $EMAIL = "(?:" . $LOCALPART . "[\\@]" . $DOMAIN . ")"; $PHONE_DIGIT = "[\\.\\-\\(\\)\\+\\ Xx]*"; $PHONE = "(?:(?:" . $PHONE_DIGIT . $DIGIT . "){10,20})"; $ZIPCODE = "(?:" . $DIGIT . "{5}(?:[\\-]" . $DIGIT . "{4})?)"; $PRICE = "(?:" . $DIGIT . "+(?:[\\.]" . $DIGIT . "{2})?)|(?:[\\.]" . $DIGIT . "{2})"; $FLOAT = "(?:" . $DIGIT . "+(?:[\\.]" . $DIGIT . "*)?)|(?:[\\.]" . $DIGIT . "+)"; $INTEGER = "(?:" . $DIGIT . "+)"; # Some recommended regular expressions $SOMETHING = ".+"; $ANYTHING = ".*"; $ONE_LINE_REQUIRED = "^(?:(?:[^\\n\\r])+)\$"; $ONE_LINE_OPTIONAL = "^(?:(?:[^\\n\\r])*)\$"; $ZIPCODE_REQUIRED = "^" . $ZIPCODE . "\$"; $ZIPCODE_OPTIONAL = "^(?:" . $ZIPCODE . "?)\$"; $PHONE_REQUIRED = "^" . $PHONE . "\$"; $PHONE_OPTIONAL = "^(?:" . $PHONE . "?)\$"; $EMAIL_REQUIRED = "^" . $EMAIL . "\$"; $EMAIL_OPTIONAL = "^(?:" . $EMAIL . "?)\$"; $PRICE_REQUIRED = "^" . $PRICE . "\$"; $PRICE_OPTIONAL = "^(?:" . $PRICE . "?)\$"; $FLOAT_REQUIRED = "^" . $FLOAT . "\$"; $FLOAT_OPTIONAL = "^(?:" . $FLOAT . "?)\$"; $INTEGER_REQUIRED = "^" . $INTEGER . "\$"; $INTEGER_OPTIONAL = "^(?:" . $INTEGER . "?)\$"; } sub loadTemplate(){ $template_error = ""; if ($page_template_file ne ""){ if (!open(TEMPLATE, "<$page_template_file")){ $template_error = '
The template file could not be opened.
\n'; return; } $page_template = join("",