package plugins::dsbl_deny; # A DSBL comment filter plugin for Movable Type # MT implementation inspired by http://weblog.sinteur.com/index.php?p=7967 # Requires Net::DNS package or the nslookup utility # # Modified by Jacques Distler ( http://golem.ph.utexas.edu/~distler/blog/ ) # to # 1) Use the opm.blotzed.org list of open HTTP proxies # 2) Block trackbacks as well as Comments # # Modified by Chad Everett ( http://jayseae.cxliv.org/ ) # to # 1) Allow template tag to specify an IP address to check # 2) Register the plugin with MT::Plugin # 3) Check for MT version of 3.1-something for particular features use MT; use MT::Template::Context; if ($MT::VERSION =~ m(^3\.1)) { my $plugin; use MT::Plugin; $plugin = new MT::Plugin(); $plugin->name('dsbl_deny'); $plugin->description('A DSBL comment filter plugin for Movable Type'); MT->add_plugin($plugin); MT->add_callback('CommentFilter', 2, undef, \&plugins::dsbl_deny::check_comment_for_proxy); MT->add_callback('TBPingFilter', 2, undef, \&plugins::dsbl_deny::check_tb_for_proxy); } MT::Template::Context->add_tag(DSBLDeny => \&check_ip_for_proxy); my $dnsbl = 'opm.blitzed.org'; my $dnsbl_url = 'http://opm.blitzed.org/proxy?ip='; sub check_comment_for_proxy { my ($eh, $app, $comment) = @_; my $remote_ip = $app->remote_ip; my ($a, $b, $c, $d) = split /\./, $remote_ip; if (checkdnsrr("$d.$c.$b.$a.$dnsbl")) { $app->log("Blocked comment post from known open proxy: $remote_ip"); my $url = $dnsbl_url . $remote_ip; # we're forcing out the header here and exiting since I can't find # a cleaner way to force a redirection to the DSBL.org site... if ($ENV{MOD_PERL}) { $app->{apache}->header_out(Location => $url); $app->response_code(Apache::Constants::REDIRECT()); $app->send_http_header; } else { my $q = $app->{query}; print $q->redirect(-uri => $url, %{ $app->{cgi_headers} }); } exit; } return 1; } sub check_ip_for_proxy { my ($ctx, $args) = @_; my $remote_ip = $args->{ip}; return $ctx->error(MT->translate("You must specify an IP address.")) unless ($remote_ip); my ($a, $b, $c, $d) = split /\./, $remote_ip; if (checkdnsrr("$d.$c.$b.$a.$dnsbl")) { return $ctx->error(MT->translate("IP address of known open proxy: $remote_ip")); } return ''; } sub check_tb_for_proxy { my ($eh, $app, $tb) = @_; my $remote_ip = $app->remote_ip; my ($a, $b, $c, $d) = split /\./, $remote_ip; if (checkdnsrr("$d.$c.$b.$a.$dnsbl")) { $app->log("Blocked trackback post from known open proxy: $remote_ip"); return 0; } return 1; } sub checkdnsrr { my ($ip, $type) = @_; if (eval 'require Net::DNS;') { my $res = Net::DNS::Resolver->new; my $query = $res->search($ip); if ($query) { foreach my $rr ($query->answer) { if ($type) { next unless $rr->type eq $type; } return 1; } } } else { my $opt = $type ? '-ty='.$type : ''; my $out = `nslookup -sil $opt $ip`; if ($out && ($out !~ 'NXDOMAIN')) { return 1; } } return 0; } 1;