#!/usr/local/bin/perl
#
# Master Form V4
# Version 4.7b
#
# Version 4.0 based on Master Form version 1.0 (completed May 8, 2000)
# through version 2.8 (completed March 9, 2003)
# and Master Form V3 version 3.0 (completed May 8, 2003)
# through version 3.5m (completed February 1, 2005)
# Version 4.0 completed February 4, 2005
# Version 4.6 completed August 19, 2010
# Version 4.7 completed February 14, 2017 (removed plug-in functionality)
# Version 4.7a completed February 17, 2017 (CGI.pm single-value workaround)
# Version 4.7b completed March 19, 2017 (allow "+" character in name part of email address)
#
# File MasterFormV4.cgi (file may be renamed if desired)
# The form processor.
#
# Copyright 2000,2001 by William Bontrager.
# Copyright 2002-2010 by Bontrager Connection, LLC
# Copyright 2012,2017 by Will Bontrager Software LLC
#
# Programmer: Will Bontrager
# Website: http://www.willmaster.com/
#
# This custom version downloaded
# from: Willmaster.com
# for: websites4contractors.com
# by: 127.0.0.1
# at: 1627995706 -- Tuesday, August 3, 2021 at 13:01:46 GMT.
#
###########################################################
use strict; # May be commented out after testing.
use MasterFormV4Common;
sub Exit { ErrorHTML @_ if @_; goto BOTTOM; }
sub GetDateTime
{
my @Month = split /\t/,$G{MonthList};
my @Mon = split /\t/,$G{MonList};
my @W = split /\t/,$G{WeekdayList};
$Mine{SYSTEMTIME} = $Transfer{Time};
my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime($Mine{SYSTEMTIME});
$year += 1900;
$Mine{YEAR} = $year;
$year = substr($year,-2);
$Mine{YEAR2} = $year;
$Mine{SHORTMONTH} = $Mon[$month];
$Mine{LONGMONTH} = $Month[$month];
$month++;
$Mine{MONTH} = $month;
my $s = $month; $s = "0$s" if length($month) < 2;
$Mine{MONTH2} = $s;
$Mine{DAY} = $mday;
$s = $mday; $s = "0$s" if length($mday) < 2;
$Mine{DAY2} = $s;
$Mine{WEEKDAY} = $W[$wday];
$Mine{HOUR} = $hour;
$s = $hour; $s = "0$s" if length($hour) < 2;
$Mine{HOUR2} = $s;
$Mine{AMPM} = 'AM';
if($hour >= 12) { $Mine{AMPM} = 'PM'; }
if($hour > 12) { $hour -= 12; }
$Mine{AMPMHOUR} = $hour;
$s = $hour; $s = "0$s" if length($hour) < 2;
$Mine{AMPMHOUR2} = $s;
$Mine{MINUTE} = $min;
$s = $min; $s = "0$s" if length($min) < 2;
$Mine{MINUTE2} = $s;
$Mine{SECOND} = $sec;
$s = $sec; $s = "0$s" if length($sec) < 2;
$Mine{SECOND2} = $s;
($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = gmtime;
$sec = $sec < 10 ? "0$sec" : "$sec";
$min = $min < 10 ? "0$min" : "$min";
$hour = $hour < 10 ? "0$hour" : "$hour";
$year += 1900;
my @weekday = qw(Sun Mon Tue Wed Thu Fri Sat);
my @month = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
$Mine{HEADER_TIME_STAMP} = "$weekday[$wday], $mday $month[$month] $year $hour:$min:$sec -0000";
} # sub GetDateTime
sub FlowTo
{
my $page = '';
($In{flowto},undef) =~ split /\t/,$In{flowto},2;
FixNextPage(\$In{flowto},'name="flowto" value');
RetrievePage($In{flowto},'Form field name="flowto"','',\$page);
$page =~ s/
Hidden field name="filetemplate" is used to specify the template that
Master Form V4 shall use when updating the database file. And name="dbfile" is
used to specify the database file itself.
(If both name="filetemplate" and name="dbfile" were to contain the same value,
Master Form V4 would use the database file as the template and append the result
to the bottom of the template file, thinking it's the database file
which would double the size of the template/database file every time Master Form V4 was used.
Please assign hidden field name="filetemplate" a value different
than the value assigned to hidden field name="dbfile"
EEEE
$we = <
When you'll have Master Form V4 update a database, two hidden form fields are required,
name="filetemplate" and name="dbfile"
name="filetemplate"
This specifies the URL or server location of the template Master Form V4 will use when creating your database
and/or appending a record thereto. The template is used as a guide to format the data
to be stored in the database.
name="dbfile"
This specifies the server location of the database itself, the file that will be
updated after the data has been formatted according to the template.
EEEE
$we = <
No field name="redirect" or name="flowto" was found,
and the browser didn't provide referring URL information.
Note:
Master Form V4 should be accessed only via a form submission.
EEEE
$we = <
The number of file field template files specified in hidden form field name="filetemplate" and the number of database file names specified in hidden form field name="dbfile" do not match. The same number of template files as database files must be specified. Otherwise, I won't know which template file applies to which database file.
EEEE
$we = <
When a URL is used to specify the location of an email template, it must be a URL to a page on the $ENV{SERVER_NAME} domain.
$In{emailtemplate} does not qualify.
EEEE
$we = <
' . join('
',@message) . '
';
my $wmessage = join "\n ",@message;
$e = <
While handling uploaded files for storing on the server, Master Form V4 thought you might want to know about the following:
$message
$we = < $Transfer{AntiSubNameLen} and length($field) > $Transfer{AntiSubValueLen};
last if $banned;
}
}
next unless $banned;
$banned = '' if $word =~ m!http://! and $field =~ /^FormLocation|errorpage|hidden|uploadedfilesaveinfo|flowto|redirect|emailtemplate|filetemplate|submitget|submitpost$/;
next unless $banned;
$banned = '' if $field =~ /^l/ and length($field) > $Transfer{AntiSubNameLen} and length($field) > $Transfer{AntiSubValueLen};
next unless $banned;
$banned = qq~"$word" in form field containing "$In{$field}"~;
last;
}
return unless $banned;
$In{exitnow} = 'yes';
return unless $G{WebPageToDisplayUponBanned} =~ /\w/;
$In{BANNED} = $banned;
my $page = '';
RetrievePage($G{WebPageToDisplayUponBanned},'"Banned word/phrase found" page','',\$page);
FixNextPage \$page,'web' if $page =~ /\[\-?\[/;
ContentHeader;
print "\n$page";
} # sub CheckForBannedOrBlocked
sub InformationGetPost
{
my $content = '';
my $failed = q~This operation failed. The balance of the form submission procedure was not interrupted by this failure.~;
my $failed2 = q~The content (if any) received is:~;
my $line = '=' x 50;
if($In{submitpost} =~ /\w/)
{
for my $thing (split /\t/,$In{submitpost})
{
$thing =~ s/^[,\s]*(.*?)[,\s]*$/$1/;
my @fields = split /[,\s]+/,$thing;
my $url = shift @fields;
my %in = ();
for my $fld (@fields)
{
my $fd = $fld;
($fd,$fld) = split /=/,$fld,2 if $fld =~ /=/;
$in{$fd} = $In{$fld};
}
my ($success,$code) = PostPage $url,\%in,\$content;
unless($success)
{
my @message = (qq~Unable to deliver form information to $url with method POST. The status code is:~);
push @message,$code,$failed,$failed2,$content;
WebmasterNotice @message,'get-post';
}
}
}
if($In{submitget} =~ /\w/)
{
for my $thing (split /\t/,$In{submitget})
{
$thing =~ s/^[,\s]*(.*?)[,\s]*$/$1/;
my @fields = split /[,\s]+/,$thing;
my $url = shift @fields;
my @in = ();
for my $fld (@fields)
{
my $fd = $fld;
($fd,$fld) = split /=/,$fld,2 if $fld =~ /=/;
my $v = HEXize $In{$fld};
my $k = HEXize $fd;
push @in,"$k=$v";
}
$url .= '?' . join '&',@in;
my ($success,$code) = GetPage $url,\$content;
unless($success)
{
my @message = (qq~Unable to deliver form information to $url with method GET. The status code is:~);
push @message,$code,$failed,$failed2,$content;
WebmasterNotice @message,'get-post';
}
}
}
} # sub InformationGetPost
sub AutomaticSubmitProtectionMechanism
{
return unless $G{ASPMenabled} =~ /[yt1l]/i;
my @list = ();
for(keys %In) { push @list,$_ if $_ =~ /^l/ and length($_) > $Transfer{AntiSubNameLen} and length($In{$_}) > $Transfer{AntiSubValueLen}; }
return if @list and PassedASPMcheck \@list;
my $AutoSubmitEmail = 'An automatic submission may have been attempted.';
WebmasterNotice $AutoSubmitEmail,'isautosubmit';
if($G{ASPMfailMessage} =~ m!^https?://\S+$!i) { print "Location: $G{ASPMfailMessage}\n\n"; }
else { print "Content-type: text/html\n\n$G{ASPMfailMessage}"; }
Exit;
} # sub AutomaticSubmitProtectionMechanism
sub AddSecretHiddenFields
{
return unless $In{hidden} =~ /\w/;
my $page = '';
RetrievePage($In{hidden},'Form field name="hidden"','',\$page);
while($page =~ s/]+)>//si)
{
my $line = $1;
$line =~ s/(\w+=)/>$1/gs;
my %k = ();
for(split />/,$line)
{
s/^\s*//s;
s/^(\w+)=//;
my $kk = lc $1;
s/^["\s]*//s;
s/["\s]*$//s;
$k{$kk} = $_;
}
next unless $k{name};
my($k,$v) = ($k{name},$k{value});
if($In{$k}) { $In{$k} .= "\t$v"; }
else { $In{$k} = $v; }
}
} # sub AddSecretHiddenFields
sub SequentialNumbering
{
return unless $In{use_numbering_key} =~ /\w/;
$In{use_numbering_start} = '' unless $In{use_numbering_start};
$In{use_number} = RecordNumberSequenceAndReturnNextNumber $In{use_numbering_key},$In{use_numbering_start};
} # sub SequentialNumbering
sub CrossSiteScriptingSanitization
{
my %exception = ();
if(open Rexceptions,')
{
next unless $line =~ /\S/;
next unless index($line,'#');
$line =~ s/^\s*(.*?)\s*$/$1/s;
$exception{$line} = 1;
}
close Rexceptions;
}
for my $k ( keys %In )
{
next if $exception{$k};
$In{$k} =~ s/</g;
$In{$k} =~ s/>/>/g;
$In{$k} =~ s/'/'/g;
$In{$k} =~ s/"/"/g;
$In{$k} =~ s/`//g;
$In{$k} =~ s/\)/)/g;
$In{$k} =~ s/\(/(/g;
}
} # sub CrossSiteScriptingSanitization
sub GetWhitelistFileList
{
%FileWhitelist = ();
if(open Rwhitelist,')
{
next unless $line =~ /\S/;
next if index($line,'#') > -1;
$line =~ s/^\s*(.*?)\s*$/$1/s;
$FileWhitelist{$line} = 1;
}
close Rwhitelist;
}
} # sub GetWhitelistFileList
RecordFormLocation;
sub trail{$dom=$d;$v=$_[0];}
GetWhitelistFileList;
Exit("Unauthorized use by $ENV{HTTP_REFERER}") unless ParseFormData and trail(1);
my %inMail = %In;
CrossSiteScriptingSanitization;
Exit UpdateNoticeDelivery if $In{unac} and $In{unac} eq $G{UpdateNoticeAuthorizationCode};
Exit if $In{exitnow};
AddSecretHiddenFields;
CheckForBannedOrBlocked;
Exit if $In{exitnow};
WebmasterNotification(1) if $In{filetemplate} =~ /\w/ and $In{filetemplate} eq $In{dbfile};
WebmasterNotification(2) if ($In{filetemplate} =~ /\w/ and $In{dbfile} !~ /\w/) or ($In{filetemplate} !~ /\w/ and $In{dbfile} =~ /\w/);
{
my @e = SanitizeServerLocationValues $In{errorpage},'name="errorpage"';
delete $In{errorpage} if @e;
push @e,SanitizeServerLocationValues $In{uploadedfilesaveinfo},'name="uploadedfilesaveinfo"';
push @e,SanitizeServerLocationValues $In{flowto},'name="flowto"';
Exit @e if @e;
}
CheckRequiredFields;
CheckEmailFields;
GetDateTime;
for my $k (split /\; */,$ENV{HTTP_COOKIE})
{
my ($n,$v) = split(/\=/,$k,2);
$v =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
$Mine{$n} = $v;
}
$Mine{HTTP_USER_AGENT} = $ENV{HTTP_USER_AGENT};
$Mine{SELFDOMAIN} = $ENV{SERVER_NAME};
$Mine{REFERRER} = $ENV{HTTP_REFERER};
$Mine{IP} = $ENV{REMOTE_ADDR};
$Mine{ALLME} = $Mine{ME} = $0;
$Mine{ME} =~ s!^.*[\\/]!!;
for(keys %ENV) { $Mine{$_} = $ENV{$_} unless $Mine{$_}; }
AutomaticSubmitProtectionMechanism unless $In{exitnow};
$In{ControlPanelAlertAddress} = $G{DefaultEmailToAddy};
unless($In{exitnow})
{
SequentialNumbering;
my %localin = %In;
for( keys %inMail ) { $In{$_} = $inMail{$_}; }
%inMail = ();
SendTheEmail;
%In = %localin;
}
StoreUploadedFiles unless $In{exitnow};
UpdateDatabases unless $In{exitnow};
Exit if $In{exitnow};
InformationGetPost;
if($In{redirect} =~ /\w/)
{
$In{redirect} = (split(/\t/,$In{redirect},2))[0];
my $Tplace = $In{redirect};
FixNextPage(\$Tplace,'name="redirect" value');
$In{redirect} = $Tplace;
print "Location: $In{redirect}\n\n";
print qq~
If no redirect occurs,
click here.
~;
}
elsif($In{flowto} =~ /\w/) { FlowTo; }
elsif($Mine{REFERRER} =~ /\w/)
{
print "Location: $Mine{REFERRER}\n\n";
print qq~
If no redirect occurs,
click here.
~;
}
else { WebmasterNotification(3); }
BOTTOM:
exit;
# end of script