html/tordetect.pl


   1 #!/usr/bin/perl
   2 use strict;
   3 use Irssi;
   4 use Net::DNS;
   5 use vars qw($VERSION %IRSSI);
   6 
   7 $VERSION = "0.0.1";
   8 %IRSSI = (
   9     authors     => "Sebastian 'yath' Schmidt",
  10     contact     => "yath+irssiscripts\@yath.de",
  11     name        => "Tor autodetection for Irssi",
  12     description => "This script will automatically detect people using the ".
  13                    "Tor anonymity network and append \".TOR\" to their ".
  14                    "hostname, to make things like /ignore -time 3600 ".
  15                    "*!*\@*.TOR possible (e.g. when your favourite ".
  16                    "channel gets flooded).",
  17     license     => "Public domain"
  18 );
  19 
  20 use constant {
  21     HOSTSUFFIX => ".TOR",
  22     DNSBL      => "tor-irc.dnsbl.oftc.net",
  23     CACHETIME  => 3600,
  24 };
  25 
  26 my %cache;
  27 
  28 sub resolve_host($) {
  29     my $hostname = shift;
  30     return $hostname if "$hostname." =~ (/^(\d{1,3}\.){4}$/); # yes, that sucks
  31 
  32     my $res = Net::DNS::Resolver->new();
  33     my $q = $res->search($hostname, "A");
  34     return unless $q;
  35     return map { $_->address } grep { $_->type eq "A" } $q->answer;
  36 }
  37 
  38 sub reverse_addr($) {
  39     return join(".", reverse(split(/\./, $_[0])));
  40 }
  41 
  42 sub istor($) {
  43     my $hostname = shift;
  44     if (exists($cache{$hostname})) {
  45         if (time >= $cache{$hostname}->[0]) {
  46             delete $cache{$hostname};
  47         } else {
  48             return $cache{$hostname}->[1];
  49         }
  50     }
  51 
  52     my $result = 0;
  53 
  54     foreach my $addr (resolve_host($hostname)) {
  55         if (grep /^127\.0\.0\.1$/,
  56                 resolve_host(reverse_addr($addr).".".DNSBL)) {
  57             $result = 1;
  58             last;
  59         }
  60     }
  61 
  62     $cache{$hostname} = [time+CACHETIME, $result];
  63     return $result;
  64 }
  65 
  66 sub handler_server_event {
  67     my ($server, $data, $sender_nick, $sender_addr) = @_;
  68     return unless ($sender_nick ne "" and $sender_addr =~ /.+@(.+)/);
  69     $sender_addr .= HOSTSUFFIX if istor($1);
  70     Irssi::signal_continue($server, $data, $sender_nick, $sender_addr);
  71 }
  72 
  73 Irssi::signal_add("server event", \&handler_server_event);