#!/usr/bin/perl -w use strict; use warnings; use CGI qw(:standard :cgi-lib); $CGI::POST_MAX=102400; $CGI::DISABLE_UPLOADS = 1; require Mail::Send; use Fcntl ':flock'; # import LOCK_* constants #################### GLOBAL SETUP ################################# # Parameter name manipulation, helps prevent some spam my $nameParam = 'fdsf43'; my $phoneParam = 'xf3f3'; my $floodTime = 120; # flood protection timeout in seconds my $floodTries = 1; # flood protection - number of requests that are allowed to be sent my $floodFile = 'flood.ip'; my $sendEmail = 0; # should we send request e-mail? my $emailAddress = 'callbackscript@example.com'; # to which address should we be sending requests? my $emailSubject = 'Call Request'; # what e-mail subject should we use? my $backButtonMessage = 'Please hit your browser\'s Back button and correct this.'; my $userHost = remote_host(); # store user's IP my $q = new CGI; printHTML(qq|Name field is required. $backButtonMessage|) if !defined($q->param($nameParam)) or $q->param($nameParam) eq 'Name'; printHTML(qq|Phone number field is required. $backButtonMessage|) if !defined($q->param($nameParam)) or $q->param($phoneParam) eq 'Phone number'; printHTML(qq|Name field may not be longer than 100 characters. $backButtonMessage|) if length($q->param($nameParam)) > 100; printHTML(qq|Phone number field may not be longer than 100 characters. $backButtonMessage|) if length($q->param($phoneParam)) > 100; my %userInfo = ( 'host' => remote_host(), 'name' => $q->param($nameParam), 'phone number' => $q->param($phoneParam), 'request time' => scalar (localtime(time))); if (checkFlood($userInfo{'host'})) { if (defined($q->param('ajax'))) { printHTTPHeaders(); print "FLOOD"; exit; } printHTML('You have already submitted your request. We will call you as soon as possible. Thank you.'); } if ($sendEmail) { sendMail(); } else {testScript(); } if (defined($q->param('ajax'))) { printHTTPHeaders(); print "OK"; exit; } printHTML('Your request has been submitted. We will call you as soon as possible. Thank you.'); sub testScript { printHTMLError ("Failed to open `test` file: $!") unless open TEST_FILE, ">", 'test'; print TEST_FILE <to($emailAddress); $msg->subject($emailSubject . " from $userInfo{'name'} [" . localtime() . "]"); my $fh = $msg->open('sendmail'); print $fh <close; # complete the message and send it } sub checkFlood { my $userHost = shift; my $noFlood = 0; my $yesFlood = 1; my $separator = ':sep:'; return $noFlood unless open FLOOD_FILE, "<", $floodFile; my $userFloodCount = 0; my @floodData = (); while() { chomp; my ($ip, $time) = split /\Q$separator\E/, $_, 2; push @floodData, {'ip' => $ip, 'time' => $time } unless (time() - $time) > $floodTime; $userFloodCount++ if $ip eq $userHost and (time() - $time) < $floodTime; } push @floodData, { 'ip' => $userHost, 'time' => time() } if $userFloodCount <= $floodTries; close FLOOD_FILE; return $noFlood unless open FLOOD_FILE, ">", $floodFile; flock(FLOOD_FILE, LOCK_EX); seek(FLOOD_FILE, 0, 2); foreach my $flooder(@floodData) { print FLOOD_FILE $flooder->{'ip'} . $separator . $flooder->{'time'} . $/; } flock(FLOOD_FILE, LOCK_UN); close FLOOD_FILE; return $yesFlood if $userFloodCount >= $floodTries; return $noFlood; } sub printHTMLError { my $message = shift; printHTTPHeaders(); print < Fatal Server Error

Fatal Server Error

A server error has occured ( $message ). Try again later. We apologize for the inconvenience.

END_HTML exit; } sub printHTML { my $message = shift; printHTTPHeaders(); print < Foo Bar Baz

SENT

END_HTML exit; } sub printHTTPHeaders { print "Content-type: text/html\n\n"; }