#!/usr/bin/perl $version = '1.3.2'; ############################################################################## # # # FormMail16-SpamTrap (fm16st) Version 1.3.2 # # Created 2003-01-11 Last Modified 2004-05-15 # # by Wolfgang Ellsaesser w dot ellsaesser at gmx dot de # # Idea: Norbert Huettisch in de.admin.net-abuse.mail # # # # The newest version can be found at # # This script bases on FormMail 1.6 by Matt Wright (see below). # # # ############################################################################## # # # ========================================================================== # # ###### This script is NOT a real FormMail program ###### # # ###### it shall prevent spammers from sending spam ###### # # ###### BTW, sorry for my bad English :-) ###### # # ========================================================================== # # # # Es handelt sich um eine Art "Schwarzes Loch", das zwar alle Formulare an- # # nimmt, aber nichts weiterschickt. Spammer, die den Bug von alten FormMail- # # skripten ausnutzen wollen, sollen damit ins Leere laufen. # # # # Die E-Mail-Adressen von Spammern, die dieses Skript auf die Sicherheits- # # lücke testen, können in eine Datei geschrieben werden und z.B. auf Remove- # # Lists eingetragen werden, für SugarPlum usw. # # Außerdem können alle Zugriffe zusätzlich zur access.log geloggt werden. # # # ############################################################################## # Installation: # # - read the documentation: # # http://www.almnet.de/fm16st/ :) (this file is in German) # # - change variables below (maybe you have to change the first line, too)# # - rename or copy this fm16st.pl to formmail.pl, FormMail.pl, # # formmail.cgi, ... # # If you copy it to multiple filenames, it can be easier for bots to # # guess the name of the script. # # - upload the script(s) to your server (e.g. in /cgi-bin/) # # - chmod them to 755 # ############################################################################## # FormMail Version 1.6 # # Copyright 1995-1997 Matt Wright mattw@scriptarchive.com # # Created 06/09/95 Last Modified 05/02/97 # # Matt's Script Archive, Inc.: http://www.scriptarchive.com/ # ############################################################################## # COPYRIGHT NOTICE # # Copyright 1995-1997 Matthew M. Wright All Rights Reserved. # # # # FormMail may be used and modified free of charge by anyone so long as this # # copyright notice and the comments above remain intact. By using this # # code you agree to indemnify Matthew M. Wright from any liability that # # might arise from its use. # # # # Selling the code for this program without prior written consent is # # expressly forbidden. In other words, please ask first before you try and # # make money off of my program. # # # # Obtain permission before redistributing this software over the Internet or # # in any other medium. In all cases copyright and header must remain intact # ############################################################################## ############################################################################## # # # +++ CONFIGURATION +++ # # # # You have to change the lines below before you can use this script. # # # $write_log = 1; # | = 0 -> Don't write logfile # # | = 1 -> Write logfile # # | [default: $write_log=1] # # ---------------------------------------------------------------------- # # # $logfile = '/(your path here)/trap.log'; # | Enter here the (absolute) path to your fm16st-logfile # # | (NOT the (Apache-)access.log!) # # | Create this file by yourself and make sure that the file may be # # | modified by this skript (chmod) # # | You don't have to change this if $write_log is 0. # # ---------------------------------------------------------------------- # # # $notify_by_email = 0; # | Set this to 1 if you want to be notified by email when someone # # | runs this script (you'll have also to change $notify_to below). # # | Warning: You may get tons of E-Mail if your fm16st-script will be # # | used by spammers # # | [default: $notify_by_email=0] # # ---------------------------------------------------------------------- # # # $mailprog = '/(path)/sendmail -i -t'; # | Enter here the absolute path to your sendmail program. You don't # # | have to change this, if $notify_by_email is set to 0. # # | Do not remove the -i and the -t unless you are know exactly what # # | you are doing. # # ---------------------------------------------------------------------- # # # $notify_to = 'Your Name '; # | If $notify_by_email above is set to 1, you have to enter your # # | email address here to receive your notification mail. # # | It is really important to enter your own valid email address! # # ---------------------------------------------------------------------- # # # $notify_from = 'fm16st '; # | If $notify_by_email above is set to 1, you have to enter a email # # | address which fm16st can use as sender address in the notification. # # | This should also be a valid email address that belongs to you. It # # | can be the same address as in $notify_to. # # ---------------------------------------------------------------------- # # # $sleep_time = 1; # | If you want fm16st to wait a little while sending the HTML-result # # | (to prevent server overload or to slow down a spammer) set it to the # # | amount of time fm16st shall wait. # # | If you don't want to pause fm16st, set $sleep_time to 0 # # | [default: $sleep_time=1] # # ---------------------------------------------------------------------- # # # # +++ END OF CONFIGURATION +++ # # # # You don't need to change the code below. You may, if you want to :-) # # To change the output of the logfile, you have to change one line in # # the sub write_logfile. # # # ############################################################################## # Retrieve Date &get_date; # Parse Form Contents &parse_form; # Write data to Logfile (if $write_log) &write_logfile; # send information to script owner (if $notify_by_email) ¬ify_email; # Return HTML Page or Redirect User &return_html; ############################################################################## sub get_date { # Define arrays for the day of the week and month of the year. # @days = ('Sunday','Monday','Tuesday','Wednesday', 'Thursday','Friday','Saturday'); @months = ('January','February','March','April','May','June','July', 'August','September','October','November','December'); # Get the current time and format the hour, minutes and seconds. Add # # 1900 to the year to get the full 4 digit year. # ($sec,$min,$hour,$mday,$mon,$year,$wday) = (localtime(time))[0,1,2,3,4,5,6]; $time = sprintf("%02d:%02d:%02d",$hour,$min,$sec); $year += 1900; # Format the date. # $date = "$days[$wday], $months[$mon] $mday, $year at $time"; } #### END &get_date #### ############################################################################## sub parse_form { # Define the configuration associative array. # %Config = ('recipient','', 'subject','', 'email','', 'realname','', 'redirect','', 'bgcolor','', 'background','', 'link_color','', 'vlink_color','', 'text_color','', 'alink_color','', 'title','', 'sort','', 'print_config','', 'required','', 'env_report','', 'return_link_title','', 'return_link_url','', 'print_blank_fields','', 'missing_fields_redirect',''); # Determine the form's REQUEST_METHOD (GET or POST) and split the form # # fields up into their name-value pairs. If the REQUEST_METHOD was # # not GET or POST, send an error. # if ($ENV{'REQUEST_METHOD'} eq 'GET') { # Split the name-value pairs @pairs = split(/&/, $ENV{'QUERY_STRING'}); } elsif ($ENV{'REQUEST_METHOD'} eq 'POST') { # Get the input read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); # Split the name-value pairs @pairs = split(/&/, $buffer); } else { &error('request_method'); } # For each name-value pair: # foreach $pair (@pairs) { # Split the pair up into individual variables. # local($name, $value) = split(/=/, $pair); # Decode the form encoding on the name and value variables. # $name =~ tr/+/ /; $name =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # If they try to include server side includes, erase them, so they # aren't a security risk if the html gets returned. Another # security hole plugged up. $value =~ s///g; # If the field name has been specified in the %Config array, it will # # return a 1 for defined($Config{$name}}) and we should associate # # this value with the appropriate configuration variable. If this # # is not a configuration form field, put it into the associative # # array %Form, appending the value with a ', ' if there is already a # # value present. We also save the order of the form fields in the # # @Field_Order array so we can use this order for the generic sort. # if (defined($Config{$name})) { $Config{$name} = $value; } else { if ($Form{$name} && $value) { $Form{$name} = "$Form{$name}, $value"; } elsif ($value) { push(@Field_Order,$name); $Form{$name} = $value; } } } # The next six lines remove any extra spaces or new lines from the # # configuration variables, which may have been caused if your editor # # wraps lines after a certain length or if you used spaces between field # # names or environment variables. # $Config{'required'} =~ s/(\s+|\n)?,(\s+|\n)?/,/g; $Config{'required'} =~ s/(\s+)?\n+(\s+)?//g; $Config{'env_report'} =~ s/(\s+|\n)?,(\s+|\n)?/,/g; $Config{'env_report'} =~ s/(\s+)?\n+(\s+)?//g; $Config{'print_config'} =~ s/(\s+|\n)?,(\s+|\n)?/,/g; $Config{'print_config'} =~ s/(\s+)?\n+(\s+)?//g; } #### END &parse_form #### ############################################################################## sub write_logfile { # Write data to logfile if ($write_log) { open(LOGF, ">>$logfile") || die "I can't create that file\n"; # change the below line to change logfile format and infos to be logged # the following sample logs all data. Normally, you do not need HTTP_REFERER or HTTP_USER_AGENT. # print LOGF join("\t",scalar localtime,$ENV{'REMOTE_HOST'},$ENV{'REMOTE_ADDR'},$ENV{'HTTP_REFERER'},$ENV{'HTTP_USER_AGENT'},$Config{'email'},$Config{'recipient'},$Config{'subject'},$Config{'message'},"\n"); print LOGF join("\t",scalar localtime,$ENV{'REMOTE_HOST'},$ENV{'REMOTE_ADDR'},$Config{'email'},$Config{'recipient'},$Config{'subject'},$Config{'message'},"\n"); close(LOGF); } } #### END &write_logfile #### ############################################################################## sub notify_email { # Send information to skriptowner if ($notify_by_email) { open(MAIL,"|$mailprog") || print STDERR "fm16st: SendMail could not be opened!\n"; print MAIL "To: $notify_to\n"; print MAIL "From: $notify_from\n"; print MAIL "Subject: [fm16st] message from $ENV{'SCRIPT_NAME'}\n"; print MAIL "Comments: If you receive this mail in error, contact the sender or $ENV{'SERVER_ADMIN'}.\n"; print MAIL "Precedence: bulk\n"; print MAIL "Priority: Low\n"; print MAIL "X-Mailer: fm16st $version \n"; print MAIL "X-Priority: 4 (Low)\n"; print MAIL "\n"; # end message header print MAIL "Hi,\nyour fm16st-script just has been run:\n\n"; print MAIL "\n- remote host: $ENV{'REMOTE_HOST'} ($ENV{'REMOTE_ADDR'})\n"; print MAIL "\n- sender email: $Config{'email'}\n"; print MAIL "\n- recipient: $Config{'recipient'}\n"; print MAIL "\n -subject: $Config{'subject'}\n"; print MAIL "\n- message: $Config{'message'}\n"; print MAIL "\n-- \n"; print MAIL "fm16st $version \n\n"; close (MAIL); } } #### END ¬ifybyemail #### ############################################################################## sub return_html { # Local variables used in this subroutine initialized. # local($sort_order,$sorted_field); # If redirect option is used, print the redirectional location header. # if ($Config{'redirect'}) { print "Location: $Config{'redirect'}\n\n"; } # Otherwise, begin printing the response page. # else { # Print HTTP header and opening HTML tags. # print "Content-type: text/html\n\n"; print "\n \n"; # Print out title of page # if ($Config{'title'}) { print " $Config{'title'}\n" } else { print " Thank You\n" } print " \n \n
\n"; # Print custom or generic title. # if ($Config{'title'}) { print "

$Config{'title'}

\n" } else { print "

Thank You For Filling Out This Form

\n" } print "
\n"; print "Below is what you submitted to $Config{'recipient'} on "; print "$date


\n"; # Sort alphabetically if specified: # if ($Config{'sort'} eq 'alphabetic') { foreach $field (sort keys %Form) { # If the field has a value or the print blank fields option # # is turned on, print out the form field and value. # if ($Config{'print_blank_fields'} || $Form{$field}) { print "$field: $Form{$field}

\n"; } } } # If a sort order is specified, sort the form fields based on that. # elsif ($Config{'sort'} =~ /^order:.*,.*/) { # Set the temporary $sort_order variable to the sorting order, # # remove extraneous line breaks and spaces, remove the order: # # directive and split the sort fields into an array. # $sort_order = $Config{'sort'}; $sort_order =~ s/(\s+|\n)?,(\s+|\n)?/,/g; $sort_order =~ s/(\s+)?\n+(\s+)?//g; $sort_order =~ s/order://; @sorted_fields = split(/,/, $sort_order); # For each sorted field, if it has a value or the print blank # # fields option is turned on print the form field and value. # foreach $sorted_field (@sorted_fields) { if ($Config{'print_blank_fields'} || $Form{$sorted_field}) { print "$sorted_field: $Form{$sorted_field}

\n"; } } } # Otherwise, default to the order in which the fields were sent. # else { # For each form field, if it has a value or the print blank # # fields option is turned on print the form field and value. # foreach $field (@Field_Order) { if ($Config{'print_blank_fields'} || $Form{$field}) { print "$field: $Form{$field}

\n"; } } } print "


\n"; # Check for a Return Link and print one if found. # if ($Config{'return_link_url'} && $Config{'return_link_title'}) { print "

\n"; } sleep($sleep_time); # Print the page footer. # print <<"(END HTML FOOTER)";

FormMail V1.6 © 1995 -1997 Matt Wright
A Free Product of Matt's Script Archive, Inc.
(END HTML FOOTER) } } #### END &return_html #### ############################################################################## sub body_attributes { # Check for Background Color if ($Config{'bgcolor'}) { print " bgcolor=\"$Config{'bgcolor'}\"" } # Check for Background Image if ($Config{'background'}) { print " background=\"$Config{'background'}\"" } # Check for Link Color if ($Config{'link_color'}) { print " link=\"$Config{'link_color'}\"" } # Check for Visited Link Color if ($Config{'vlink_color'}) { print " vlink=\"$Config{'vlink_color'}\"" } # Check for Active Link Color if ($Config{'alink_color'}) { print " alink=\"$Config{'alink_color'}\"" } # Check for Body Text Color if ($Config{'text_color'}) { print " text=\"$Config{'text_color'}\"" } } #### END &body_attributes #### ############################################################################## sub error { # Localize variables and assign subroutine input. # local($error) = @_; if ($error eq 'request_method') { print <<"(END ERROR HTML)"; Content-type: text/html Error: Request Method
Error: Request Method
The Request Method of the Form you submitted did not match either GET or POST. Please check the form and make sure the method= statement is in upper case and matches GET or POST.

FormMail V1.6 © 1995 - 1997 Matt Wright
A Free Product of Matt's Script Archive, Inc.
(END ERROR HTML) } exit; } #### END &error ####