5 use strict; |
5 use strict; |
6 use File::Temp; |
6 use File::Temp; |
7 use Getopt::Long; |
7 use Getopt::Long; |
8 use Pod::Usage; |
8 use Pod::Usage; |
9 use File::Basename; |
9 use File::Basename; |
|
10 use Net::LibIDN qw(:all); |
10 use if $ENV{DEBUG} => "Smart::Comments"; |
11 use if $ENV{DEBUG} => "Smart::Comments"; |
11 use DNStools::Config qw(get_config); |
12 use DNStools::Config qw(get_config); |
12 |
13 |
13 my $ME = basename $0; |
14 my $ME = basename $0; |
14 |
15 |
15 sub read_conf(@); |
|
16 sub read_argv($); |
|
17 sub rm_keys($@); |
16 sub rm_keys($@); |
18 sub ck_zone($@); |
17 sub check_zone($@); |
19 sub create_ksk($@); |
18 sub create_ksk($@); |
20 sub create_zsk($@); |
19 sub create_zsk(@); |
21 sub post_create($@); |
20 sub post_create($@); |
22 |
21 |
|
22 my $CHARSET = "UTF-8"; |
|
23 my %cf; |
|
24 |
23 MAIN: { |
25 MAIN: { |
24 ### reading config |
26 |
25 my %conf = get_config(); |
27 %cf = get_config(); |
26 |
28 my $cmd; |
27 my ($cmd, @zones) = read_argv($conf{master_dir}); |
29 |
28 |
30 system("command -v dnssec-keygen &>/dev/null"); |
29 given ($cmd) { |
31 die "$ME: command 'dnssec-keygen' not found in $ENV{PATH}\n" if $?; |
30 when ("rm") { rm_keys($conf{master_dir}, @zones); exit } |
|
31 when ("ck") { ck_zone($conf{master_dir}, @zones) } |
|
32 when ("ksk") { create_ksk($conf{master_dir}, @zones) } |
|
33 }; |
|
34 |
|
35 create_zsk($conf{master_dir}, @zones); |
|
36 post_create($conf{master_dir}, @zones); |
|
37 } |
|
38 |
|
39 sub read_argv ($) { |
|
40 my ($master_dir) = @_; |
|
41 my ($cmd, @zones); # return |
|
42 |
32 |
43 GetOptions( |
33 GetOptions( |
44 "zsk" => sub { $cmd = "zsk" }, |
34 "zsk" => sub { push @$cmd => "zsk" }, |
45 "ksk" => sub { $cmd = "ksk" }, |
35 "ksk" => sub { push @$cmd => "ksk" }, |
46 "rm" => sub { $cmd = "rm" }, |
36 "rm" => sub { push @$cmd => "rm" }, |
47 "ck|check" => sub { $cmd = "ck" }, |
37 "check" => sub { $cmd = "check" }, |
48 "h|help" => sub { pod2usage(-exitvalue => 0, -verbose => 1) }, |
38 "h|help" => sub { pod2usage(-exit => 0, -verbose => 1) }, |
49 "m|man" => sub { |
39 "m|man" => sub { |
50 pod2usage( |
40 pod2usage( |
51 -exitvalue => 0, |
41 -exit => 0, |
52 -noperldoc => system("perldoc -V &>/dev/null"), |
42 -noperldoc => system("perldoc -V &>/dev/null"), |
53 -verbose => 2 |
43 -verbose => 2 |
54 ); |
44 ); |
55 }, |
45 }, |
56 ) |
46 ) |
57 and @ARGV |
47 and @ARGV |
|
48 and @$cmd == 1 |
|
49 and $cmd = $cmd->[0] |
58 or pod2usage; |
50 or pod2usage; |
59 |
51 |
60 # checks the zones in argv if there are managed zones |
52 # checks the zones in argv if they're managed ones |
61 foreach (@ARGV) { |
53 my @zones; |
62 chomp(my $zone = `idn --quiet "$_"`); |
54 foreach my $utf8zone (@ARGV) { |
|
55 my $zone = idn_to_ascii($utf8zone, $CHARSET); |
63 |
56 |
64 die "zone $zone is not managed\n" |
57 die "zone $zone is not managed\n" |
65 if not -f "$master_dir/$zone/$zone"; |
58 if not -f "$cf{master_dir}/$zone/$zone"; |
66 |
59 |
67 push @zones, $zone; |
60 push @zones, $zone; |
68 } |
61 } |
69 return ($cmd, @zones); |
62 |
70 } |
63 given ($cmd) { |
71 |
64 when ("zsk") { exit create_zsk(@zones) }; |
|
65 #when ("ksk") { return create_ksk(@zones) }; |
|
66 #when ("check") { return check_zone(@zones) }; |
|
67 #when ("rm") { return rm_keys(@zones) }; |
|
68 default { die "not implemented\n" }; |
|
69 }; |
|
70 } |
72 |
71 |
73 sub rm_keys ($@) { |
72 sub rm_keys ($@) { |
74 |
73 |
75 # deletes all the keys were handed over -rm in argv |
74 # deletes all the keys were handed over -rm in argv |
76 my ($master_dir, @zone) = @_; |
75 my ($master_dir, @zone) = @_; |
107 |
106 |
108 if ($ep == 1) { |
107 if ($ep == 1) { |
109 print " * $zone: removed key-set\n"; |
108 print " * $zone: removed key-set\n"; |
110 } |
109 } |
111 |
110 |
112 open(my $old, "$zpf/$zone") or die "$zpf/$zone: $!\n"; |
111 open(my $old, "$zpf/$zone") or die "$zpf/$zone: $!\n"; |
113 my $fh = File::Temp->new(DIR => $zpf) or die "Can't create tmpfile: $!\n"; |
112 my $fh = File::Temp->new(DIR => $zpf) |
114 print $fh grep { not /^\s*\$INCLUDE.*"K$zone.*\.key"/i } <$old>; |
113 or die "Can't create tmpfile: $!\n"; |
115 rename($fh->filename => "$zpf/$zone") |
114 print $fh grep { not /^\s*\$INCLUDE.*"K$zone.*\.key"/i } <$old>; |
116 or die "Can't rename " . $fh->filename . " to $zpf/$zone: $!\n"; |
115 rename($fh->filename => "$zpf/$zone") |
|
116 or die "Can't rename " . $fh->filename . " to $zpf/$zone: $!\n"; |
117 } |
117 } |
118 } |
118 } |
119 |
119 |
120 sub create_ksk ($@) { |
120 sub create_ksk ($@) { |
121 my ($master_dir, @zone) = @_; |
121 my ($master_dir, @zone) = @_; |
154 print "!! THE KSK must be published !! \n"; |
154 print "!! THE KSK must be published !! \n"; |
155 |
155 |
156 } |
156 } |
157 } |
157 } |
158 |
158 |
159 sub create_zsk ($@) { |
159 sub create_zsk (@) { |
160 my ($master_dir, @zone) = @_; |
160 my @zones = @_; |
161 my @index; |
161 |
162 my $keyname; |
162 my $keyname; |
163 |
163 |
164 for (@zone) { |
164 foreach my $zone (@zones) { |
165 my $zone = $_; |
165 my $dir = "$cf{master_dir}/$zone"; |
166 my $zpf = "$master_dir/$zone"; |
166 |
167 |
167 chomp($keyname = `cd $dir && dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`); |
168 $keyname = `cd $zpf && dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`; |
168 |
169 |
169 my @index; |
170 unless (-f "$zpf/.index.zsk") { |
170 open(my $idx, "+>>", "$dir/.index.zsk") or die "Can't open $dir/.index.zsk: $!\n"; |
171 @index = (); |
171 seek($idx, 0, 0); |
172 } |
172 chomp(@index = <$idx>); |
173 else { |
|
174 open(INDEX, "$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n"; |
|
175 @index = <INDEX>; |
|
176 close(INDEX); |
|
177 } |
|
178 |
173 |
179 push @index, $keyname; |
174 push @index, $keyname; |
180 if (@index > 2) { shift(@index); } |
175 shift @index if @index > 2; |
181 |
176 |
182 { |
177 truncate($idx, 0); |
183 my $fh = File::Temp->new(DIR => "$zpf") |
178 print $idx join "\n" => @index, ""; |
184 or die "Can't create tmpdir: $!\n"; |
179 close($idx); |
185 print $fh join "" => @index, ""; |
180 |
186 rename($fh->filename => "$zpf/.index.zsk") |
181 say "$zone: new ZSK $keyname"; |
187 or die "Can't rename " |
182 |
188 . $fh->filename |
183 open(my $kc, ">", "$dir/.keycounter") or die "$dir/.keycounter: $!\n"; |
189 . " to $zpf/.index.zsk: $!\n"; |
184 print $kc "0\n"; |
190 } |
185 close($kc); |
191 chomp($keyname); |
186 } |
192 print " * $zone: new ZSK $keyname\n"; |
187 } |
193 |
188 |
194 open(KC, ">$zpf/.keycounter") or die "$zpf/keycounter: $!\n"; |
189 sub check_zone ($@) { |
195 print KC "0"; |
|
196 close(KC); |
|
197 } |
|
198 } |
|
199 |
|
200 sub ck_zone ($@) { |
|
201 my ($master_dir, @zone) = @_; |
190 my ($master_dir, @zone) = @_; |
202 |
191 |
203 for (@zone) { |
192 for (@zone) { |
204 my $zone = $_; |
193 my $zone = $_; |
205 my $zpf = "$master_dir/$zone"; |
194 my $zpf = "$master_dir/$zone"; |