# HG changeset patch # User Matthias Förste # Date 1309179990 -7200 # Node ID 69856eb1e8268bb03f26692f86636145f041d636 # Parent 43e9d618af4303add63342c50f8db4b75a3311ab --ksk should work now diff -r 43e9d618af43 -r 69856eb1e826 sbin/dnssec-keytool --- a/sbin/dnssec-keytool Fri Jun 10 09:12:18 2011 +0200 +++ b/sbin/dnssec-keytool Mon Jun 27 15:06:30 2011 +0200 @@ -15,7 +15,8 @@ sub rm_keys($@); sub check_zone($@); -sub create_ksk($@); +sub create_key($@); +sub create_ksk(@); sub create_zsk(@); sub post_create($@); @@ -65,9 +66,9 @@ given ($cmd) { when ("zsk") { exit create_zsk(@zones) }; - #when ("ksk") { return create_ksk(@zones) }; - #when ("check") { return check_zone(@zones) }; - #when ("rm") { return rm_keys(@zones) }; + when ("ksk") { exit create_ksk(@zones) }; + #when ("check") { exit check_zone(@zones) }; + #when ("rm") { exit rm_keys(@zones) }; default { die "not implemented\n" }; }; } @@ -120,74 +121,62 @@ } } -sub create_ksk ($@) { - my ($master_dir, @zone) = @_; - my @index; - my $keyname; +sub create_key ($@) { - for (@zone) { - my $zone = $_; - my $zpf = "$master_dir/$zone"; - - $keyname = - `cd $zpf && dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE $zone`; + my ($type, @zones) = @_; + my $master_dir = "$cf{master_dir}"; - unless (-f "$zpf/.index.ksk") { @index = (); } - else { - open(INDEX, "$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n"; - @index = ; - close(INDEX); - } + my $args = { - push @index, $keyname; - if (@index > 2) { shift(@index); } - - { - my $fh = File::Temp->new(DIR => "$zpf") - or die "Can't create tmpdir: $!\n"; - print $fh join "" => @index, ""; - rename($fh->filename => "$zpf/.index.ksk") - or die "Can't rename " - . $fh->filename - . " to $zpf/.index.ksk: $!\n"; + ksk => { + cmd => 'cd %s && dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE %s' + }, + zsk => { + cmd => 'cd %s && dnssec-keygen -a RSASHA1 -b 512 -n ZONE %s' } - chomp($keyname); - print " * $zone: new KSK $keyname\n"; - print "!! THE KSK must be published !! \n"; + }; + + die "Invalid type $type" unless defined $args->{$type}; + + for my $zone (@zones) { + + my (@index, $keyname, $idx); + my $dir = "$master_dir/$zone"; + my $cmd = sprintf $args->{$type}->{cmd}, $dir, $zone; + + chomp($keyname = qx/$cmd/); + die "Key generation failed! (output was: '$keyname')" unless $keyname =~ /^K\Q$zone\E\.?\+\d{3}\+\d{5}$/; + + open $idx, '+>>', "$dir/.index.$type" or die "Can't open $dir/.index.$type: $!\n"; + seek $idx, 0 ,0 or die "Cant' seek: $!"; + chomp (@index = <$idx>); + + push @index, $keyname; + # TODO: this should be part of the key removal procedure, no? + # shift @index if @index > 2; + + seek $idx, 0 ,0 or die "Cant' seek: $!"; + truncate $idx, 0 or die "Can't truncate: $!"; + print $idx join "\n" => @index, ''; + close $idx; + + say "$zone: new ", uc $type, " $keyname"; + + key_to_zonefile($keyname); + + if (lc $type eq 'zsk') { + open my $kc, '>', "$dir/.keycounter" or die "Can't open $dir/.keycounter: $!\n"; + print $kc "0\n"; + close $kc; + } } + } -sub create_zsk (@) { - my @zones = @_; - - my $keyname; - - foreach my $zone (@zones) { - my $dir = "$cf{master_dir}/$zone"; - - chomp($keyname = `cd $dir && dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`); - - my @index; - open(my $idx, "+>>", "$dir/.index.zsk") or die "Can't open $dir/.index.zsk: $!\n"; - seek($idx, 0, 0); - chomp(@index = <$idx>); - - push @index, $keyname; - shift @index if @index > 2; - - truncate($idx, 0); - print $idx join "\n" => @index, ""; - close($idx); - - say "$zone: new ZSK $keyname"; - - open(my $kc, ">", "$dir/.keycounter") or die "$dir/.keycounter: $!\n"; - print $kc "0\n"; - close($kc); - } -} +sub create_ksk (@) { return create_key 'ksk', @_; } +sub create_zsk (@) { return create_key 'zsk', @_; } sub check_zone ($@) { my ($master_dir, @zone) = @_; @@ -279,31 +268,26 @@ } } -sub key_to_zonefile ($@) { +sub key_to_zonefile (@) { - # the function added all keys to the indexfile - my $zone = $_[0]; - my $master_dir = $_[1]; - my $zpf = "$master_dir/$zone"; - my @old_content; - my @new_content = (); - - open(ZONEFILE, "<$zpf/$zone"); - @old_content = ; - close(ZONEFILE); + (my ($keyname) = @_); + $keyname =~ /^K(.*)\.\+\d{3}\+\d{5}$/; + my $zone = $1 or die "Can't determine zone from key name '$keyname'\n"; + my $zf = "$cf{master_dir}/$zone/$zone"; + my (@lines, $tmp); - for (@old_content) { - unless (m#INCLUDE.*key#) { push @new_content, $_; } - } + open OLD, '<', $zf or die "Can't open $zf: $!\n"; + chomp (@lines = ); + close OLD; + + return if grep /^\s*\$include\s+("?)\Q$keyname\E\.key\1$/i, @lines; - for (<$zpf/*>) { - if (m#(.*\/)(K.*\.key)#) { - push @new_content, "\$INCLUDE \"$2\"\n"; - } - } - open(ZONEFILE, ">$zpf/$zone") or die "$zpf/$zone: $!\n"; - print ZONEFILE @new_content; - close(ZONEFILE); + $tmp = File::Temp->new(UNLINK => 0) or die "Can't create temporary file\n"; + print $tmp join "\n", @lines, qq(\$INCLUDE "$keyname.key"\n); + close $tmp; + + rename $tmp => $zf or die "Can't rename '$tmp' => '$zf': $!"; + } __END__ @@ -328,11 +312,11 @@ =item B<--zsk> -Create a new ZSK for the zones. +Create a new ZSK for the zones and include the DNSKEY record for it in the respective zone. =item B<--ksk> -Create a new KSK for the zones. +Create a new KSK for the zones and include the DNSKEY record for it in the respective zone. =item B<--rm>