File Coverage

blib/lib/Metabrik/Audit/Dns.pm
Criterion Covered Total %
statement 9 83 10.8
branch 0 42 0.0
condition 0 27 0.0
subroutine 3 8 37.5
pod 1 5 20.0
total 13 165 7.8


line stmt bran cond sub pod time code
1             #
2             # $Id$
3             #
4             # audit::dns Brik
5             #
6             package Metabrik::Audit::Dns;
7 1     1   533 use strict;
  1         3  
  1         30  
8 1     1   5 use warnings;
  1         2  
  1         26  
9              
10 1     1   5 use base qw(Metabrik);
  1         2  
  1         530  
11              
12             sub brik_properties {
13             return {
14 0     0 1   revision => '$Revision$',
15             tags => [ qw(unstable) ],
16             author => 'GomoR ',
17             license => 'http://opensource.org/licenses/BSD-3-Clause',
18             attributes => {
19             nameserver => [ qw(nameserver|$nameserver_list) ],
20             domainname => [ qw(domainname) ],
21             rtimeout => [ qw(timeout) ],
22             },
23             attributes_default => {
24             rtimeout => 2,
25             nameserver => '127.0.0.1',
26             },
27             # XXX: version should use network::dns version_bind Command
28             commands => {
29             version => [ qw(nameserver|$nameserver_list|OPTIONAL) ],
30             recursion => [ qw(nameserver|$nameserver_list|OPTIONAL) ],
31             axfr => [ qw(nameserver|$nameserver_list domainname|$domainname_list) ],
32             all => [ qw(nameserver|$nameserver_list|OPTIONAL domainname|$domainname_list|OPTIONAL) ],
33             },
34             require_modules => {
35             'Net::DNS::Resolver' => [ ],
36             },
37             };
38             }
39              
40             sub version {
41 0     0 0   my $self = shift;
42 0           my ($nameserver) = @_;
43              
44 0   0       $nameserver ||= $self->nameserver;
45 0 0         $self->brik_help_run_undef_arg('version', $nameserver) or return;
46 0 0         my $ref = $self->brik_help_run_invalid_arg('version', $nameserver, 'ARRAY', 'SCALAR')
47             or return;
48              
49 0           my $result = {};
50 0 0         if ($ref eq 'ARRAY') {
51 0           for (@$nameserver) {
52 0           my $r = $self->version($_);
53 0           for (keys %$r) { $result->{$_} = $r->{$_} }
  0            
54             }
55             }
56             else {
57 0 0         my $dns = Net::DNS::Resolver->new(
    0          
58             nameservers => [ $nameserver ],
59             recurse => 0,
60             searchlist => [],
61             debug => $self->log->level > 2 ? 1 : 0,
62             udp_timeout => $self->rtimeout,
63             tcp_timeout => $self->rtimeout,
64             #usevc => 1, # Force TCP
65             ) or return $self->log->error("version: Net::DNS::Resolver::new failed");
66            
67 0           my $version = 'undef';
68 0           my $res = $dns->send('version.bind', 'TXT', 'CH');
69 0 0 0       if (defined($res) && defined($res->{answer})) {
70 0           my $rr = $res->{answer}->[0];
71 0 0 0       if (defined($rr) && (defined($rr->{rdata}) || defined($rr->{txtdata}))) {
      0        
72 0   0       $version = unpack("H*", $rr->{rdata} || $rr->{txtdata}->[0]->value);
73             }
74             }
75              
76 0           $result->{$nameserver} = $version;
77             }
78              
79 0           return $result;
80             }
81              
82             sub recursion {
83 0     0 0   my $self = shift;
84 0           my ($nameserver) = @_;
85              
86 0   0       $nameserver ||= $self->nameserver;
87 0 0         $self->brik_help_run_undef_arg('recursion', $nameserver) or return;
88 0 0         my $ref = $self->brik_help_run_invalid_arg('recursion', $nameserver, 'ARRAY', 'SCALAR')
89             or return;
90              
91 0           my $result = {};
92 0 0         if ($ref eq 'ARRAY') {
93 0           for (@$nameserver) {
94 0           my $r = $self->recursion($_);
95 0           for (keys %$r) { $result->{$_} = $r->{$_} }
  0            
96             }
97             }
98             else {
99 0 0         my $dns = Net::DNS::Resolver->new(
    0          
100             nameservers => [ $nameserver ],
101             recurse => 1,
102             searchlist => [],
103             debug => $self->log->level > 2 ? 1 : 0,
104             udp_timeout => $self->rtimeout,
105             tcp_timeout => $self->rtimeout,
106             ) or return $self->log->error("recursion: Net::DNS::Resolver::new failed");
107              
108 0           my $recursion_allowed = 0;
109 0           my $res = $dns->search('example.com');
110 0 0 0       if (defined($res) && defined($res->answer)) {
111 0           $recursion_allowed = 1;
112             }
113              
114 0           $result->{$nameserver} = $recursion_allowed;
115             }
116              
117 0           return $result;
118             }
119              
120             sub axfr {
121 0     0 0   my $self = shift;
122 0           my ($nameserver, $domainname) = @_;
123              
124 0   0       $nameserver ||= $self->nameserver;
125 0   0       $domainname ||= $self->domainname;
126 0 0         $self->brik_help_run_undef_arg('axfr', $nameserver) or return;
127 0 0         my $ref = $self->brik_help_run_invalid_arg('axfr', $nameserver, 'ARRAY', 'SCALAR')
128             or return;
129 0 0         $self->brik_help_run_undef_arg('axfr', $domainname) or return;
130              
131 0           my $result = {};
132 0 0         if ($ref eq 'ARRAY') {
133 0           for (@$nameserver) {
134 0           my $r = $self->axfr($_);
135 0           for (keys %$r) { $result->{$_} = $r->{$_} }
  0            
136             }
137             }
138             else {
139 0 0         my $dns = Net::DNS::Resolver->new(
    0          
    0          
140             nameservers => [ $nameserver ],
141             recurse => 0,
142             searchlist => ref($domainname) eq 'ARRAY' ? $domainname : [ $domainname ],
143             debug => $self->log->level > 2 ? 1 : 0,
144             udp_timeout => $self->rtimeout,
145             tcp_timeout => $self->rtimeout,
146             ) or return $self->log->error("axfr: Net::DNS::Resolver::new failed");
147              
148 0           my $axfr_allowed = 0;
149 0           my @res;
150 0           eval {
151 0           @res = $dns->axfr; # May fail with 'improperly terminated AXFR'
152             };
153 0 0         if (@res) {
154 0           $axfr_allowed = 1;
155             }
156              
157 0           $result->{$nameserver} = $axfr_allowed;
158             }
159              
160 0           return $result;
161             }
162              
163             sub all {
164 0     0 0   my $self = shift;
165 0           my ($nameserver, $domainname) = @_;
166              
167 0           my $result = {};
168              
169 0           my $version = $self->version($nameserver, $domainname);
170 0           for (keys %$version) { $result->{$_}{version} = $version->{$_} }
  0            
171              
172 0           my $recursion = $self->recursion($nameserver, $domainname);
173 0           for (keys %$recursion) { $result->{$_}{recursion} = $recursion->{$_} }
  0            
174              
175 0           my $axfr = $self->axfr($nameserver, $domainname);
176 0           for (keys %$axfr) { $result->{$_}{axfr} = $axfr->{$_} }
  0            
177              
178 0           return $result;
179             }
180              
181             1;
182              
183             __END__