118 rename($fh->filename => "$zpf/$zone") |
119 rename($fh->filename => "$zpf/$zone") |
119 or die "Can't rename " . $fh->filename . " to $zpf/$zone: $!\n"; |
120 or die "Can't rename " . $fh->filename . " to $zpf/$zone: $!\n"; |
120 } |
121 } |
121 } |
122 } |
122 |
123 |
123 sub create_ksk ($@) { |
124 sub create_key ($@) { |
124 my ($master_dir, @zone) = @_; |
125 |
125 my @index; |
126 my ($type, @zones) = @_; |
126 my $keyname; |
127 my $master_dir = "$cf{master_dir}"; |
127 |
128 |
128 for (@zone) { |
129 my $args = { |
129 my $zone = $_; |
130 |
130 my $zpf = "$master_dir/$zone"; |
131 ksk => { |
131 |
132 cmd => 'cd %s && dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE %s' |
132 $keyname = |
133 }, |
133 `cd $zpf && dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE $zone`; |
134 zsk => { |
134 |
135 cmd => 'cd %s && dnssec-keygen -a RSASHA1 -b 512 -n ZONE %s' |
135 unless (-f "$zpf/.index.ksk") { @index = (); } |
136 } |
136 else { |
137 |
137 open(INDEX, "$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n"; |
138 }; |
138 @index = <INDEX>; |
139 |
139 close(INDEX); |
140 die "Invalid type $type" unless defined $args->{$type}; |
140 } |
141 |
|
142 for my $zone (@zones) { |
|
143 |
|
144 my (@index, $keyname, $idx); |
|
145 my $dir = "$master_dir/$zone"; |
|
146 my $cmd = sprintf $args->{$type}->{cmd}, $dir, $zone; |
|
147 |
|
148 chomp($keyname = qx/$cmd/); |
|
149 die "Key generation failed! (output was: '$keyname')" unless $keyname =~ /^K\Q$zone\E\.?\+\d{3}\+\d{5}$/; |
|
150 |
|
151 open $idx, '+>>', "$dir/.index.$type" or die "Can't open $dir/.index.$type: $!\n"; |
|
152 seek $idx, 0 ,0 or die "Cant' seek: $!"; |
|
153 chomp (@index = <$idx>); |
141 |
154 |
142 push @index, $keyname; |
155 push @index, $keyname; |
143 if (@index > 2) { shift(@index); } |
156 # TODO: this should be part of the key removal procedure, no? |
144 |
157 # shift @index if @index > 2; |
145 { |
158 |
146 my $fh = File::Temp->new(DIR => "$zpf") |
159 seek $idx, 0 ,0 or die "Cant' seek: $!"; |
147 or die "Can't create tmpdir: $!\n"; |
160 truncate $idx, 0 or die "Can't truncate: $!"; |
148 print $fh join "" => @index, ""; |
161 print $idx join "\n" => @index, ''; |
149 rename($fh->filename => "$zpf/.index.ksk") |
162 close $idx; |
150 or die "Can't rename " |
163 |
151 . $fh->filename |
164 say "$zone: new ", uc $type, " $keyname"; |
152 . " to $zpf/.index.ksk: $!\n"; |
165 |
153 } |
166 key_to_zonefile($keyname); |
154 |
167 |
155 chomp($keyname); |
168 if (lc $type eq 'zsk') { |
156 print " * $zone: new KSK $keyname\n"; |
169 open my $kc, '>', "$dir/.keycounter" or die "Can't open $dir/.keycounter: $!\n"; |
157 print "!! THE KSK must be published !! \n"; |
170 print $kc "0\n"; |
158 |
171 close $kc; |
159 } |
172 } |
160 } |
173 |
161 |
174 } |
162 sub create_zsk (@) { |
175 |
163 my @zones = @_; |
176 } |
164 |
177 |
165 my $keyname; |
178 sub create_ksk (@) { return create_key 'ksk', @_; } |
166 |
179 sub create_zsk (@) { return create_key 'zsk', @_; } |
167 foreach my $zone (@zones) { |
|
168 my $dir = "$cf{master_dir}/$zone"; |
|
169 |
|
170 chomp($keyname = `cd $dir && dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`); |
|
171 |
|
172 my @index; |
|
173 open(my $idx, "+>>", "$dir/.index.zsk") or die "Can't open $dir/.index.zsk: $!\n"; |
|
174 seek($idx, 0, 0); |
|
175 chomp(@index = <$idx>); |
|
176 |
|
177 push @index, $keyname; |
|
178 shift @index if @index > 2; |
|
179 |
|
180 truncate($idx, 0); |
|
181 print $idx join "\n" => @index, ""; |
|
182 close($idx); |
|
183 |
|
184 say "$zone: new ZSK $keyname"; |
|
185 |
|
186 open(my $kc, ">", "$dir/.keycounter") or die "$dir/.keycounter: $!\n"; |
|
187 print $kc "0\n"; |
|
188 close($kc); |
|
189 } |
|
190 } |
|
191 |
180 |
192 sub check_zone ($@) { |
181 sub check_zone ($@) { |
193 my ($master_dir, @zone) = @_; |
182 my ($master_dir, @zone) = @_; |
194 |
183 |
195 for (@zone) { |
184 for (@zone) { |
277 } |
266 } |
278 } |
267 } |
279 } |
268 } |
280 } |
269 } |
281 |
270 |
282 sub key_to_zonefile ($@) { |
271 sub key_to_zonefile (@) { |
283 |
272 |
284 # the function added all keys to the indexfile |
273 (my ($keyname) = @_); |
285 my $zone = $_[0]; |
274 $keyname =~ /^K(.*)\.\+\d{3}\+\d{5}$/; |
286 my $master_dir = $_[1]; |
275 my $zone = $1 or die "Can't determine zone from key name '$keyname'\n"; |
287 my $zpf = "$master_dir/$zone"; |
276 my $zf = "$cf{master_dir}/$zone/$zone"; |
288 my @old_content; |
277 my (@lines, $tmp); |
289 my @new_content = (); |
278 |
290 |
279 open OLD, '<', $zf or die "Can't open $zf: $!\n"; |
291 open(ZONEFILE, "<$zpf/$zone"); |
280 chomp (@lines = <OLD>); |
292 @old_content = <ZONEFILE>; |
281 close OLD; |
293 close(ZONEFILE); |
282 |
294 |
283 return if grep /^\s*\$include\s+("?)\Q$keyname\E\.key\1$/i, @lines; |
295 for (@old_content) { |
284 |
296 unless (m#INCLUDE.*key#) { push @new_content, $_; } |
285 $tmp = File::Temp->new(UNLINK => 0) or die "Can't create temporary file\n"; |
297 } |
286 print $tmp join "\n", @lines, qq(\$INCLUDE "$keyname.key"\n); |
298 |
287 close $tmp; |
299 for (<$zpf/*>) { |
288 |
300 if (m#(.*\/)(K.*\.key)#) { |
289 rename $tmp => $zf or die "Can't rename '$tmp' => '$zf': $!"; |
301 push @new_content, "\$INCLUDE \"$2\"\n"; |
290 |
302 } |
|
303 } |
|
304 open(ZONEFILE, ">$zpf/$zone") or die "$zpf/$zone: $!\n"; |
|
305 print ZONEFILE @new_content; |
|
306 close(ZONEFILE); |
|
307 } |
291 } |
308 |
292 |
309 __END__ |
293 __END__ |
310 |
294 |
311 =pod |
295 =pod |