#!/usr/bin/perl
#
# $Cambridge: hermes/conf/bind/bin/dnssec-survey,v 1.4 2012/06/06 21:13:06 fanf2 Exp $

use warnings;
use strict;

my $date_re = qr{[0-9]{2}-[A-Z][a-z][a-z]-[0-9]{4}};
my $time_re = qr{[0-9]{2}:[0-9]{2}:[0-9]{2}[.][0-9]{3}};
my $stamp_re = qr{$date_re $time_re};
my $domain_re = qr{[A-Za-z0-9.-]+};

my %month = (	Jan =>  1, Feb =>  2, Mar =>  3,
		Apr =>  4, May =>  5, Jun =>  6,
		Jul =>  7, Aug =>  8, Sep =>  9,
		Oct => 10, Nov => 11, Dec => 12
	    );

sub stamp2time {
	my ($D,$M,$Y,$h,$m,$s,$f) = split m{[ :.-]}, shift;
	$M = $month{$M};
	use integer;
	if ($M > 2) { $M += 1; }
	else { $Y -= 1; $M += 13; }
	my $t = $Y/400 - $Y/100 + $Y*1461/4 + $M*153/5 + $D;
	no integer;
	return $t*86400 + $h*3600 + $m*60 + $s + $f/1000;
}

sub authority {
	my $domain = shift;
	my $flags;
	my $zone;
	for (qx{dig +time=1 +tries=1 soa $domain}) {
		if (m{^;;[ ]flags:([ a-z]+);
		         [ ]QUERY:[ ]\d+,
			 [ ]ANSWER:[ ]\d+,
			 [ ]AUTHORITY:[ ]\d+,
			 [ ]ADDITIONAL:[ ]\d+ }x) {
			$flags = $1;
		} elsif (m{^($domain_re)\s+(\d+)\s+IN\s+SOA\s+}) {
			$zone = $1;
		}
	}
	return ($zone, defined $flags && $flags =~ m{ad} ? 1 : 0);
}

my %zone_of;
my %secure;

my $zones;
my $secure;

select STDOUT; $| = 1;

while (<>) {
	next unless m{^($stamp_re) queries: info: client \S+ [(]($domain_re)[)]:};
	my ($t,$d) = ($1, lc $2);
	next if $d =~ m{(	[.]ahbl[.]org
			|	[.]rfc-ignorant[.]org
			|	[.]barracudacentral[.]org
			|	[.]bondedsender[.]org
			|	[.]habeas[.]com
			|	[.]isipp[.]com
			|	[.]senderscore[.]com
			|	[.]surriel[.]com
			|	[.]njabl[.]org
			|	[.]sorbs[.]net
			|	[.]spamcop[.]net
			|	[.]spamhaus[.]org
			|	[.]support-intelligence[.]net
			|	[.]uribl[.]com
			|	[.]dnsbl[.]ja[.]net
			|	[.]mail-abuse[.]ja[.]net
			)$}x;
	next if exists $zone_of{$d} or exists $secure{$d};
	my ($z,$s) = authority $d;
	next if not defined $z;
	$zone_of{$d} = $z;
	next if exists $secure{$z};
	$secure{$z} = $s;
	$zones += 1;
	$secure += $s;
	print STDOUT "$s $z\n";
	print STDERR "$secure/$zones $s $z\r";
}

exit 0;
