update-serial.pl
branchhs12
changeset 41 3c10c45c6a59
parent 39 8b46e7c48995
child 46 de6761ce0d5b
child 48 04cefcf6f4ac
equal deleted inserted replaced
40:512e12c40389 41:3c10c45c6a59
     4 use warnings;
     4 use warnings;
     5 use FindBin;
     5 use FindBin;
     6 use File::Basename;
     6 use File::Basename;
     7 
     7 
     8 sub del_double {
     8 sub del_double {
       
     9 
     9     # entfernt doppelte eintraege in einer liste
    10     # entfernt doppelte eintraege in einer liste
    10     my %all;
    11     my %all;
    11     grep { $all{$_} = 0 } @_;
    12     grep { $all{$_} = 0 } @_;
    12     return ( keys %all );
    13     return (keys %all);
    13 }
    14 }
    14 
    15 
    15 sub read_conf {
    16 sub read_conf {
       
    17 
    16     # liest die Konfiguration ein
    18     # liest die Konfiguration ein
    17     my @configs = ( "$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf" );
    19     my @configs = ("$FindBin::Bin/dnstools.conf", "/etc/dnstools.conf");
    18     our %config;
    20     our %config;
    19 
    21 
    20     for ( grep {-f} @configs ) {
    22     for (grep { -f } @configs) {
    21         open( CONFIG, $_ ) or die "Can't open $_: $!\n";
    23         open(CONFIG, $_) or die "Can't open $_: $!\n";
    22     }
    24     }
    23     unless ( seek( CONFIG, 0, 0 ) ) {
    25     unless (seek(CONFIG, 0, 0)) {
    24         die "Can't open config (searched: @configs)\n";
    26         die "Can't open config (searched: @configs)\n";
    25     }
    27     }
    26     while (<CONFIG>) {
    28     while (<CONFIG>) {
    27         chomp;
    29         chomp;
    28         s/#.*//;
    30         s/#.*//;
    29         s/\t//g;
    31         s/\t//g;
    30         s/\s//g;
    32         s/\s//g;
    31 
    33 
    32         next unless length;
    34         next unless length;
    33         my ( $cname, $ccont ) = split( /\s*=\s*/, $_, 2 );
    35         my ($cname, $ccont) = split(/\s*=\s*/, $_, 2);
    34         $config{$cname} = $ccont;
    36         $config{$cname} = $ccont;
    35     }
    37     }
    36     close(CONFIG);
    38     close(CONFIG);
    37 }
    39 }
    38 
    40 
    39 sub add_argv {
    41 sub add_argv {
       
    42 
    40     # prueft ob zonen aus ARGV verwaltete zonen sind
    43     # prueft ob zonen aus ARGV verwaltete zonen sind
    41     # und fuegt sie, falls ja in die liste @new_serial ein
    44     # und fuegt sie, falls ja in die liste @new_serial ein
    42     our @new_serial;
    45     our @new_serial;
    43     our $master_dir;
    46     our $master_dir;
    44     my $zone;
    47     my $zone;
    45     
    48 
    46     for (@ARGV) {
    49     for (@ARGV) {
    47         chomp( $zone = `idn --quiet "$_"` );
    50         chomp($zone = `idn --quiet "$_"`);
    48         if ( -e "$master_dir/$zone/$zone" ) {
    51         if (-e "$master_dir/$zone/$zone") {
    49             push @new_serial, $zone;
    52             push @new_serial, $zone;
    50         }
    53         }
    51     }
    54     }
    52 }
    55 }
    53 
    56 
    58     for (<$master_dir/*>) {
    61     for (<$master_dir/*>) {
    59         my $zone = basename($_);
    62         my $zone = basename($_);
    60 
    63 
    61         if (-e "$master_dir/$zone/.stamp") {
    64         if (-e "$master_dir/$zone/.stamp") {
    62             my $stamptime = (-M "$master_dir/$zone/.stamp");
    65             my $stamptime = (-M "$master_dir/$zone/.stamp");
    63             my $filetime = (-M "$master_dir/$zone/$zone");
    66             my $filetime  = (-M "$master_dir/$zone/$zone");
    64             if ($stamptime > $filetime) {
    67             if ($stamptime > $filetime) {
    65                 push @new_serial, $zone;
    68                 push @new_serial, $zone;
    66                 print " * $zone: zonedatei wurde geaendert\n";
    69                 print " * $zone: zonedatei wurde geaendert\n";
    67             }
    70             }
    68         }
    71         }
    69         else {
    72         else {
    70             print " * $zone: keine .stamp-datei gefunden\n"; # NOCH IN NEW_SERIAL PUSHEN
    73             print " * $zone: keine .stamp-datei gefunden\n"
       
    74               ;    # NOCH IN NEW_SERIAL PUSHEN
    71             push @new_serial, $zone;
    75             push @new_serial, $zone;
    72         }
    76         }
    73     }
    77     }
    74 
    78 
    75 }
    79 }
    76 
    80 
    77 sub sign_end {
    81 sub sign_end {
    78     our $sign_alert_time;  # die zeit zwischen dem ende und der neuen
    82     our $sign_alert_time;    # die zeit zwischen dem ende und der neuen
    79                            # signierung (siehe externe konfiguration)
    83                              # signierung (siehe externe konfiguration)
    80     our $master_dir;
    84     our $master_dir;
    81     our @new_serial;
    85     our @new_serial;
    82     
    86 
    83     # erzeugt $time (die zeit ab der neu signiert werden soll)
    87     # erzeugt $time (die zeit ab der neu signiert werden soll)
    84     chomp( my $unixtime = `date +%s` );
    88     chomp(my $unixtime = `date +%s`);
    85     $unixtime = $unixtime + ( 3600 * $sign_alert_time );
    89     $unixtime = $unixtime + (3600 * $sign_alert_time);
    86     my $time = `date -d \@$unixtime +%Y%m%d%H`;
    90     my $time = `date -d \@$unixtime +%Y%m%d%H`;
    87     
    91 
    88     ## vergleicht fuer alle zonen im ordner $master_dir mit einer
    92     ## vergleicht fuer alle zonen im ordner $master_dir mit einer
    89     ## <zone>.signed-datei den zeitpunkt in $time mit dem ablaufdatum der
    93     ## <zone>.signed-datei den zeitpunkt in $time mit dem ablaufdatum der
    90     ## signatur, welcher aus der datei <zone>.signed ausgelesen wird.
    94     ## signatur, welcher aus der datei <zone>.signed ausgelesen wird.
    91     for (<$master_dir/*>) {
    95     for (<$master_dir/*>) {
    92         s#($master_dir/)(.*)#$2#;
    96         s#($master_dir/)(.*)#$2#;
    93         my $zone = $_;
    97         my $zone = $_;
    94     
    98 
    95         if ( -e "$master_dir/$zone/$zone.signed" ) {
    99         if (-e "$master_dir/$zone/$zone.signed") {
    96             open( ZONE, "$master_dir/$zone/$zone.signed" );
   100             open(ZONE, "$master_dir/$zone/$zone.signed");
    97             my @zone_sig_content = <ZONE>;
   101             my @zone_sig_content = <ZONE>;
    98             close(ZONE);
   102             close(ZONE);
    99             
   103 
   100             for (@zone_sig_content) {
   104             for (@zone_sig_content) {
   101                 if (m#SOA.*[0-9]{14}#) {
   105                 if (m#SOA.*[0-9]{14}#) {
   102                     s#.*([0-9]{10})([0-9]{4}).*#$1#;
   106                     s#.*([0-9]{10})([0-9]{4}).*#$1#;
   103                     if ( $_ < $time ) {
   107                     if ($_ < $time) {
   104                         push @new_serial, $zone;
   108                         push @new_serial, $zone;
   105                     }
   109                     }
   106                 }
   110                 }
   107             }
   111             }
   108         }
   112         }
   109     }
   113     }
   110 }
   114 }
   111 
   115 
   112 sub sign_zone {
   116 sub sign_zone {
       
   117 
   113     # signiert die zonen und erhoeht den wert in der keycounter-datei
   118     # signiert die zonen und erhoeht den wert in der keycounter-datei
   114     our @new_serial;
   119     our @new_serial;
   115     our $master_dir;
   120     our $master_dir;
   116     my $zone;
   121     my $zone;
   117     my $kc;
   122     my $kc;
   118 
   123 
   119     for ( &del_double( @new_serial ) ) {
   124     for (&del_double(@new_serial)) {
   120         $zone = $_;
   125         $zone = $_;
   121 
   126 
   122         unless (-e "$master_dir/$zone/.index.zsk") {
   127         unless (-e "$master_dir/$zone/.index.zsk") {
   123             next;
   128             next;
   124         }
   129         }
   127         if (`dnssec-signzone $zone 2>/dev/null`) {
   132         if (`dnssec-signzone $zone 2>/dev/null`) {
   128             print " * $zone neu signiert \n";
   133             print " * $zone neu signiert \n";
   129 
   134 
   130             # erhoeht den keycounter
   135             # erhoeht den keycounter
   131             if ("$master_dir/$zone/.keycounter") {
   136             if ("$master_dir/$zone/.keycounter") {
   132                 open( KC, "$master_dir/$zone/.keycounter" );
   137                 open(KC, "$master_dir/$zone/.keycounter");
   133                 $kc = <KC>;
   138                 $kc = <KC>;
   134                 close(KC);
   139                 close(KC);
   135                 $kc += 1;
   140                 $kc += 1;
   136             }
   141             }
   137             else {
   142             else {
   138                 $kc = 1;
   143                 $kc = 1;
   139             }
   144             }
   140             open( KC, ">$master_dir/$zone/.keycounter" );
   145             open(KC, ">$master_dir/$zone/.keycounter");
   141             print KC $kc;
   146             print KC $kc;
   142             close(KC);
   147             close(KC);
   143         }
   148         }
   144         else { print "$zone konnte nicht signiert werden \n"; }
   149         else { print "$zone konnte nicht signiert werden \n"; }
   145     }
   150     }
   146 }
   151 }
   147 
   152 
   148 sub update_serial {
   153 sub update_serial {
   149     our $master_dir;
   154     our $master_dir;
   150     our @new_serial;
   155     our @new_serial;
   151     chomp (my  $date = `date +%Y%m%d`);
   156     chomp(my $date = `date +%Y%m%d`);
   152     my @new_content;
   157     my @new_content;
   153     my  $sdate;
   158     my $sdate;
   154     my  $scount;
   159     my $scount;
   155     my  $serial;
   160     my $serial;
   156 
   161 
   157     for ( &del_double( @new_serial ) ) {
   162     for (&del_double(@new_serial)) {
       
   163 
   158         # erhoeht den serial
   164         # erhoeht den serial
   159         my $zone = $_;
   165         my $zone        = $_;
   160         my $file = "$master_dir/$zone/$zone";
   166         my $file        = "$master_dir/$zone/$zone";
   161         my @new_content = ();
   167         my @new_content = ();
   162  
   168 
   163         open (SER, "<$file") or die "$file: $!\n";
   169         open(SER, "<$file") or die "$file: $!\n";
   164         for (<SER>) {
   170         for (<SER>) {
   165             if (/^\s+(\d+)(\d{2})\s*;\s*serial/i) {
   171             if (/^\s+(\d+)(\d{2})\s*;\s*serial/i) {
   166                 $sdate  = $1;
   172                 $sdate  = $1;
   167                 $scount = $2;
   173                 $scount = $2;
   168                 $serial = "$sdate$scount";
   174                 $serial = "$sdate$scount";
   169                 if ( $date eq $sdate ) {
   175                 if ($date eq $sdate) {
   170                     $scount++;
   176                     $scount++;
   171                 }
   177                 }
   172                 else {
   178                 else {
   173                     $sdate = $date;
   179                     $sdate  = $date;
   174                     $scount = "00";
   180                     $scount = "00";
   175                 }
   181                 }
   176             }
   182             }
   177             if ($serial) {
   183             if ($serial) {
   178                 s/$serial/$sdate$scount/;
   184                 s/$serial/$sdate$scount/;
   179             }
   185             }
   180             push @new_content, $_;
   186             push @new_content, $_;
   181         }
   187         }
   182         close (SER);
   188         close(SER);
   183 
   189 
   184         open (RES, ">$file") or die "$file: $!\n";
   190         open(RES, ">$file") or die "$file: $!\n";
   185         print RES @new_content;
   191         print RES @new_content;
   186         close (RES);
   192         close(RES);
   187         print " * $zone: serial erhoeht \n";
   193         print " * $zone: serial erhoeht \n";
   188 
   194 
   189         open(STAMP, ">$master_dir/$zone/.stamp") or die "$master_dir/$zone/.stamp: $!\n";
   195         open(STAMP, ">$master_dir/$zone/.stamp")
       
   196           or die "$master_dir/$zone/.stamp: $!\n";
   190         close(STAMP);
   197         close(STAMP);
   191         print " * $zone: stamp aktualisiert \n";
   198         print " * $zone: stamp aktualisiert \n";
   192     }
   199     }
   193 }
   200 }
   194 
   201 
   195 sub mk_zone_conf {
   202 sub mk_zone_conf {
       
   203 
   196     # erzeugt eine named.conf-datei aus den entsprechenden vorlagen.
   204     # erzeugt eine named.conf-datei aus den entsprechenden vorlagen.
   197     our $bind_dir;
   205     our $bind_dir;
   198     our $conf_dir;
   206     our $conf_dir;
   199 
   207 
   200     open( TO, ">$bind_dir/named.conf.zones" )
   208     open(TO, ">$bind_dir/named.conf.zones")
   201         or die "$bind_dir/named.conf.zones: $!\n";
   209       or die "$bind_dir/named.conf.zones: $!\n";
   202     while (<$conf_dir/*>) {
   210     while (<$conf_dir/*>) {
   203         open( FROM, "$_" ) or die "$_: $! \n";
   211         open(FROM, "$_") or die "$_: $! \n";
   204         print TO <FROM>;
   212         print TO <FROM>;
   205         close(FROM);
   213         close(FROM);
   206     }
   214     }
   207     close(TO);
   215     close(TO);
   208     print "** zonekonfiguration erzeugt\n";
   216     print "** zonekonfiguration erzeugt\n";
   209 }
   217 }
   210 
   218 
   211 sub update_index {
   219 sub update_index {
       
   220 
   212     # aktualisiert die indexzone;
   221     # aktualisiert die indexzone;
   213     our @new_serial;
   222     our @new_serial;
   214     our $indexzone;
   223     our $indexzone;
   215     our $master_dir;
   224     our $master_dir;
   216     my @iz_content_old;
   225     my @iz_content_old;
   217     my @iz_content_new;
   226     my @iz_content_new;
   218 
   227 
   219     open (INDEXZONE, "$master_dir/$indexzone/$indexzone")
   228     open(INDEXZONE, "$master_dir/$indexzone/$indexzone")
   220         or die "$master_dir/$indexzone/$indexzone: $!\n";
   229       or die "$master_dir/$indexzone/$indexzone: $!\n";
   221     @iz_content_old = <INDEXZONE>;
   230     @iz_content_old = <INDEXZONE>;
   222     close (INDEXZONE);
   231     close(INDEXZONE);
   223 
   232 
   224     for (@iz_content_old) {
   233     for (@iz_content_old) {
   225         unless (m#ZONE::#) {
   234         unless (m#ZONE::#) {
   226             push @iz_content_new, $_;
   235             push @iz_content_new, $_;
   227         }
   236         }
   228     }
   237     }
   229 
   238 
   230     for my $dir ( glob "$master_dir/*" ) {
   239     for my $dir (glob "$master_dir/*") {
   231         my $zone = basename($dir);
   240         my $zone     = basename($dir);
   232         my $info_end = "::sec-off";
   241         my $info_end = "::sec-off";
   233 
   242 
   234         if (-e "$dir/.keycounter") {
   243         if (-e "$dir/.keycounter") {
   235             $info_end = "::sec-on";
   244             $info_end = "::sec-on";
   236         }
   245         }
   238         my $iz_line = "\t\tIN TXT\t\t\"ZONE::$zone$info_end\"\n";
   247         my $iz_line = "\t\tIN TXT\t\t\"ZONE::$zone$info_end\"\n";
   239 
   248 
   240         push @iz_content_new, $iz_line;
   249         push @iz_content_new, $iz_line;
   241     }
   250     }
   242 
   251 
   243     open (INDEXZONE, ">$master_dir/$indexzone/$indexzone")
   252     open(INDEXZONE, ">$master_dir/$indexzone/$indexzone")
   244         or die "$master_dir/$indexzone/$indexzone: $!\n";
   253       or die "$master_dir/$indexzone/$indexzone: $!\n";
   245     print INDEXZONE @iz_content_new;
   254     print INDEXZONE @iz_content_new;
   246     close (INDEXZONE);
   255     close(INDEXZONE);
   247 
   256 
   248     # fuegt die index-zone in die liste damit der serial erhoet wird
   257     # fuegt die index-zone in die liste damit der serial erhoet wird
   249     push @new_serial, $indexzone;
   258     push @new_serial, $indexzone;
   250 
   259 
   251     print "** index-zone aktualisiert \n";
   260     print "** index-zone aktualisiert \n";
   252 }
   261 }
   253 
   262 
   254 sub file_entry {
   263 sub file_entry {
       
   264 
   255     # prueft jede domain, die ein verzeichnis in $master_dir hat, ob sie
   265     # prueft jede domain, die ein verzeichnis in $master_dir hat, ob sie
   256     # dnssec nutzt.
   266     # dnssec nutzt.
   257     # passt die eintraege in $config_file falls noetig an.
   267     # passt die eintraege in $config_file falls noetig an.
   258     our $master_dir;
   268     our $master_dir;
   259     our $conf_dir;
   269     our $conf_dir;
   260 
   270 
   261     while (<$master_dir/*>) {
   271     while (<$master_dir/*>) {
   262         s#($master_dir/)(.*)#$2#;
   272         s#($master_dir/)(.*)#$2#;
   263         my $zone = $_;
   273         my $zone      = $_;
   264         my $zone_file = "$master_dir/$zone/$zone";
   274         my $zone_file = "$master_dir/$zone/$zone";
   265         my $conf_file = "$conf_dir/$zone";
   275         my $conf_file = "$conf_dir/$zone";
   266         my @c_content;
   276         my @c_content;
   267 
   277 
   268         unless ( -f "$conf_file" ) {
   278         unless (-f "$conf_file") {
   269             die "$conf_file: $! \n";
   279             die "$conf_file: $! \n";
   270         }
   280         }
   271 
   281 
   272         if ( -e "$master_dir/$zone/.keycounter" ) {
   282         if (-e "$master_dir/$zone/.keycounter") {
   273             open( FILE, "<$conf_file" ) or die "$conf_file: $!\n";
   283             open(FILE, "<$conf_file") or die "$conf_file: $!\n";
   274             @c_content = <FILE>;
   284             @c_content = <FILE>;
   275             close(FILE);
   285             close(FILE);
   276             for (@c_content) {
   286             for (@c_content) {
   277                 if (m{(.*)($zone_file)(";)}) {
   287                 if (m{(.*)($zone_file)(";)}) {
   278                     print " * zonekonfiguration aktualisiert ($2 ==> $2.signed)\n";
   288                     print
       
   289                       " * zonekonfiguration aktualisiert ($2 ==> $2.signed)\n";
   279                     $_ = "$1$2.signed$3\n";
   290                     $_ = "$1$2.signed$3\n";
   280                 }
   291                 }
   281             }
   292             }
   282             open( FILE, ">$conf_file" ) or die "$conf_file: $!\n";
   293             open(FILE, ">$conf_file") or die "$conf_file: $!\n";
   283             print FILE @c_content;
   294             print FILE @c_content;
   284             close(FILE);
   295             close(FILE);
   285         }
   296         }
   286         else {
   297         else {
   287             open( FILE, "<$conf_file" ) or die "$conf_file: $!\n";
   298             open(FILE, "<$conf_file") or die "$conf_file: $!\n";
   288             @c_content = <FILE>;
   299             @c_content = <FILE>;
   289             close(FILE);
   300             close(FILE);
   290             for (@c_content) {
   301             for (@c_content) {
   291                 if (m{(.*)($zone_file)\.signed(.*)}) {
   302                 if (m{(.*)($zone_file)\.signed(.*)}) {
   292                     print " * zonekonfiguration aktualisiert ($2.signed ==> $2)\n";
   303                     print
       
   304                       " * zonekonfiguration aktualisiert ($2.signed ==> $2)\n";
   293                     $_ = "$1$2$3\n";
   305                     $_ = "$1$2$3\n";
   294                 }
   306                 }
   295             }
   307             }
   296             open( FILE, ">$conf_file" ) or die "$conf_file: $!\n";
   308             open(FILE, ">$conf_file") or die "$conf_file: $!\n";
   297             print FILE @c_content;
   309             print FILE @c_content;
   298             close(FILE);
   310             close(FILE);
   299         }
   311         }
   300     }
   312     }
   301 }
   313 }
   302 
   314 
   303 sub server_reload {
   315 sub server_reload {
   304     if (`rndc reload`) {print "** reload dns-server \n"};
   316     if (`rndc reload`) { print "** reload dns-server \n" }
   305 }
   317 }
   306 
   318 
   307 sub to_begin_ro {
   319 sub to_begin_ro {
       
   320 
   308     # gibt alle zonen mit abgelaufenen keycounter in die liste @begin_ro_list
   321     # gibt alle zonen mit abgelaufenen keycounter in die liste @begin_ro_list
   309     our @begin_ro_list;
   322     our @begin_ro_list;
   310     our $master_dir;
   323     our $master_dir;
   311     our $key_counter_end;
   324     our $key_counter_end;
   312     our @new_serial;
   325     our @new_serial;
   313     my $zone;
   326     my $zone;
   314 
   327 
   315     while (<$master_dir/*>) {
   328     while (<$master_dir/*>) {
   316         chomp( $zone = $_ );
   329         chomp($zone = $_);
   317         my $key;
   330         my $key;
   318 
   331 
   319         unless (-f "$zone/.keycounter" ) {next;}
   332         unless (-f "$zone/.keycounter") { next; }
   320 
   333 
   321         open( KEY, "$zone/.keycounter" ) or die "$zone/.keycounter: $!\n";
   334         open(KEY, "$zone/.keycounter") or die "$zone/.keycounter: $!\n";
   322         $key = <KEY>;
   335         $key = <KEY>;
   323         close(KEY);
   336         close(KEY);
   324 
   337 
   325         # vergleicht den wert aus der keycount-datei mit dem wert aus der
   338         # vergleicht den wert aus der keycount-datei mit dem wert aus der
   326         #dnstools.conf (key_counter_end)
   339         #dnstools.conf (key_counter_end)
   327         if ( $key_counter_end <= $key ) {
   340         if ($key_counter_end <= $key) {
   328             $zone =~ s#($master_dir/)(.*)#$2#;
   341             $zone =~ s#($master_dir/)(.*)#$2#;
   329             push @begin_ro_list, $zone;
   342             push @begin_ro_list, $zone;
   330         }
   343         }
   331     }
   344     }
   332 }
   345 }
   333 
   346 
   334 sub to_end_ro {
   347 sub to_end_ro {
       
   348 
   335     # funktion ueberprueft ob ein keyrollover fertig ist
   349     # funktion ueberprueft ob ein keyrollover fertig ist
   336     # die bedingung dafuer ist das:
   350     # die bedingung dafuer ist das:
   337     # - eine datei .index.zsk vorhanden ist
   351     # - eine datei .index.zsk vorhanden ist
   338     # - die datei .index.zsk vor mehr x stunden geaendert wurde
   352     # - die datei .index.zsk vor mehr x stunden geaendert wurde
   339     # - die datei .index.zsk ueber mehr als zwei zeilen gross ist
   353     # - die datei .index.zsk ueber mehr als zwei zeilen gross ist
   340     our $master_dir;
   354     our $master_dir;
   341     our @end_ro_list;
   355     our @end_ro_list;
   342     our $ablauf_zeit;
   356     our $ablauf_zeit;
   343     chomp( my $now_time = `date +%s` );
   357     chomp(my $now_time = `date +%s`);
   344 
   358 
   345     for (<$master_dir/*>) {
   359     for (<$master_dir/*>) {
   346         my $zone = $_;
   360         my $zone = $_;
   347         $zone =~ s#($master_dir/)(.*)#$2#;
   361         $zone =~ s#($master_dir/)(.*)#$2#;
   348 
   362 
   350         my $index_wc;
   364         my $index_wc;
   351         my @status;
   365         my @status;
   352 
   366 
   353         # prueft nach der ".index.zsk"-datei und erstellt den zeitpunkt
   367         # prueft nach der ".index.zsk"-datei und erstellt den zeitpunkt
   354         # an dem das key-rollover endet. - $status[9]
   368         # an dem das key-rollover endet. - $status[9]
   355         if ( -e "$master_dir/$zone/.index.zsk" ) {
   369         if (-e "$master_dir/$zone/.index.zsk") {
   356             @status = stat("$master_dir/$zone/.index.zsk");
   370             @status = stat("$master_dir/$zone/.index.zsk");
   357             $status[9] += ( 3600 * $ablauf_zeit );
   371             $status[9] += (3600 * $ablauf_zeit);
   358         }
   372         }
   359         else { next; }
   373         else { next; }
   360 
   374 
   361         # $status[9] ist der zeitpunkt an dem der key-rollover endet
   375         # $status[9] ist der zeitpunkt an dem der key-rollover endet
   362         # prueft ob das key-rollover-ende erreicht ist
   376         # prueft ob das key-rollover-ende erreicht ist
   363         unless ( $status[9] < $now_time ) { next;}
   377         unless ($status[9] < $now_time) { next; }
   364 
   378 
   365         # prueft die anzahl der schluessel in der .index.zsk
   379         # prueft die anzahl der schluessel in der .index.zsk
   366         open( INDEX, "$master_dir/$zone/.index.zsk" )
   380         open(INDEX, "$master_dir/$zone/.index.zsk")
   367             or die "$master_dir/$zone/.index.zsk: $!\n";
   381           or die "$master_dir/$zone/.index.zsk: $!\n";
   368         @index    = <INDEX>;
   382         @index    = <INDEX>;
   369         $index_wc = @index;
   383         $index_wc = @index;
   370         close(INDEX);
   384         close(INDEX);
   371         if ( $index_wc > 1 ) {push @end_ro_list, $zone;}
   385         if ($index_wc > 1) { push @end_ro_list, $zone; }
   372     }
   386     }
   373 }
   387 }
   374 
   388 
   375 sub begin_ro {
   389 sub begin_ro {
       
   390 
   376     # anfang des key-rollovers
   391     # anfang des key-rollovers
   377     our @begin_ro_list;
   392     our @begin_ro_list;
   378     our $master_dir;
   393     our $master_dir;
   379     our @new_serial;
   394     our @new_serial;
   380 
   395 
   381     for ( &del_double( @begin_ro_list ) ) {
   396     for (&del_double(@begin_ro_list)) {
       
   397 
   382         #erzeugt zsks
   398         #erzeugt zsks
   383         my $zone = $_;
   399         my $zone = $_;
   384         my $zpf   = "$master_dir/$zone";
   400         my $zpf  = "$master_dir/$zone";
   385         my @index;
   401         my @index;
   386 
   402 
   387         chdir "$zpf" or die "$zpf: $!\n";
   403         chdir "$zpf" or die "$zpf: $!\n";
   388         my $keyname = `dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`;
   404         my $keyname = `dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`;
   389 
   405 
   390         open( INDEX, ".index.zsk" ) or die "$zpf/.index.zsk: $!\n";
   406         open(INDEX, ".index.zsk") or die "$zpf/.index.zsk: $!\n";
   391         @index = <INDEX>;
   407         @index = <INDEX>;
   392         close(INDEX);
   408         close(INDEX);
   393 
   409 
   394         push @index, $keyname;
   410         push @index, $keyname;
   395         if ( @index > 2 ) { shift(@index); }
   411         if (@index > 2) { shift(@index); }
   396 
   412 
   397         open( INDEX, ">.index.zsk" ) or die "$zpf/.index.zsk: $!\n";
   413         open(INDEX, ">.index.zsk") or die "$zpf/.index.zsk: $!\n";
   398         print INDEX @index;
   414         print INDEX @index;
   399         close(INDEX);
   415         close(INDEX);
   400 
   416 
   401         chomp($keyname);
   417         chomp($keyname);
   402         print " * $zone: neuer ZSK $keyname erstellt\n";
   418         print " * $zone: neuer ZSK $keyname erstellt\n";
   403 
   419 
   404         open( KC, ">.keycounter" ) or die "$zpf/keycounter: $!\n";
   420         open(KC, ">.keycounter") or die "$zpf/keycounter: $!\n";
   405         print KC "0";
   421         print KC "0";
   406         close(KC);
   422         close(KC);
   407 
   423 
   408         &kill_useless_keys($zone);
   424         &kill_useless_keys($zone);
   409         &key_to_zonefile($zone);
   425         &key_to_zonefile($zone);
   410         push @new_serial, $zone;
   426         push @new_serial, $zone;
   411     }
   427     }
   412 }
   428 }
   413 
   429 
   414 sub key_to_zonefile {
   430 sub key_to_zonefile {
       
   431 
   415     # die funktion fugt alle schluessel in eine zonedatei
   432     # die funktion fugt alle schluessel in eine zonedatei
   416     our $master_dir;
   433     our $master_dir;
   417     my $zone = $_[0];
   434     my $zone = $_[0];
   418     my $zpf = "$master_dir/$zone";
   435     my $zpf  = "$master_dir/$zone";
   419     my @old_content;
   436     my @old_content;
   420     my @new_content = ();
   437     my @new_content = ();
   421 
   438 
   422     open(ZONEFILE, "<$zpf/$zone");
   439     open(ZONEFILE, "<$zpf/$zone");
   423     @old_content = <ZONEFILE>;
   440     @old_content = <ZONEFILE>;
   430     for (<$zpf/*>) {
   447     for (<$zpf/*>) {
   431         if (m#(.*\/)(K.*\.key)#) {
   448         if (m#(.*\/)(K.*\.key)#) {
   432             push @new_content, "\$INCLUDE \"$2\"\n";
   449             push @new_content, "\$INCLUDE \"$2\"\n";
   433         }
   450         }
   434     }
   451     }
   435     open( ZONEFILE, ">$zpf/$zone" ) or die "$zpf/$zone: $!\n";
   452     open(ZONEFILE, ">$zpf/$zone") or die "$zpf/$zone: $!\n";
   436     print ZONEFILE @new_content;
   453     print ZONEFILE @new_content;
   437     close(ZONEFILE);
   454     close(ZONEFILE);
   438 }
   455 }
   439 
   456 
   440 sub kill_useless_keys {
   457 sub kill_useless_keys {
       
   458 
   441     # die funktion loescht alle schluessel die nicht in der index.zsk
   459     # die funktion loescht alle schluessel die nicht in der index.zsk
   442     # der uebergebenen zone stehen
   460     # der uebergebenen zone stehen
   443     our $master_dir;
   461     our $master_dir;
   444     my $zone     = $_[0];
   462     my $zone    = $_[0];
   445     my @keylist  = ();
   463     my @keylist = ();
   446     my $zpf      = "$master_dir/$zone";
   464     my $zpf     = "$master_dir/$zone";
   447 
   465 
   448     open (INDEX, "<$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n";
   466     open(INDEX, "<$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n";
   449     @keylist = <INDEX>;
   467     @keylist = <INDEX>;
   450     close(INDEX);
   468     close(INDEX);
   451     open (INDEX, "<$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n";
   469     open(INDEX, "<$zpf/.index.ksk") or die "$zpf/.index.ksk: $!\n";
   452     push @keylist, <INDEX>;
   470     push @keylist, <INDEX>;
   453 
   471 
   454     # kuerzt die schluessel-bezeichnung aus der indexdatei auf die id um sie
   472     # kuerzt die schluessel-bezeichnung aus der indexdatei auf die id um sie
   455     # besser vergleichen zu koennen.
   473     # besser vergleichen zu koennen.
   456     for ( @keylist ) {
   474     for (@keylist) {
   457         chomp;
   475         chomp;
   458         s#K.*\+.*\+(.*)#$1#;
   476         s#K.*\+.*\+(.*)#$1#;
   459     }
   477     }
   460 
   478 
   461     # prueft alle schluesseldateien (ksk, zsk) ob sie in der jeweiligen
   479     # prueft alle schluesseldateien (ksk, zsk) ob sie in der jeweiligen
   462     # indexdatei beschrieben sind. wenn nicht werden sie geloescht.
   480     # indexdatei beschrieben sind. wenn nicht werden sie geloescht.
   463     for (`ls $master_dir/$zone/K*[key,private]`) {
   481     for (`ls $master_dir/$zone/K*[key,private]`) {
   464         chomp;
   482         chomp;
   465         my $file = $_;
   483         my $file     = $_;
   466         my $rm_count = 1;
   484         my $rm_count = 1;
   467         my $keyname;
   485         my $keyname;
   468         for (@keylist) {
   486         for (@keylist) {
   469             if ( $file =~ /$_/ ) { $rm_count = 0;}
   487             if ($file =~ /$_/) { $rm_count = 0; }
   470         }
   488         }
   471         if ($rm_count == 1) {
   489         if ($rm_count == 1) {
   472             unlink "$file";
   490             unlink "$file";
   473             if ($file =~ /$zpf\/(.*\.key)/ ) {
   491             if ($file =~ /$zpf\/(.*\.key)/) {
   474                 print " * $zone: Schluessel $1 entfernt \n";
   492                 print " * $zone: Schluessel $1 entfernt \n";
   475             }
   493             }
   476         }       
   494         }
   477     }
   495     }
   478 }
   496 }
   479 
   497 
   480 sub end_ro {
   498 sub end_ro {
   481     our @end_ro_list;
   499     our @end_ro_list;
   482     our $master_dir;
   500     our $master_dir;
   483     our @new_serial;
   501     our @new_serial;
   484     my @content;
   502     my @content;
   485 
   503 
   486     for (@end_ro_list) {
   504     for (@end_ro_list) {
   487         my $zone = $_;
   505         my $zone  = $_;
   488         my $count = 0;
   506         my $count = 0;
   489         my @content;
   507         my @content;
   490         my $last_key;
   508         my $last_key;
   491 
   509 
   492         open (INDEX, "<$master_dir/$zone/.index.zsk");
   510         open(INDEX, "<$master_dir/$zone/.index.zsk");
   493         @content = <INDEX>;
   511         @content = <INDEX>;
   494         close(INDEX);
   512         close(INDEX);
   495 
   513 
   496         for (@content) {
   514         for (@content) {
   497             $count++;
   515             $count++;
   498             $last_key = $_;
   516             $last_key = $_;
   499         }
   517         }
   500         if ($count > 1) {
   518         if ($count > 1) {
   501             open (INDEX, ">$master_dir/$zone/.index.zsk");
   519             open(INDEX, ">$master_dir/$zone/.index.zsk");
   502             print INDEX $last_key;
   520             print INDEX $last_key;
   503             close (INDEX);
   521             close(INDEX);
   504         }
   522         }
   505         &kill_useless_keys($zone);
   523         &kill_useless_keys($zone);
   506         &key_to_zonefile($zone);
   524         &key_to_zonefile($zone);
   507         push @new_serial, $zone;
   525         push @new_serial, $zone;
   508     }
   526     }
   509 }
   527 }
   510 
   528 
   511 
       
   512 &read_conf;
   529 &read_conf;
   513 
   530 
   514 our %config;
   531 our %config;
   515 our @new_serial;     # liste fuer neuen serial
   532 our @new_serial;       # liste fuer neuen serial
   516 our @begin_ro_list;  # liste mit zonen deren key-rollover beginnt
   533 our @begin_ro_list;    # liste mit zonen deren key-rollover beginnt
   517 our @end_ro_list;    # liste mit zonen deren key-rollover fertig ist
   534 our @end_ro_list;      # liste mit zonen deren key-rollover fertig ist
   518 our $master_dir      = $config{master_dir};
   535 our $master_dir      = $config{master_dir};
   519 our $bind_dir        = $config{bind_dir};
   536 our $bind_dir        = $config{bind_dir};
   520 our $conf_dir        = $config{zone_conf_dir};
   537 our $conf_dir        = $config{zone_conf_dir};
   521 our $sign_alert_time = $config{sign_alert_time};
   538 our $sign_alert_time = $config{sign_alert_time};
   522 our $indexzone       = $config{indexzone};
   539 our $indexzone       = $config{indexzone};
   525 
   542 
   526 &add_argv;
   543 &add_argv;
   527 &changed_zone;
   544 &changed_zone;
   528 &sign_end;
   545 &sign_end;
   529 
   546 
   530 &to_begin_ro; # prueft nach beginnenden rollover-verfahren
   547 &to_begin_ro;    # prueft nach beginnenden rollover-verfahren
   531 &to_end_ro; # prueft nach endenden rollover-verfahren
   548 &to_end_ro;      # prueft nach endenden rollover-verfahren
   532 
   549 
   533 if (@begin_ro_list) {
   550 if (@begin_ro_list) {
   534     &begin_ro; # eine rollover-beginn-sequenz
   551     &begin_ro;    # eine rollover-beginn-sequenz
   535 }
   552 }
   536 
   553 
   537 if (@end_ro_list) {
   554 if (@end_ro_list) {
   538     &end_ro; # eine rollover-end-squenz
   555     &end_ro;      # eine rollover-end-squenz
   539 }
   556 }
   540 
   557 
   541 if (@new_serial) {
   558 if (@new_serial) {
   542     &update_index; # index zone aktuallisieren
   559     &update_index;     # index zone aktuallisieren
   543     &update_serial; # serial aktuallisieren
   560     &update_serial;    # serial aktuallisieren
   544     &sign_zone; # zone signieren
   561     &sign_zone;        # zone signieren
   545 }
   562 }
   546 
   563 
   547 &file_entry;  # bearbeitet die file-eintraege der konfigurations-datei
   564 &file_entry;           # bearbeitet die file-eintraege der konfigurations-datei
   548 &mk_zone_conf; # konfiguration zusammenfuegen
   565 &mk_zone_conf;         # konfiguration zusammenfuegen
   549 &server_reload; # server neu laden
   566 &server_reload;        # server neu laden