#!/usr/bin/perl
#
package Mail::SpamCannibal::PageIndex;
#
# cannibal.cgi or cannibal.plx
# link admin.cgi or admin.plx
#
# version 2.16, 11-16-08
#
# Copyright 2003 - 2008, Michael Robinton
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
use strict;
#use diagnostics;
use vars qw(%ftxt $timeout);
$timeout = 15; # 15 second timeout for internal UDP PTR lookup
use Mail::SpamCannibal; # just for version number
use IPTables::IPv4::DBTarpit; # just for version number
use Mail::SpamCannibal::IP2ccFlag;
use Mail::SpamCannibal::ScriptSupport qw(
doINCLUDE
lookupIP
validIP
valid127
is_GENERIC
);
use Net::DNS::Codes qw(:all);
use Net::DNS::ToolKit qw(
newhead
gethead
get_ns
inet_aton
inet_ntoa
ttlAlpha2Num
);
use Net::DNS::ToolKit::Utilities qw(
id
query
question
rlook_send
rlook_rcv
);
use Mail::SpamCannibal::BDBclient qw(
dataquery
retrieve
INADDR_NONE
);
#########################################################################
# Individual pages are put together by calling the html_cat routine. #
# See: Mail::SpamCannibal::WebService &html_cat #
#########################################################################
use Mail::SpamCannibal::WebService qw(
sendhtml
html_cat
cookie_date
get_query
make_jsPOP_win
);
use Mail::SpamCannibal::Session qw(
decode
sesswrap
);
my $CONFIG = doINCLUDE '../config/sc_web.conf';
die "could not load config file"
unless $CONFIG;
my $OverRide = 0; # override mod perl output
my ($admin,$sess,%extraheaders);
my $expire = $CONFIG->{expire} || 300; # default expiration 5 minutes
my $log_expire = $CONFIG->{log_expire} || 180; # default expiration 3 minutes
my %query = get_query();
# check for query from LaBrea client & convert if necessary
if ($query{query} && $query{query} =~ /(\d+\.\d+\.\d+\.\d+)/) {
$query{page} = 'lookup';
$query{lookup} = $1;
}
# return session on success, undef otherwise
#
sub is_cookie() {
return($ENV{HTTP_COOKIE} &&
$ENV{HTTP_COOKIE} =~ /SpamCannibal=([\w-]+\.[\w-]+\.\d+\.\d+\.[\w-]+)/)
? $1 : undef;
}
my $admses = 0;
my $user;
my $passexp = 0;
if ($ENV{SCRIPT_FILENAME} && $ENV{SCRIPT_FILENAME} =~ m|/admin\..+$|) {
$extraheaders{'Set-Cookie'} = 'SpamCannibal=on; path=/; expires='. cookie_date(1);
if (($admin = $CONFIG->{wrapper}) &&
-e $admin && -x $admin &&
do { # return true if good session instantiated
if ( $query{user} &&
($_ = sesswrap("$admin newtick $query{user}")) &&
$_ =~ /^OK\s+([\w-]+\.[\w-]+\.\d+\.\d+\.[\w-]+)/) {
$sess = $1;
$query{page} = 'passwd';
}
elsif ( defined $query{passwd} &&
($sess = is_cookie) &&
($_ = sesswrap("$admin login $sess $log_expire $query{passwd} $CONFIG->{maxretry}")) &&
($query{page} = '2realAH') &&
($_ =~ /^OK\s*([^\s]+)/ || ($_ =~ /^NOT OK\s*([^\s]+)/ && ($query{page} = 'passwd'))) &&
($user = $1)) {
1;
}
elsif ( ($sess = is_cookie) &&
($_ = sesswrap("$admin chksess $sess $expire")) &&
$_ =~ /^OK\s*([^\s]+)/ &&
($user = $1)) {
1;
}
else {
0;
}
}
) {
$extraheaders{'Set-Cookie'} = 'SpamCannibal='. $sess .
'; path=/; expires='. cookie_date(time + $expire);
$extraheaders{'Set-Cookie'} .= '; secure'
if $CONFIG->{secure};
$query{page} = 'ahome'
unless $query{page};
$admses = $expire - 60; # this is an admin session
$admses = 0 if $admses < 0;
$admses *= 1000; # session web page timeout
}
else {
$query{page} = 'login'
unless $query{page} eq '2realAH'; # reset to login indirectly if password expire
}
push @{$CONFIG->{static}}, @{$CONFIG->{admin}};
if ($CONFIG->{secure} && ! $ENV{SSL_SERVER_CN}) { # bail if not secure connection
$query{page} = 'sorry';
}
}
else {
$query{page} = 'home'
unless $query{page};
}
# %ftxt will contain a like hash of cached text and will already
# exist if there is a previous instantiation of this script
%ftxt = () unless %ftxt;
my $bgcolor = ($CONFIG->{bgcolor} && $CONFIG->{bgcolor} =~ /^#[0-9a-fA-F]{6}$/)
? $CONFIG->{bgcolor}
:'#ffffff';
$ftxt{bgcolor} = qq| bgcolor="$bgcolor" |;
$ftxt{versions} = q|
|;
my $html = '';
my $pagerror = '';
PageGen:
while (1) {
# for static pages, just issue them
my ($name,$nav);
if ($admin) { # use nav2 for admin
$nav = ($query{page} =~ /sorry|login|passwd/) # no nav bar for listed pages
? '' : 'nav2';
$ftxt{versions} .= make_jsPOP_win('passwd',300,200)
if $query{page} eq 'login';
} else {
$nav = 'nav';
}
###### STATIC pages except 'home'
foreach $name (@{$CONFIG->{static}}) {
if ($query{page} =~ /^$name/) {
foreach (qw(
top
bgcolor
top2
versions
logo2
stats
),
$nav,
$name,
) {
html_cat(\$html,$_,$CONFIG,\%ftxt);
}
$html .= $pagerror;
last PageGen;
}
}
###### HOME
if ($query{page} =~ /^home/) {
foreach (qw(
top
bgcolor
top2
versions
logo1
stats
),
'nav',
'home',
) {
html_cat(\$html,$_,$CONFIG,\%ftxt);
}
$html .= (exists $CONFIG->{reason} && $CONFIG->{reason})
? $CONFIG->{reason}
: q
|SpamCannibal does not block email access except for IP addresses and
generic netblocks that have sent or relayed what we believe to be spam or
other unsolicited email directly to our email servers. Spam originating
IP addresses are blocked ONLY for access to our mail servers, however,
the database we use for that purpose is freely available for anyone to
look at and use as they see fit.
|;
$html .= "\n";
last PageGen;
}
###### WHOIS
if ($query{page} =~ /^whois/) {
my $IP = ($query{whois} && $query{whois} =~ /(\d+\.\d+\.\d+\.\d+)/)
? $1 : '';
foreach (qw(
top
bgcolor
top2
versions
logo2
stats
),
$nav,
'whois',
) {
html_cat(\$html,$_,$CONFIG,\%ftxt);
}
if ($IP) {
if ($ENV{HTTP_REFERER} !~ /$ENV{SERVER_NAME}/i || $ENV{HTTP_REFERER} =~ m|/\?|) {
$html .= qq|
Due to the excessive load placed on our system, we have disabled the ability
for third party sites to query the Whois Proxy through the web
interface. Please enter your request manually.
|;
} else {
my $cc = (@_ = Mail::SpamCannibal::IP2ccFlag::get($IP))
? qq| $_[0]
record number |. $recno;
if ($ip) {
$html .= ' IP '. $ip;
}
$html .= q|
|;
for(my $i=0;$i <= $#IPs;$i += 5) {
$html .= '
';
foreach(0..4) {
my $cell = ' ';
if ($IPs[$i+$_]) {
my $ip = inet_ntoa($IPs[$i+$_]);
$cell = ($ip =~ /^127\./) ? $ip : # no link for internal addresses
q||. $ip .q||;
}
$html .= q|
|. $cell . qq|
\n|;
}
$html .= qq|
\n|;
}
$html .= q|
|;
}
last PageGen;
}
###### END page search
$html .= q|Not Found
The URL requested was not found on this server
|;
last PageGen; # oops!
}
# Special handling items
# updpass
# spamlst
#
$html .= q|
| if $query{page} =~ /^updpass/;
$query{spam} =~ s/\r//g;
$query{spam} =~ s/\n/\\n/g;
$html .= q|
| if $query{page} =~ /^spamlst/ &&
validIP($query{host});
# if this is an admin session, insert page timer
$html .= q|
| if $admses && $query{page} !~ /login|passwd|2realAH/;
$html .= q|
tag
$query{page} = 'updpass';
} else {
$query{page} = 'ahome';
}
next PageGen;
}
###### 2REALAH
if ($admin && $query{page} =~ '2realAH') {
$html = q|