#!/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-2007 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, $BLANK); &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 = ( 'InsightCentral.net Editors','insightcentral@insightcentral.net', 'Community Support','team@insightcentral.net', 'Site Administrator','benjamin@insightcentral.net', #'administrator',&safeHeader($ENV{'SERVER_ADMIN'}), # The following aliases are commented out examples, remove the leading # sign to use them #'webmaster','webmaster@yoursite.tld', #'postmaster','postmaster@yoursite.tld', #'two people','webmaster@yoursite.tld,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 = 'InsightCentral.net - Contact Us'; my $sent_page_title = 'InsightCentral.net - Message Sent'; # Extra text (may be html formatted) that will be placed on # the page before the the form my $input_page_text = '

If you wish to contribute material to InsightCentral.net, ask a question not already answered on this site, or contact us for any other reason, just write your message below and a member of the InsightCentral.net team will get back to you as soon as possible.

Please note that this web site has been created by and for people interested in this unique car, and is not connected with the Honda corporation in any way. For more information on us and this site, see About InsightCentral.net.

'; my $sent_page_text = '

Thank you for your message.

'; 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 the page_template # variable above 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 = ""; # FormFields is the list of questions the user is expected # to answer. The questions will appear in the same order as # they are ordered here. You may safely remove the subject, # email, name, and message from the form. The to field should # not be removed. The name of each field should contain only # letters, numbers, and underscore. Spaces or symbols should # not be used. Each has several attributes that control the # display of the question to the user. # # "required" # a regular expression that describes what a valid submission looks # like. By default, any entry at all is allowed. # 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, $BLANK # # "error" # A user friendly error message for each required # element that a user gets wrong. # # "type" # Type of input in web pages for each field. # Currently supported are 'text', 'hidden', 'radio', # 'select', and 'textarea' # If there is no type, 'text' is assumed. # Setting the type for the to field will have no effect since # the to field is handled specially. # # "description" # Description to appear next to entry forms and in # the email or $NO_DESCRIPTION for none # If no description is given the field name followed # by a colon is used # # "selected" # For fields of type "select", or "radio" indicates # the default selection # # "special" # Any special purpose for which the field is used. # Must be one of "to", "from", "name", "subject", # "regarding", or "referrer" # my @FormFields = ( 'to', { 'required' => $ONE_LINE_REQUIRED, 'error' => 'You must specify a recipient.', 'description' => 'Please select a recipient:', # Alias of the address put in the "To:" field of the email. 'special' => 'to', }, 'email', { 'required' => $EMAIL_REQUIRED, 'error' => 'The email address you entered does not appear to be valid.', 'type' => 'text', 'description' => 'Your email address:', # Put in the "From:" field of the email as the email of the person it is from 'special' => 'from', }, 'confirm', { # This is a field designed to thwart automated submissions # This field is not visible to the user. # Bots may attempt to fill it in which will prevent submission. 'required' => $BLANK, 'error' => 'This item should not be enterred', 'type' => 'trap', 'description' => 'Your homepage:', }, 'name', { 'required' => $ONE_LINE_REQUIRED, 'error' => 'You must enter your name.', 'type' => 'text', 'description' => 'Your full name:', # Put in the "From:" field of the email as the name of the person it is from 'special' => 'name', }, 'subject', { 'required' => $ONE_LINE_REQUIRED, 'error' => 'You must enter a subject.', 'type' => 'text', 'description' => 'The subject of your message:', # Put in the "Subject:" field of the email. 'special' => 'subject', }, 'message', { 'required' => $SOMETHING, 'error' => 'You must enter a message.', 'type' => 'textarea', 'description' => $NO_DESCRIPTION, }, 'regarding', { 'required' => $ANYTHING, 'error' => '', 'type' => 'hidden', 'description' => $NO_DESCRIPTION, # Put in the "Subject:" field of the email in parenthesis. 'special' => 'regarding', }, 'referrer', { 'required' => $ANYTHING, 'error' => '', 'type' => 'hidden', 'description' => $NO_DESCRIPTION, # The original referring url. 'special' => 'referrer', }, # The following fields are disabled examples, remove the 'enabled' => 0 line to use them 'phone', { 'required' => $PHONE_OPTIONAL, 'error' => 'The phone number you entered does not appear to be valid.', 'type' => 'text', 'description' => 'Phone Number:', 'enabled' => 0, }, 'fax', { 'required' => $PHONE_OPTIONAL, 'error' => 'The fax number you entered does not appear to be valid.', 'type' => 'text', 'description' => 'Fax Number:', 'enabled' => 0, }, 'address1', { 'required' => $ONE_LINE_OPTIONAL, 'error' => 'Please enter your address.', 'type' => 'text', 'description' => 'Address:', 'enabled' => 0, }, 'address2', { 'required' => $ONE_LINE_OPTIONAL, 'error' => 'Please enter your address.', 'type' => 'text', 'description' => $NO_DESCRIPTION, 'enabled' => 0, }, 'city', { 'required' => '^(?:[a-zA-Z ]*)$', 'error' => 'Your city does not appear to be valid.', 'type' => 'text', 'description' => 'City:', 'enabled' => 0, }, 'state', { 'required' => '^(?: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)$', 'error' => 'Please choose your state.', 'type' => 'select', 'description' => 'State:', 'enabled' => 0, }, 'zip', { 'required' => $ZIPCODE_OPTIONAL, 'error' => 'Your zipcode does not appear to be valid.', 'type' => 'text', 'description' => 'Zipcode:', 'enabled' => 0, }, 'most_basic_question', { # uses the default values for required, error, type, and description 'enabled' => 0, }, 'color', { # A required select drop down 'type' => 'select', 'required' => '^(?:Red|Orange|Yellow|Green|Blue|Purple|Black|White)$', 'error' => 'Please choose a color.', 'description' => 'Choose a color:', 'enabled' => 0, }, 'vegetable', { # An optional select drop down 'type' => 'select', 'required' => '^(?:|Asparagus|Squash|Potato|Carrot|Broccoli)$', 'error' => 'Please enter a valid vegetable.', 'description' => 'To help us prevent unwanted emails, please select the vegetable that begins with the letter C:', 'enabled' => 0, }, 'letter', { # A select drop down with a pre-filled option 'type' => 'select', 'required' => '^(?:A|B|C|D)$', 'error' => 'Please choose on of the four letters.', 'description' => 'Choose a letter (C is selected by default):', 'selected' => 'C', 'enabled' => 0, }, 'yes_no', { # required radio buttons 'type' => 'radio', 'required' => '^(?:yes|no)$', 'error' => 'Please answer the yes/no question', 'description' => 'Yes or no:', 'enabled' => 0, }, 'true_false', { # radio buttons with a prefilled option 'type' => 'radio', 'required' => '^(?:true|false)$', 'error' => 'Please answer the true/false question', 'description' => 'True or false (false is selected by default):', 'selected' => 'false', 'enabled' => 0, }, 'vegetable2', { # optional radio buttons 'type' => 'radio', 'required' => '^(?:|Lettuce|Tomato|Brussel Sprouts)$', 'error' => 'Please choose a valid vegetable.', 'description' => 'Which (if any) is your favorite vegetable:', 'enabled' => 0, }, 'about', { # prefilled 'type' => 'text', 'required' => $ANYTHING, 'error' => 'Please enter what this message is about.', 'description' => 'What is this message about:', 'default' => 'Email', 'enabled' => 0, }, ); # The name of the field for 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]?\\:\\/\\/((insightcentral\\.net)|(www\\.insightcentral\\.net))\\/'; # 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. We do not accept any links via this contact form.", "\\[[ \\r\\n\\t]*[Uu][Rr][Ll][ \\r\\n\\t]*\\=","You appear to be trying to include message board formatted links. This form does not accept links.", ); # Whether or not users are required to preview # their message before sending. # 0 -- preview disabled (allows users to send mail the fastest) # 1 -- preview required (best for spam prevention) # 2 -- preview available, but not required (most choice for users) 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. # to put question and answer on the same line use: # .cf_userentry, .cf_radioselection { display:inline; margin-left:0.25cm; } 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 = "http://www.insightcentral.net/thankyou.html"; # 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 thank you) my $redirect_delay_sent = 0; #===================================================================== # 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, $field_name_to, $field_name_from_email, $field_name_from_name, $field_name_subject, $field_name_regarding, $field_name_referrer); &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 = "2.01.01"; # 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 . "?)\$"; $BLANK = "^\$"; } 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("",