diff -r 5578cb7933c1 -r d8fa60488868 bin/dnssec-keytool --- a/bin/dnssec-keytool Mon Jun 06 09:30:17 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,349 +0,0 @@ -#! /usr/bin/perl - -use v5.10; -use warnings; -use strict; -use File::Temp; -use Getopt::Long; -use Pod::Usage; -use File::Basename; -use Net::LibIDN qw(:all); -use if $ENV{DEBUG} => "Smart::Comments"; -use DNStools::Config qw(get_config); - -my $ME = basename $0; - -sub rm_keys($@); -sub check_zone($@); -sub create_ksk($@); -sub create_zsk(@); -sub post_create($@); - -my $CHARSET = "UTF-8"; -my %cf; - -MAIN: { - - %cf = get_config(); - my $cmd; - - system("command -v dnssec-keygen &>/dev/null"); - die "$ME: command 'dnssec-keygen' not found in $ENV{PATH}\n" if $?; - - GetOptions( - "zsk" => sub { push @$cmd => "zsk" }, - "ksk" => sub { push @$cmd => "ksk" }, - "rm" => sub { push @$cmd => "rm" }, - "check" => sub { $cmd = "check" }, - "h|help" => sub { pod2usage(-exit => 0, -verbose => 1) }, - "m|man" => sub { - pod2usage( - -exit => 0, - # "system('perldoc -V &>/dev/null')" appears shorter, but may not - # do what you expect ( it still returns 0 on debian squeeze with - # dash as system shell even if cannot find the command in $PATH) - -noperldoc => system('perldoc -V >/dev/null 2>&1'), - -verbose => 2 - ); - }, - ) - and @ARGV - and @$cmd == 1 - and $cmd = $cmd->[0] - or pod2usage; - - # checks the zones in argv if they're managed ones - my @zones; - foreach my $utf8zone (@ARGV) { - my $zone = idn_to_ascii($utf8zone, $CHARSET); - - die "zone $zone is not managed\n" - if not -f "$cf{master_dir}/$zone/$zone"; - - push @zones, $zone; - } - - 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) }; - default { die "not implemented\n" }; - }; -} - -sub rm_keys ($@) { - - # deletes all the keys were handed over -rm in argv - my ($master_dir, @zone) = @_; - - for (@zone) { - my $zone = $_; - - my $zpf = "$master_dir/$zone"; - my $ep = 0; - - if (-e "$zpf/$zone.signed") { - unlink "$zpf/$zone.signed" and $ep = 1; - } - if (-e "$zpf/.keycounter") { - unlink "$zpf/.keycounter" and $ep = 1; - } - if (-e "$zpf/.index.ksk") { - unlink "$zpf/.index.ksk" and $ep = 1; - } - if (-e "$zpf/.index.zsk") { - unlink "$zpf/.index.zsk" and $ep = 1; - } - if (-e "$zpf/dsset-$zone.") { - unlink "$zpf/dsset-$zone." and $ep = 1; - } - if (-e "$zpf/keyset-$zone.") { - unlink "$zpf/keyset-$zone." and $ep = 1; - } - - for (glob("$zpf/K$zone*")) { - chomp($_); - unlink("$_"); - } - - if ($ep == 1) { - print " * $zone: removed key-set\n"; - } - - open(my $old, "$zpf/$zone") or die "$zpf/$zone: $!\n"; - my $fh = File::Temp->new(DIR => $zpf) - or die "Can't create tmpfile: $!\n"; - print $fh grep { not /^\s*\$INCLUDE.*"K$zone.*\.key"/i } <$old>; - rename($fh->filename => "$zpf/$zone") - or die "Can't rename " . $fh->filename . " to $zpf/$zone: $!\n"; - } -} - -sub create_ksk ($@) { - my ($master_dir, @zone) = @_; - my @index; - my $keyname; - - for (@zone) { - my $zone = $_; - my $zpf = "$master_dir/$zone"; - - $keyname = - `cd $zpf && dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE $zone`; - - unless (-f "$zpf/.index.ksk") { @index = (); } - else { - open(INDEX, "$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n"; - @index = ; - close(INDEX); - } - - 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"; - } - - chomp($keyname); - print " * $zone: new KSK $keyname\n"; - print "!! THE KSK must be published !! \n"; - - } -} - -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 check_zone ($@) { - my ($master_dir, @zone) = @_; - - for (@zone) { - my $zone = $_; - my $zpf = "$master_dir/$zone"; - my $keyfile; - my @content; - my @keylist; - - for (<$zpf/*>) { - if (m#(K$zone.*\.key)#) { - $keyfile = $1; - open(KEYFILE, "<", "$zpf/$keyfile") - or die "$zpf/$keyfile: $!\n"; - @content = ; - close(KEYFILE); - for (@content) { - if (m#DNSKEY.257#) { - push @keylist, $keyfile; - } - } - } - } - - open(INDEX, ">$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n"; - for (@keylist) { - s#\.key##; - print INDEX "$_\n"; - } - close(INDEX); - - print " * $zone: new .index.ksk created\n"; - if (-f "$zpf/.index.zsk") { - unlink("$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n"; - } - } -} - -sub post_create ($@) { - my ($master_dir, @zone) = @_; - for (@zone) { - my $zone = $_; - `touch $master_dir/$zone/$zone`; - &kill_useless_keys($zone, $master_dir); - &key_to_zonefile($zone, $master_dir); - } -} - -sub kill_useless_keys ($@) { - - # the function deletes all keys that are not available in the zone - - my $zone = $_[0]; - my $master_dir = $_[1]; - my @keylist = (); - my $zpf = "$master_dir/$zone"; - - open(INDEX, "<$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n"; - @keylist = ; - close(INDEX); - open(INDEX, "<$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n"; - push @keylist, ; - - # shortened the key name from the index file on the id in order to - # be able to compare - for (@keylist) { - chomp; - s#K.*\+.*\+(.*)#$1#; - } - - # reviewed every key file (KSK, ZSK), whether they are described in - # the respective index file. if not they will be deleted. - for (glob("$master_dir/$zone/K*")) { - chomp; - my $file = $_; - my $rm_count = 1; - my $keyname; - for (@keylist) { - if ($file =~ /$_/) { $rm_count = 0; } - } - if ($rm_count == 1) { - unlink "$file"; - if ($file =~ /$zpf\/(.*\.key)/) { - print " * $zone: Key $1 removed \n"; - } - } - } -} - -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); - - for (@old_content) { - unless (m#INCLUDE.*key#) { push @new_content, $_; } - } - - 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); -} - -__END__ - -=pod - -=head1 NAME - - dnssec-keytool - key management - -=head1 SYNOPSIS - - dnssec-keytool {--zsk|--ksk|--rm|--check} zone... - -=head1 DESCRIPTION - -Blabla. - -=head1 OPTIONS - -=over - -=item B<--zsk> - -Create a new ZSK for the zones. - -=item B<--ksk> - -Create a new KSK for the zones. - -=item B<--rm> - -Remote all key material from the zones. - -=item B<--check> - -??? - -=back - -=cut - -# vim:sts=4 sw=4 aw ai sm: