source: trunk/dnsbl/dnsbl.cgi@ 69

Last change on this file since 69 was 69, checked in by Kris Deugau, 6 years ago

/trunk/dnsbl

  • Accumulated fixes and tweaks from production
  • Add FindBin to a couple of scripts to make them more portable; they no longer need to be run from the directory they're in, or have system-specific paths hardcoded in either "use lib" or a -I argument
  • Property svn:executable set to *
  • Property svn:keywords set to Date Rev Author Id
File size: 7.3 KB
RevLine 
[2]1#!/usr/bin/perl
[40]2# Main add-IP-to-list CGI
3##
4# $Id: dnsbl.cgi 69 2018-07-19 21:03:38Z kdeugau $
[67]5# Copyright 2009-2012,2014,2015,2017,2018 Kris Deugau <kdeugau@deepnet.cx>
[40]6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation, either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19##
[2]20
21use strict;
22use warnings;
[17]23no warnings qw(uninitialized);
[2]24use CGI::Carp qw (fatalsToBrowser);
25use CGI::Simple;
26use HTML::Template;
[64]27use Net::DNS;
[45]28
[69]29# push "the directory the script is in" into @INC
30use FindBin;
31use lib "$FindBin::RealBin/";
32
[67]33use DNSBL 2.2;
[51]34use DNSBLweb;
[2]35
36# Set up the CGI object...
37my $q = new CGI::Simple;
38# ... and get query-string params as well as POST params if necessary
39$q->parse_query_string;
40
41my %webvar;
42# This is probably excessive fiddling, but it puts the parameters somewhere my fingers know about...
43foreach ($q->param()) {
44 $webvar{$_} = $q->param($_);
45}
46
47my $dnsbl = new DNSBL;
[54]48# here be drag'ns, should theoretically be $DNSBL::maxlvl, but we
49# only have up to level 4 in the report HTML/template
[55]50my $maxlvl = 4;
[2]51
[46]52# try to be friendly to non-US-ASCII characters. Still need to find what
53# difference from RH<->Debian is still at fault.
54print $q->header(-charset=>'utf8');
[24]55
[25]56# default DB info - all other settings should be loaded from the DB.
57my $dbhost = "localhost";
58my $dbname = "dnsbl";
59my $dbuser = "dnsbl";
60my $dbpass = "spambgone";
[2]61
[25]62# Load a config ref containing DB host, name, user, and pass info based on
63# from the server name + full script web path. This allows us to host
64# multiple instances without having to duplicate the code.
65# This file is a Perl fragment to be processed inline.
[26]66my $cfgname = $ENV{SERVER_NAME}.$ENV{REQUEST_URI};
[25]67$cfgname =~ s|[./-]|_|g;
[66]68$cfgname =~ s|_dnsbl_cgi.*||;
[26]69$cfgname =~ s|_$||;
[25]70if (-e "/etc/dnsbl/$cfgname.conf") {
71 my $cfg = `cat /etc/dnsbl/$cfgname.conf`;
72 ($cfg) = ($cfg =~ /^(.+)$/s); # avoid warnings, failures, and general nastiness with taint mode
73 eval $cfg;
74}
75
76my $dbh = $dnsbl->connect($dbhost, $dbname, $dbuser, $dbpass);
77
[2]78my $page;
[25]79my $templatedir = $ENV{SCRIPT_FILENAME};
[63]80$templatedir =~ s/\w+\.cgi//;
[25]81$templatedir .= "templates";
82$ENV{HTML_TEMPLATE_ROOT} = $templatedir;
[2]83
[25]84my %config;
85my $sth = $dbh->prepare("SELECT key,value FROM misc");
86$sth->execute;
87while (my ($key,$value) = $sth->fetchrow_array) {
88 $config{$key} = $value;
89}
90
[2]91# decide which page to spit out...
92if (!$webvar{page}) {
[25]93 $page = HTML::Template->new(filename => "index.tmpl");
[2]94} else {
[25]95 $page = HTML::Template->new(filename => "$webvar{page}.tmpl");
[2]96}
97
[25]98$page->param(pgtitle => $config{pgtitle}) if defined($config{pgtitle});
99$page->param(pgcomment => $config{pgcomment}) if defined($config{pgcomment});
100
[2]101if ($webvar{page} eq 'report') {
[26]102 my $dnsblsiteroot = $ENV{REQUEST_URI};
103 $dnsblsiteroot =~ s|/dnsbl\.cgi\?.+|/|;
104 $page->param(dnsblsiteroot => $dnsblsiteroot);
105
[60]106 $webvar{ip} =~ s/^\s*//;
107 $webvar{ip} =~ s/\s*$//;
[2]108 $page->param(ip => $webvar{ip});
[64]109
110##fixme
111# at some point this may need to be tweaked for Net::DNS's 1.x calling convention when they drop support for the older one
112 #my @ptr = rr($webvar{ip});
113 #$page->param(revinfo => join(',',@ptr));
114 my $res = new Net::DNS::Resolver;
115 $res->tcp_timeout(2); # make me adjustable!
116 $res->udp_timeout(2); # make me adjustable!
117 my $query = $res->query($webvar{ip}, "PTR");
118 if ($query) {
119 my @rdata;
120 foreach my $rr ($query->answer) {
121 my ($host,$ttl,$class,$type,$data) =
122 ($rr->string =~ /^([0-9a-zA-Z_.-]+)\s+(\d+)\s+([A-Za-z]+)\s+([A-Za-z]+)\s+(.+)$/s);
123 push @rdata, $data;
124 }
125 $page->param(revinfo => join(', ',@rdata));
126 } else {
127 $page->param(revinfo => "DNS error: ".$res->errorstring);
128 }
129
[66]130 my $ipinfo = $dnsbl->ipexists($webvar{ip});
131 $page->param(nreports => $ipinfo->[0]) if $ipinfo;
132 $page->param(ipexclude => $ipinfo->[1]) if $ipinfo;
133 # extract and list the entire tree the IP is part of
[51]134 $page->param(browsebits =>
135 DNSBLweb::retlvl($dbh, $dnsbl, 0, ip => $webvar{ip}, block => $dnsbl->getcontainer($webvar{ip},0) ));
[54]136 for (my $i=0; $i <= $maxlvl; $i++) {
[66]137 my ($block,$comment,$org) = $dnsbl->getcontainer($webvar{ip},$i);
[2]138 if ($block) {
[66]139 $page->param("comment$i" => $comment);
140 my ($bcl,$bal,$bwl) = $dnsbl->islisted($block);
[29]141 $page->param("autob$i" => $bcl);
[66]142 $page->param("flag$i" => ($bwl ? 'exclude' : ($bal ? 'b1list' : '')) );
143 $page->param("excl$i" => $bwl);
[29]144 my ($ol) = $dnsbl->islisted($org);
145 $page->param("listorg$i" => $ol);
[2]146 $page->param("block$i" => $block);
147 $page->param("org$i" => $org);
148 }
149 }
150} elsif ($webvar{page} eq 'dbreport') {
[26]151 my $dnsblsiteroot = $ENV{REQUEST_URI};
152 $dnsblsiteroot =~ s|/dnsbl\.cgi\?.+|/|;
153 $page->param(dnsblsiteroot => $dnsblsiteroot);
154
[11]155 my $err = '';
[54]156
[60]157 $webvar{ip} =~ s/^\s*//;
158 $webvar{ip} =~ s/\s*$//;
159
[54]160 # basic algo: for each listing level, add the org and block if not already present.
161 # escape the loop if we check a level with no block entered.
162
163 # there are still error checks that should probably be done. changes in block
164 # level/parenting should also Just Work(TM), rather than requiring setparents.pl
165 # or setparents-full.pl
166 for (my $i = 0; $i <= $maxlvl; $i++) {
167 my $orgn = "org$i";
168 my $blockn = "block$i";
[66]169 my $commentn = "comment$i";
170 my $excln = "exclude$i";
[60]171 $webvar{$orgn} =~ s/^\s*//;
172 $webvar{$orgn} =~ s/\s*$//;
173 $webvar{$blockn} =~ s/^\s*//;
174 $webvar{$blockn} =~ s/\s*$//;
[66]175 $webvar{$commentn} =~ s/^\s*//;
176 $webvar{$commentn} =~ s/\s*$//;
177 $webvar{$excln} =~ s/on/1/;
[54]178 my $orgid = $dnsbl->orgexists($webvar{$orgn});
179 if (!$orgid) {
180 $orgid = $dnsbl->addorg($webvar{$orgn});
181 $page->param($orgn => $webvar{$orgn});
[2]182 }
[54]183 if ($webvar{$blockn} =~ /-/) {
[59]184 my $tmp = new NetAddr::IP $webvar{$blockn};
185 if (!$tmp) {
186 # Don't need to autofind ranges that are already CIDR-matched
187 $err .= "Autofinding CIDR block containing $webvar{ip} for range '$webvar{$blockn}': ";
188 my ($s,$f) = split /[\s-]+/, $webvar{$blockn};
189 my $cidr = $dnsbl->range2cidr($s, $f, $webvar{ip});
190 $err .= "$cidr<br>\n";
191 $webvar{$blockn} = $cidr;
192 }
[2]193 }
[54]194 if (!$dnsbl->blockexists($webvar{$blockn})) {
[69]195 my $ret = $dnsbl->addblock($webvar{$blockn}, $orgid, $i, $webvar{$excln}, $webvar{$commentn});
[54]196 $err .= "error adding $webvar{$blockn}: $ret<br>\n" if $ret;
197 $page->param($blockn => $webvar{$blockn});
[66]198 } else {
199 my $ret = $dnsbl->updateblock($webvar{$blockn}, $orgid, $i, $webvar{$excln}, $webvar{$commentn});
200 $err .= "error updating $webvar{$blockn}: $ret<br>\n" if $ret;
[2]201 }
[54]202 last unless $webvar{"block".($i+1)};
[2]203 }
[54]204
[66]205 my $count = $dnsbl->report($webvar{ip}, $webvar{excludeip});
[2]206
207 $page->param(ip => $webvar{ip});
[11]208 $page->param(err => $err);
[22]209
[51]210 $page->param(browsebits =>
211 DNSBLweb::retlvl($dbh, $dnsbl, 0, ip => $webvar{ip}, block => $dnsbl->getcontainer($webvar{ip},0) ));
[2]212}
[25]213
[2]214print $page->output;
Note: See TracBrowser for help on using the repository browser.