sub checkForOpenProxy { my($self, $ip) = @_; # If we weren't passed an IP address, default to whatever # the current IP address is. if (!$ip && $ENV{GATEWAY_INTERFACE}) { my $r = Apache->request; $ip = $r->connection->remote_ip if $r; } # If we don't have an IP address, it can't be an open proxy. return 0 if !$ip; # Known secure IPs also don't count as open proxies. my $constants = getCurrentStatic(); my $gSkin = getCurrentSkin(); my $secure_ip_regex = $constants->{admin_secure_ip_regex}; return 0 if $secure_ip_regex && $ip =~ /$secure_ip_regex/; # If the IP address is already one we have listed, use the # existing listing. my $port = $self->getKnownOpenProxy($ip); if (defined $port) { #print STDERR scalar(localtime) . " cfop no need to check ip '$ip', port is '$port'\n"; return $port; } #print STDERR scalar(localtime) . " cfop ip '$ip' not known, checking\n"; # No known answer; probe the IP address and get an answer. my $ports = $constants->{comments_portscan_ports} || '80 8080 8000 3128'; my @ports = grep /^\d+$/, split / /, $ports; return 0 if !@ports; my $timeout = $constants->{comments_portscan_timeout} || 5; my $connect_timeout = int($timeout/scalar(@ports)+0.2); my $ok_url = "$gSkin->{absolutedir}/ok.txt"; my $pua = Slash::Custom::ParUserAgent->new(); $pua->redirect(1); $pua->max_redirect(3); $pua->max_hosts(scalar(@ports)); $pua->max_req(scalar(@ports)); $pua->timeout($connect_timeout); #use LWP::Debug; #use Data::Dumper; #LWP::Debug::level("+trace"); LWP::Debug::level("+debug"); my $start_time = Time::HiRes::time; local $_proxy_port = undef; sub _cfop_callback { my($data, $response, $protocol) = @_; #print STDERR scalar(localtime) . " _cfop_callback protocol '$protocol' port '$_proxy_port' succ '" . ($response->is_success()) . "' data '$data' content '" . ($response->is_success() ? $response->content() : "(fail)") . "'\n"; if ($response->is_success() && $data eq "ok\n") { # We got a success, so the IP is a proxy. # We should know the proxy's port at this # point; if not, that's remarkable, so # print an error. my $orig_req = $response->request(); $_proxy_port = $orig_req->{_slash_proxytest_port}; if (!$_proxy_port) { print STDERR scalar(localtime) . " _cfop_callback got data but no port, protocol '$protocol' port '$_proxy_port' succ '" . ($response->is_success()) . "' data '$data' content '" . $response->content() . "'\n"; } $_proxy_port ||= 1; # We can quit listening on any of the # other ports that may have connected, # returning immediately from the wait(). # So we want to return C_ENDALL. Except # C_ENDALL doesn't seem to _work_, it # crashes in _remove_current_connection. # Argh. So we use C_LASTCON. return LWP::Parallel::UserAgent::C_LASTCON; } #print STDERR scalar(localtime) . " _cfop_callback protocol '$protocol' succ '0'\n"; } #print STDERR scalar(localtime) . " cfop beginning registering\n"; for my $port (@ports) { # We switch to a new proxy every time thru. $pua->proxy('http', "http://$ip:$port/"); my $req = HTTP::Request->new(GET => $ok_url); $req->{_slash_proxytest_port} = $port; #print STDERR scalar(localtime) . " cfop registering for proxy '$pua->{proxy}{http}'\n"; $pua->register($req, \&_cfop_callback); } #print STDERR scalar(localtime) . "pua: " . Dumper($pua); my $elapsed = Time::HiRes::time - $start_time; my $wait_timeout = int($timeout - $elapsed + 0.5); $wait_timeout = 1 if $wait_timeout wait($wait_timeout); #print STDERR scalar(localtime) . " cfop done with wait, returning " . (defined $_proxy_port ? 'undef' : "'$port'") . "\n"; $_proxy_port = 0 if !$_proxy_port; $elapsed = Time::HiRes::time - $start_time; # Store this value so we don't keep probing the IP. $self->setKnownOpenProxy($ip, $_proxy_port, $elapsed); return $_proxy_port; }
(Score: 4, Funny) by darkfeline on Wednesday April 09 2014, @08:05PM
As a programmer, I'm much more disturbed by the fact that this was in the database code. As others have mentioned, while being port-scanned is certainly not pleasant, it's not really *wrong* either. It's akin to being stared at for a few seconds beyond the awkward cutoff when in public, uncomfortable for some, perhaps, but perfectly normal. But putting code where it doesn't belong? That's unforgivable. It needs to be refactored ASAP, before someone dies. Programmer rage is a legitimate workplace hazard.
Join the SDF Public Access UNIX System today!
(Score: 0) by Anonymous Coward on Wednesday April 09 2014, @08:17PM
I think a good guess was they threw it in there because they only cared about proxying spammers when one of them was about to successfully commmit to a database change. Displaying form data and requests doesn't mean the post was actually being published...
(Score: 2) by Thexalon on Wednesday April 09 2014, @09:01PM
I certainly find it suspicious that it was in the database code - it suggests that somebody was in fact trying to hide it.
"Think of how stupid the average person is. Then realize half of 'em are stupider than that." - George Carlin
(Score: 2) by khallow on Wednesday April 09 2014, @09:06PM
The AC above you had a good point. They probably wouldn't care about the fun and games until it became time for dumping some spam in the database. Or it might be that the database monkey was the one asked to fix the problem and this was in their scope.
(Score: 3, Informative) by NCommander on Wednesday April 09 2014, @11:54PM
I don't think this was malicious; just laziness since there's no general Misc module. The DB library is something of a catch all of random crap that doesn't fit anywhere else, and it can be accessed from any module by doing getCurrentDatabase, then calling methods from DB.
Still always moving
(Score: 1) by migz on Thursday April 10 2014, @11:37AM
As a dev with over 20 years experience I have seen misc code creep into the db module of many projects. It's probably because it is included in just about every piece of code. It's easier to dump it there than refactoring the planet. Unfortunately hacks like this create a lot of bit-rot. And since they are often done in a hurry to "save time" they never get fixed.
But seriously a port scanner? This one needs a feature on daily WTF.