1 #! /usr/bin/perl |
1 #! /usr/bin/perl |
2 |
2 |
|
3 use v5.10; |
3 use warnings; |
4 use warnings; |
4 use strict; |
5 use strict; |
5 use FindBin; |
6 use FindBin; |
6 use File::Temp; |
7 use File::Temp; |
7 use Getopt::Long; |
8 use Getopt::Long; |
8 use Pod::Usage; |
9 use Pod::Usage; |
9 |
10 use File::Basename; |
10 sub read_conf; |
11 use if $ENV{DEBUG} => "Smart::Comments"; |
|
12 |
|
13 my $ME = basename $0; |
|
14 |
|
15 sub read_conf(@); |
11 sub read_argv($); |
16 sub read_argv($); |
12 sub rm_keys(@); |
17 sub rm_keys($@); |
13 sub ck_zone(@); |
18 sub ck_zone($@); |
14 sub creat_ksk(@); |
19 sub create_ksk($@); |
15 sub creat_zsk(@); |
20 sub create_zsk($@); |
16 sub post_creat(@); |
21 sub post_create($@); |
17 |
22 |
18 MAIN: { |
23 MAIN: { |
19 my @zone; |
24 ### reading config |
20 my $do; |
25 my %conf = read_conf("$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf"); |
21 |
26 |
22 my %conf = read_conf(); |
27 my ($cmd, @zones) = read_argv($conf{master_dir}); |
23 ($do, @zone) = read_argv($conf{master_dir}); |
28 |
24 |
29 given ($cmd) { |
25 # completed the program, if not a valid zones was handed over |
30 when ("rm") { rm_keys($conf{master_dir}, @zones); exit } |
26 unless (@zone) { exit; } |
31 when ("ck") { ck_zone($conf{master_dir}, @zones) } |
27 |
32 when ("ksk") { create_ksk($conf{master_dir}, @zones) } |
28 if ($do eq "rm") { rm_keys($conf{master_dir}, @zone); exit; } |
33 }; |
29 if ($do eq "ck") { ck_zone($conf{master_dir}, @zone); } |
34 |
30 if ($do eq "ksk") { creat_ksk($conf{master_dir}, @zone); } |
35 create_zsk($conf{master_dir}, @zones); |
31 |
36 post_create($conf{master_dir}, @zones); |
32 creat_zsk($conf{master_dir}, @zone); |
|
33 post_creat($conf{master_dir}, @zone); |
|
34 } |
37 } |
35 |
38 |
36 sub read_argv ($) { |
39 sub read_argv ($) { |
37 my $master_dir = $_[0]; |
40 my ($master_dir) = @_; |
38 my $zone; |
41 my ($cmd, @zones); # return |
39 my $do; # return |
|
40 my @zone; # return |
|
41 |
42 |
42 GetOptions( |
43 GetOptions( |
43 "z" => sub { $do = "zsk" }, |
44 "zsk" => sub { $cmd = "zsk" }, |
44 "k" => sub { $do = "ksk" }, |
45 "ksk" => sub { $cmd = "ksk" }, |
45 "h" => sub { pod2usage }, |
46 "rm" => sub { $cmd = "rm" }, |
46 "r" => sub { $do = "rm" }, |
47 "ck|check" => sub { $cmd = "ck" }, |
47 "c" => sub { $do = "ck" }, |
48 "h|help" => sub { pod2usage(-exitvalue => 0, -verbose => 1) }, |
48 ) or pod2usage; |
49 "m|man" => sub { |
|
50 pod2usage( |
|
51 -exitvalue => 0, |
|
52 -noperldoc => system("perldoc -V &>/dev/null"), |
|
53 -verbose => 2 |
|
54 ); |
|
55 }, |
|
56 ) |
|
57 and @ARGV |
|
58 or pod2usage; |
49 |
59 |
50 # checks the zones in argv if there are managed zones |
60 # checks the zones in argv if there are managed zones |
51 for (@ARGV) { |
61 foreach (@ARGV) { |
52 chomp($zone = `idn --quiet "$_"`); |
62 chomp(my $zone = `idn --quiet "$_"`); |
53 if (-e "$master_dir/$zone/$zone") { |
63 |
54 push @zone, $zone; |
64 die "zone $zone is not managed\n" |
55 } |
65 if not -f "$master_dir/$zone/$zone"; |
56 } |
66 |
57 return ($do, @zone); |
67 push @zones, $zone; |
58 } |
68 } |
59 |
69 return ($cmd, @zones); |
60 sub read_conf { |
70 } |
|
71 |
|
72 sub read_conf(@) { |
61 |
73 |
62 # read configuration |
74 # read configuration |
63 my @conffile = ("etc/dnstools.conf", "$FindBin::Bin/dnstools.conf"); |
75 my @conffiles = @_; |
64 my %return; |
76 my %return; |
65 |
77 |
66 for (grep { -f } @conffile) { |
78 my ($_) = grep { -f } @conffiles; |
67 open(CONFIG, "<", $_) or die "Can't open $_: $!\n"; |
79 open(my $cf, $_) or die "Can't open $_: $!\n"; |
68 } |
80 |
69 unless (seek(CONFIG, 0, 0)) { |
81 while (<$cf>) { |
70 die "Can't open config (searched: @conffile)\n"; |
|
71 } |
|
72 while (<CONFIG>) { |
|
73 chomp; |
|
74 s/#.*//; |
82 s/#.*//; |
75 s/\s//g; |
83 s/\s//g; |
76 |
|
77 next unless length; |
84 next unless length; |
78 my ($cname, $ccont) = split(/\s*=\s*/, $_, 2); |
85 my ($cname, $ccont) = split(/\s*=\s*/, $_, 2); |
79 $return{$cname} = $ccont; |
86 $return{$cname} = $ccont; |
80 } |
87 } |
81 close(CONFIG); |
|
82 return %return; |
88 return %return; |
83 } |
89 } |
84 |
90 |
85 sub rm_keys (@) { |
91 sub rm_keys ($@) { |
86 |
92 |
87 # deletes all the keys were handed over -rm in argv |
93 # deletes all the keys were handed over -rm in argv |
88 my ($master_dir, @zone) = @_; |
94 my ($master_dir, @zone) = @_; |
89 my @new_zone_content; |
|
90 my @old_zone_content; |
|
91 |
95 |
92 for (@zone) { |
96 for (@zone) { |
93 my $zone = $_; |
97 my $zone = $_; |
94 |
98 |
95 my $zpf = "$master_dir/$zone"; |
99 my $zpf = "$master_dir/$zone"; |
121 |
125 |
122 if ($ep == 1) { |
126 if ($ep == 1) { |
123 print " * $zone: removed key-set\n"; |
127 print " * $zone: removed key-set\n"; |
124 } |
128 } |
125 |
129 |
126 open(ZONE, "$zpf/$zone") |
130 open(my $old, "$zpf/$zone") or die "$zpf/$zone: $!\n"; |
127 or die "$zpf/$zone: $!\n"; |
131 my $fh = File::Temp->new(DIR => $zpf) or die "Can't create tmpfile: $!\n"; |
128 @old_zone_content = <ZONE>; |
132 print $fh grep { not /^\s*\$INCLUDE.*"K$zone.*\.key"/i } <$old>; |
129 close(ZONE); |
133 rename($fh->filename => "$zpf/$zone") |
130 |
134 or die "Can't rename " . $fh->filename . " to $zpf/$zone: $!\n"; |
131 for (@old_zone_content) { |
135 } |
132 unless (m#\$INCLUDE.*\"K$zone.*\.key\"#) { |
136 } |
133 push @new_zone_content, $_; |
137 |
134 } |
138 sub create_ksk ($@) { |
135 } |
|
136 |
|
137 { |
|
138 my $fh = File::Temp->new(DIR => "$zpf") |
|
139 or die "Can't create tmpdir: $!\n"; |
|
140 print $fh join "" => @new_zone_content, ""; |
|
141 rename($fh->filename => "$zpf/$zone") |
|
142 or die "Can't rename " . $fh->filename . " to $zpf/$zone: $!\n"; |
|
143 } |
|
144 |
|
145 } |
|
146 } |
|
147 |
|
148 sub creat_ksk (@) { |
|
149 my ($master_dir, @zone) = @_; |
139 my ($master_dir, @zone) = @_; |
150 my @index; |
140 my @index; |
151 my $keyname; |
141 my $keyname; |
152 |
142 |
153 for (@zone) { |
143 for (@zone) { |
262 unlink("$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n"; |
252 unlink("$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n"; |
263 } |
253 } |
264 } |
254 } |
265 } |
255 } |
266 |
256 |
267 sub post_creat (@) { |
257 sub post_create ($@) { |
268 my ($master_dir, @zone) = @_; |
258 my ($master_dir, @zone) = @_; |
269 for (@zone) { |
259 for (@zone) { |
270 my $zone = $_; |
260 my $zone = $_; |
271 `touch $master_dir/$zone/$zone`; |
261 `touch $master_dir/$zone/$zone`; |
272 &kill_useless_keys($zone, $master_dir); |
262 &kill_useless_keys($zone, $master_dir); |
273 &key_to_zonefile($zone, $master_dir); |
263 &key_to_zonefile($zone, $master_dir); |
274 } |
264 } |
275 } |
265 } |
276 |
266 |
277 sub kill_useless_keys (@) { |
267 sub kill_useless_keys ($@) { |
278 |
268 |
279 # the function deletes all keys that are not available in the zone |
269 # the function deletes all keys that are not available in the zone |
280 |
270 |
281 my $zone = $_[0]; |
271 my $zone = $_[0]; |
282 my $master_dir = $_[1]; |
272 my $master_dir = $_[1]; |