--- 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 = <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 = <KEYFILE>;
- 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 = <INDEX>;
- close(INDEX);
- open(INDEX, "<$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n";
- push @keylist, <INDEX>;
-
- # 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 = <ZONEFILE>;
- 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: