#!/usr/bin/perl # http://www.jmbsoft.com/license.php $DDIR = './data'; require "$DDIR/variables"; ## Parse the request _ParseRequest($ENV{'REQUEST_METHOD'}); if( $ENV{'REQUEST_METHOD'} eq 'GET' ) { if( $O_GATEWAY ) { DisplayGateway(); } else { GiveHit(); } } elsif( $ENV{'REQUEST_METHOD'} eq 'POST' ) { GiveHit(); } sub GiveHit { my $forward_url = $FORWARD_URL; ## If using the gateway, and requiring cookie enabled browser, check to make sure the cookie is set if( $O_GATEWAY && $O_REQ_COOKIES && $ENV{'HTTP_COOKIE'} !~ /arp_gateway=true/ ) { HandleCheat('No Cookie Support'); } ## If using cookies to track hits, check the arp_id cookie if( $O_COOKIES && index($ENV{'HTTP_COOKIE'}, "arp_$F{'id'}=") != -1 ) { HandleCheat('Multiple Click - Cookie'); } ## If not allowing proxies, check for proxy server if( $O_PROXY && ($ENV{'HTTP_VIA'} || $ENV{'HTTP_X_FORWARDED_FOR'}) ) { HandleCheat('Proxy Detected'); } ## Check for a valid browser if( !$ENV{'HTTP_ACCEPT'} || !$ENV{'HTTP_USER_AGENT'} ) { HandleCheat('Unsupported Browser'); } ## If using the gateway, check for valid referer if( $O_GATEWAY && index($ENV{'HTTP_REFERER'}, $IN_URL) == -1 ) { HandleCheat('Bad Referring URL'); } ## If using the gateway, check the session if( $O_GATEWAY && time - $F{'s'} > $GATEWAY_EXPIRE ) { HandleCheat('Expired Gateway Session'); } ## Check the IP address if using IP logging if( $O_IPS ) { CheckIP(); } ## Set a cookie to mark that this browser has been used to register a hit if( $O_COOKIES ) { SetCookie("arp_$F{'id'}", time, $COOKIE_EXPIRE); } my @member = (); $F{'id'} =~ s/\||;//gi; ## Give the member a hit if( -f "./data/members/$F{'id'}" ) { open(FILE, "+<./data/members/$F{'id'}") || _Error("$!", "./data/members/$F{'id'}"); flock(FILE, 2); @member = split(/\|/, , 31); $member[0]++; $member[2]++; $member[20] = 0; seek(FILE, 0, 0); print FILE join('|', @member); my $tell = tell(FILE); if( $tell != -1 ) { truncate(FILE, $tell); } flock(FILE, 8); close(FILE); } ## See if it is time for a rebuild or reset CheckTime() if( !$O_CRON ); if( $O_FORWARD_CAT && $member[14] ) { $forward_url = "$MAIN_URL/" . _PlainString($member[14]) . ".$FILE_EXT"; } ## Forward surfer to the correct page print "Location: $forward_url\n\n"; } sub DisplayGateway { if( !$F{'id'} ) { print "Location: $FORWARD_URL\n\n"; exit; } if( $O_REQ_COOKIES ) { SetCookie('arp_gateway', 'true', 86400); } $T{'In_URL'} = $IN_URL; $T{'Session'} = time; $T{'ID'} = $F{'id'}; print "Content-type: text/html\n\n"; open(FILE, "./templates/in_gateway.tpl"); read(FILE, $gateway, 65536); close(FILE); $gateway =~ s/##(.*?)##/$T{$1}/gise; print $gateway; } sub HandleCheat { my $type = shift; my $message = "[%s] %s [%s] [%s]\n"; my $ip_string = "$ENV{'REMOTE_ADDR'}" . ($ENV{'HTTP_X_FORWARDED_FOR'} ? " Proxy: $ENV{'HTTP_X_FORWARDED_FOR'}" : ''); if( $O_CHEAT_LOG ) { open(CHEAT, ">>$DDIR/cheatlog"); printf CHEAT ($message, scalar(gmtime(time+3600*$TIME_ZONE)), $type, $F{'id'}, $ip_string); close(CHEAT); } ## See if it is time for a rebuild or reset CheckTime() if( !$O_CRON ); print "Location: $FORWARD_URL\n\n"; exit; } sub CheckIP { my $a = (split(/\./, $ENV{'REMOTE_ADDR'}))[0]; open(IP, "+<$DDIR/ips/$a") || _Error("$!", "$DDIR/ips/$a"); flock(IP, 2); for( ) { if( $_ eq "$ENV{'REMOTE_ADDR'}|$F{'id'}\n" ) { flock(IP, 8); close(IP); HandleCheat("Multiple Click - IP Address"); } } print IP "$ENV{'REMOTE_ADDR'}|$F{'id'}\n"; flock(IP, 8); close(IP); } sub SetCookie { my $name = shift; my $value = shift; my $expires = shift; my @months = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); my @days = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"); my @date = gmtime(time + $expires); printf("Set-Cookie: %s=%s; expires=%s, %02d-%s-%02d %02d:%02d:%02d GMT\n", $name, $value, $days[$date[6]], $date[3], $months[$date[4]], $date[5] + 1900, $date[2], $date[1], $date[0]); } sub CheckTime { my $line = undef; my $key = undef; my $time = time; $TIMES = {}; open(TIMES, "+<$DDIR/times") || _Error("$!", "$DDIR/times"); if( flock(TIMES, 2|4) ) { my $required = 0; my $update = 0; for( ) { $line = $_; if( $line =~ /^=>\[(.*?)\]\n/ ) { $key = $1; } else { $TIMES->{$key} .= $line; } } if( $time - $TIMES->{'Rebuild'} >= $REBUILD ) { require 'common.pl'; require 'arp.pl'; $required = 1; $update = 1; $TIMES->{'Rebuild'} = "$time\n"; $TIMES->{'Rebuild_By'} = "in.cgi\n"; BuildPages(); } if( $time - $TIMES->{'Reset'} >= $RESET ) { if( !$required ) { require 'common.pl'; require 'arp.pl'; } $update = 1; $TIMES->{'Reset'} = "$time\n"; $TIMES->{'Reset_By'} = "in.cgi\n"; ResetCurrentHits(); } if( $O_IPS && $time - $TIMES->{'IP_Clean'} >= $IP_EXPIRE ) { $TIMES->{'IP_Clean'} = "$time\n"; $update = 1; for( 1..255 ) { open(IPFILE, ">$DDIR/ips/$_"); close(IPFILE); } } if( $update ) { seek(TIMES, 0, 0); for( keys %$TIMES ) { print TIMES "=>[$_]\n$TIMES->{$_}"; } my $tell = tell(TIMES); if( $tell != -1 ) { truncate(TIMES, $tell); } } flock(TIMES, 8); } close(TIMES); } sub _PlainString { my $string = shift; $string =~ s/[^a-z0-9]//gi; return lc($string); } sub _Error { my $error = shift; my $file = shift; print "Content-type: text/html\n\n"; print "Error: $error
"; print "File: $file
"; exit; } sub _ParseRequest { my $type = shift; my $buffer = undef; my $name = undef; my $value = undef; my @pairs = (); if( $type eq 'POST' ) { read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}); } else { $buffer = $ENV{'QUERY_STRING'}; } @pairs = split(/&/, $buffer); for (@pairs) { ($name, $value) = split(/=/, $_); $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $F{$name} = $value; } }