--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/dnssec-keytool Fri Dec 03 16:42:12 2010 +0100
@@ -0,0 +1,350 @@
+#!/usr/bin/perl -w
+
+use strict;
+use FindBin;
+
+sub del_double {
+ my %all;
+ grep { $all{$_} = 0 } @_;
+ return ( keys %all );
+}
+
+sub read_conf {
+ # liest die Konfiguration ein
+ my @configs = ( "$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf" );
+ our %config;
+
+ for ( grep {-f} @configs ) {
+ open( CONFIG, $_ ) or die "Can't open $_: $!\n";
+ }
+ unless ( seek( CONFIG, 0, 0 ) ) {
+ die "Can't open config (searched: @configs)\n";
+ }
+ while (<CONFIG>) {
+ chomp;
+ s/#.*//;
+ s/\t//g;
+ s/\s//g;
+
+ next unless length;
+ my ( $cname, $ccont ) = split( /\s*=\s*/, $_, 2 );
+ $config{$cname} = $ccont;
+ }
+ close(CONFIG);
+}
+
+sub read_argv {
+ # wertet argv aus oder gibt die hilfe aus
+ my $arg = shift @ARGV;
+ my $zone;
+ our $do;
+ our @zones;
+ our $master_dir;
+
+ if ( ! defined $arg ) {
+ print " usage: dnssec-keytool <option> zone\n";
+ print " -z erstellt einen neuen ZSK\n";
+ print " -k erstellt je einen neuen ZSK und KSK\n";
+ print " -rm loescht das Schluesselmaterial einer Zone\n";
+ print " -c erstellt bei existierenden ksk konfigurationsdateien\n";
+ print " fuer die dnstools, sowie einen neuen zsk\n";
+ print "\n";
+
+ exit;
+ }
+ elsif ($arg eq "-k") {$do = "ksk";}
+ elsif ($arg eq "-rm") {$do = "rm";}
+ elsif ($arg eq "-c") {$do = "ck";}
+ elsif ($arg eq "-z") {$do = "zsk";}
+ else {
+ print "keine gueltige Option.\n";
+ exit;
+ }
+
+ # prueft die zonen in argv ob es verwaltete zonen sind
+ for (@ARGV) {
+ chomp( $zone = `idn --quiet "$_"` );
+ if ( -e "$master_dir/$zone/$zone" ) {
+ push @zones, $zone;
+ }
+ }
+}
+
+sub rm_keys {
+ our @zones;
+ our $master_dir;
+ my $zone;
+ my @new_zone_content;
+ my @old_zone_content;
+
+ for (@zones) {
+ $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 (`ls $zpf/K$zone*`) {
+ chomp($_);
+ print "weg du scheissezwerg $_";
+ unlink ("$_");
+ }
+
+ if ($ep == 1) {
+ print " * $zone: schluesselmaterial entfernt\n";
+ }
+
+ open( ZONE, "$zpf/$zone" )
+ or die "$zpf/$zone: $!\n";
+ @old_zone_content = <ZONE>;
+ close(ZONE);
+
+ for (@old_zone_content) {
+ unless (m#\$INCLUDE.*\"K$zone.*\.key\"#) {
+ push @new_zone_content, $_;
+ }
+ }
+
+ open( ZONE, ">$zpf/$zone" ) or die "$zpf/$zone: $!\n";
+ print ZONE @new_zone_content;
+ close(ZONE);
+ }
+}
+
+sub creat_ksk {
+ our @zones;
+ our $master_dir;
+ my @index;
+ my $zone;
+ my $keyname;
+ my $zpf;
+
+ for (@zones) {
+ $zone = $_;
+ $zpf = "$master_dir/$zone";
+
+ chdir "$zpf" or die "$zpf: $!\n";
+ $keyname = `dnssec-keygen -a RSASHA1 -b 2048 -f KSK -n ZONE $zone`;
+
+ unless ( -f ".index.ksk" ) { @index = ();}
+ else {
+ open( INDEX, ".index.ksk" ) or die "$zpf/.index.ksk: $!\n";
+ @index = <INDEX>;
+ close(INDEX);
+ }
+
+ push @index, $keyname;
+ if ( @index > 2 ) { shift(@index);}
+
+ open( INDEX, ">.index.ksk" ) or die "$zpf/.index.ksk: $!\n";
+ print INDEX @index;
+ close(INDEX);
+
+ chomp($keyname);
+ print " * $zone: neuer KSK $keyname\n";
+
+
+ print "!! DER KSK muss der Chain of Trust veroeffentlicht werden !! \n";
+
+ }
+}
+
+sub creat_zsk {
+ our @zones;
+ our $master_dir;
+ my @index;
+ my $zone;
+ my $keyname;
+ my $zpf;
+
+ for (@zones) {
+ $zone = $_;
+ $zpf = "$master_dir/$zone";
+
+ chdir "$zpf" or die "$zpf: $!\n";
+ $keyname = `dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`;
+
+ unless ( -f ".index.zsk" ) { @index = ();}
+ else {
+ open( INDEX, ".index.zsk" ) or die "$zpf/.index.zsk: $!\n";
+ @index = <INDEX>;
+ close(INDEX);
+ }
+
+ push @index, $keyname;
+ if ( @index > 2 ) { shift(@index);}
+
+ open( INDEX, ">.index.zsk" ) or die "$zpf/.index.zsk: $!\n";
+ print INDEX @index;
+ close(INDEX);
+
+ chomp($keyname);
+ print " * $zone: neuer ZSK $keyname\n";
+
+ open( KC, ">.keycounter" ) or die "$zpf/keycounter: $!\n";
+ print KC "0";
+ close(KC);
+
+ }
+}
+
+sub ck_zone {
+ our @zones;
+ our $master_dir;
+ my $zone;
+
+ for (@zones) {
+ $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");
+ @content = <KEYFILE>;
+ close (KEYFILE);
+ for (@content) {
+ if (m#DNSKEY.257#) {
+ push @keylist, $keyfile;
+ }
+ }
+ }
+ }
+
+ open( INDEX, ">.index.ksk" ) or die "$zpf/.index.ksk: $!\n";
+ for (@keylist) {
+ s#\.key##;
+ print INDEX "$_\n";
+ }
+ close(INDEX);
+
+ print " * $zone: neue .index.ksk erzeugt\n";
+
+ if (-f "$zpf/.index.zsk") {
+ unlink ("$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n";
+ }
+ }
+}
+
+sub post_creat {
+ our @zones;
+ our $master_dir;
+
+ for (@zones) {
+ my $zone = $_;
+ `touch $master_dir/$zone/$zone`;
+
+ &kill_useless_keys($zone);
+ &key_to_zonefile($zone);
+ }
+
+}
+
+sub kill_useless_keys {
+ # die funktion loescht alle schluessel die nicht in der index.zsk
+ # der uebergebenen zone stehen
+ our $master_dir;
+ my $zone = $_[0];
+ 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>;
+
+ # kuerzt die schluessel-bezeichnung aus der indexdatei auf die id um sie
+ # besser vergleichen zu koennen.
+ for ( @keylist ) {
+ chomp;
+ s#K.*\+.*\+(.*)#$1#;
+ }
+
+ # prueft alle schluesseldateien (ksk, zsk) ob sie in der jeweiligen
+ # indexdatei beschrieben sind. wenn nicht werden sie geloescht.
+ for (`ls $master_dir/$zone/K*[key,private]`) {
+ 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: Schluessel $1 entfernt \n";
+ }
+ }
+ }
+}
+
+sub key_to_zonefile {
+ # die funktion fugt alle schluessel in eine zonedatei
+ our $master_dir;
+ my $zone = $_[0];
+ 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);
+}
+
+
+&read_conf;
+
+our %config;
+our $do; # arbeitsschritte aus argv
+our @zones; # liste der zonen in argv
+our $master_dir = $config{master_dir};
+our $bind_dir = $config{bind_dir};
+our $conf_dir = $config{zone_conf_dir};
+our $sign_alert_time = $config{sign_alert_time};
+our $indexzone = $config{indexzone};
+our $key_counter_end = $config{key_counter_end};
+our $ablauf_zeit = $config{abl_zeit};
+
+&read_argv;
+
+unless (@zones) {exit;} # beendet das programm, wurden keine
+ # gueltigen zonen uebergeben
+
+if ($do eq "rm") { &rm_keys; exit;}
+if ($do eq "ck") { &ck_zone;}
+if ($do eq "ksk") { &creat_ksk; }
+
+&creat_zsk;
+&post_creat;
+
+