bin/dnssec-keytool
changeset 104 3c725372a1ce
parent 85 c47953192c5c
child 113 30bd047cd057
equal deleted inserted replaced
103:0c9f37c94f0c 104:3c725372a1ce
     5 use strict;
     5 use strict;
     6 use File::Temp;
     6 use File::Temp;
     7 use Getopt::Long;
     7 use Getopt::Long;
     8 use Pod::Usage;
     8 use Pod::Usage;
     9 use File::Basename;
     9 use File::Basename;
       
    10 use Net::LibIDN qw(:all);
    10 use if $ENV{DEBUG} => "Smart::Comments";
    11 use if $ENV{DEBUG} => "Smart::Comments";
    11 use DNStools::Config qw(get_config);
    12 use DNStools::Config qw(get_config);
    12 
    13 
    13 my $ME = basename $0;
    14 my $ME = basename $0;
    14 
    15 
    15 sub read_conf(@);
       
    16 sub read_argv($);
       
    17 sub rm_keys($@);
    16 sub rm_keys($@);
    18 sub ck_zone($@);
    17 sub check_zone($@);
    19 sub create_ksk($@);
    18 sub create_ksk($@);
    20 sub create_zsk($@);
    19 sub create_zsk(@);
    21 sub post_create($@);
    20 sub post_create($@);
    22 
    21 
       
    22 my $CHARSET = "UTF-8";
       
    23 my %cf;
       
    24 
    23 MAIN: {
    25 MAIN: {
    24     ### reading config
    26 
    25     my %conf = get_config();
    27     %cf = get_config();
    26 
    28     my $cmd;
    27     my ($cmd, @zones) = read_argv($conf{master_dir});
    29 
    28 
    30     system("command -v dnssec-keygen &>/dev/null");
    29     given ($cmd) {
    31     die "$ME: command 'dnssec-keygen' not found in $ENV{PATH}\n" if $?;
    30         when ("rm") { rm_keys($conf{master_dir}, @zones); exit }
       
    31         when ("ck") { ck_zone($conf{master_dir}, @zones) }
       
    32         when ("ksk") { create_ksk($conf{master_dir}, @zones) }
       
    33     };
       
    34 
       
    35     create_zsk($conf{master_dir}, @zones);
       
    36     post_create($conf{master_dir}, @zones);
       
    37 }
       
    38 
       
    39 sub read_argv ($) {
       
    40     my ($master_dir) = @_;
       
    41     my ($cmd, @zones);    # return
       
    42 
    32 
    43     GetOptions(
    33     GetOptions(
    44         "zsk"      => sub { $cmd = "zsk" },
    34         "zsk" => sub { push @$cmd => "zsk" },
    45         "ksk"      => sub { $cmd = "ksk" },
    35         "ksk" => sub { push @$cmd => "ksk" },
    46         "rm"       => sub { $cmd = "rm" },
    36         "rm"  => sub { push @$cmd => "rm" },
    47         "ck|check" => sub { $cmd = "ck" },
    37         "check" => sub { $cmd = "check" },
    48         "h|help" => sub { pod2usage(-exitvalue => 0, -verbose => 1) },
    38         "h|help" => sub { pod2usage(-exit => 0, -verbose => 1) },
    49         "m|man"  => sub {
    39         "m|man"  => sub {
    50             pod2usage(
    40             pod2usage(
    51                 -exitvalue => 0,
    41                 -exit      => 0,
    52                 -noperldoc => system("perldoc -V &>/dev/null"),
    42                 -noperldoc => system("perldoc -V &>/dev/null"),
    53                 -verbose   => 2
    43                 -verbose   => 2
    54             );
    44             );
    55         },
    45         },
    56       )
    46       )
    57       and @ARGV
    47       and @ARGV
       
    48       and @$cmd == 1
       
    49       and $cmd = $cmd->[0]
    58       or pod2usage;
    50       or pod2usage;
    59 
    51 
    60     # checks the zones in argv if there are managed zones
    52     # checks the zones in argv if they're managed ones
    61     foreach (@ARGV) {
    53     my @zones;
    62         chomp(my $zone = `idn --quiet "$_"`);
    54     foreach my $utf8zone (@ARGV) {
       
    55         my $zone = idn_to_ascii($utf8zone, $CHARSET);
    63 
    56 
    64         die "zone $zone is not managed\n"
    57         die "zone $zone is not managed\n"
    65           if not -f "$master_dir/$zone/$zone";
    58           if not -f "$cf{master_dir}/$zone/$zone";
    66 
    59 
    67         push @zones, $zone;
    60         push @zones, $zone;
    68     }
    61     }
    69     return ($cmd, @zones);
    62 
    70 }
    63     given ($cmd) {
    71 
    64         when ("zsk")   { exit create_zsk(@zones) };
       
    65         #when ("ksk")   { return create_ksk(@zones) };
       
    66         #when ("check") { return check_zone(@zones) };
       
    67         #when ("rm")    { return rm_keys(@zones) };
       
    68 	default		{ die "not implemented\n" };
       
    69     };
       
    70 }
    72 
    71 
    73 sub rm_keys ($@) {
    72 sub rm_keys ($@) {
    74 
    73 
    75     # deletes all the keys were handed over -rm in argv
    74     # deletes all the keys were handed over -rm in argv
    76     my ($master_dir, @zone) = @_;
    75     my ($master_dir, @zone) = @_;
   107 
   106 
   108         if ($ep == 1) {
   107         if ($ep == 1) {
   109             print " * $zone: removed key-set\n";
   108             print " * $zone: removed key-set\n";
   110         }
   109         }
   111 
   110 
   112 	open(my $old, "$zpf/$zone") or die "$zpf/$zone: $!\n";
   111         open(my $old, "$zpf/$zone") or die "$zpf/$zone: $!\n";
   113 	my $fh = File::Temp->new(DIR => $zpf) or die "Can't create tmpfile: $!\n";
   112         my $fh = File::Temp->new(DIR => $zpf)
   114 	print $fh grep { not /^\s*\$INCLUDE.*"K$zone.*\.key"/i } <$old>;
   113           or die "Can't create tmpfile: $!\n";
   115 	rename($fh->filename => "$zpf/$zone")
   114         print $fh grep { not /^\s*\$INCLUDE.*"K$zone.*\.key"/i } <$old>;
   116 	    or die "Can't rename " . $fh->filename . " to $zpf/$zone: $!\n";
   115         rename($fh->filename => "$zpf/$zone")
       
   116           or die "Can't rename " . $fh->filename . " to $zpf/$zone: $!\n";
   117     }
   117     }
   118 }
   118 }
   119 
   119 
   120 sub create_ksk ($@) {
   120 sub create_ksk ($@) {
   121     my ($master_dir, @zone) = @_;
   121     my ($master_dir, @zone) = @_;
   154         print "!! THE KSK must be published !! \n";
   154         print "!! THE KSK must be published !! \n";
   155 
   155 
   156     }
   156     }
   157 }
   157 }
   158 
   158 
   159 sub create_zsk ($@) {
   159 sub create_zsk (@) {
   160     my ($master_dir, @zone) = @_;
   160     my @zones = @_;
   161     my @index;
   161 
   162     my $keyname;
   162     my $keyname;
   163 
   163 
   164     for (@zone) {
   164     foreach my $zone (@zones) {
   165         my $zone = $_;
   165         my $dir  = "$cf{master_dir}/$zone";
   166         my $zpf  = "$master_dir/$zone";
   166 
   167 
   167         chomp($keyname = `cd $dir && dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`);
   168         $keyname = `cd $zpf && dnssec-keygen -a RSASHA1 -b 512 -n ZONE $zone`;
   168 
   169 
   169 	my @index;
   170         unless (-f "$zpf/.index.zsk") {
   170 	open(my $idx, "+>>", "$dir/.index.zsk") or die "Can't open $dir/.index.zsk: $!\n";
   171             @index = ();
   171 	seek($idx, 0, 0);
   172         }
   172 	chomp(@index = <$idx>);
   173         else {
       
   174             open(INDEX, "$zpf/.index.zsk") or die "$zpf/.index.zsk: $!\n";
       
   175             @index = <INDEX>;
       
   176             close(INDEX);
       
   177         }
       
   178 
   173 
   179         push @index, $keyname;
   174         push @index, $keyname;
   180         if (@index > 2) { shift(@index); }
   175 	shift @index if @index > 2;
   181 
   176 
   182         {
   177 	truncate($idx, 0);
   183             my $fh = File::Temp->new(DIR => "$zpf")
   178 	print $idx join "\n" => @index, "";
   184               or die "Can't create tmpdir: $!\n";
   179 	close($idx);
   185             print $fh join "" => @index, "";
   180 
   186             rename($fh->filename => "$zpf/.index.zsk")
   181         say "$zone: new ZSK $keyname";
   187               or die "Can't rename "
   182 
   188               . $fh->filename
   183         open(my $kc, ">", "$dir/.keycounter") or die "$dir/.keycounter: $!\n";
   189               . " to $zpf/.index.zsk: $!\n";
   184         print $kc "0\n";
   190         }
   185         close($kc);
   191         chomp($keyname);
   186     }
   192         print " * $zone: new ZSK $keyname\n";
   187 }
   193 
   188 
   194         open(KC, ">$zpf/.keycounter") or die "$zpf/keycounter: $!\n";
   189 sub check_zone ($@) {
   195         print KC "0";
       
   196         close(KC);
       
   197     }
       
   198 }
       
   199 
       
   200 sub ck_zone ($@) {
       
   201     my ($master_dir, @zone) = @_;
   190     my ($master_dir, @zone) = @_;
   202 
   191 
   203     for (@zone) {
   192     for (@zone) {
   204         my $zone = $_;
   193         my $zone = $_;
   205         my $zpf  = "$master_dir/$zone";
   194         my $zpf  = "$master_dir/$zone";
   318 
   307 
   319 =pod
   308 =pod
   320 
   309 
   321 =head1 NAME
   310 =head1 NAME
   322 
   311 
   323 dnssec-keytool
   312     dnssec-keytool - key management
   324 
   313 
   325 =head1 SYNOPSIS
   314 =head1 SYNOPSIS
   326 
   315 
   327 dnssec-keytool {-z|-k|-r|-c} zone
   316     dnssec-keytool {--zsk|--ksk|--rm|--check} zone...
   328 
   317 
   329 =head1 DESCRIPTION
   318 =head1 DESCRIPTION
   330 
   319 
   331 Blabla.
   320 Blabla.
   332 
   321 
   333 =head1 OPTIONS
   322 =head1 OPTIONS
   334 
   323 
   335 =over
   324 =over
   336 
   325 
   337 =item B<-z>  created a new ZSK
   326 =item B<--zsk> 
   338 
   327 
   339 =item B<-k>  created a new ZSK and KSK
   328 Create a new ZSK for the zones.
   340 
   329 
   341 =item B<-r>  delete the key-set of a zone
   330 =item B<--ksk>
   342 
   331 
   343 =item B<-c>  created configuration files for the dnstools and a new ZSK for an existing KSK
   332 Create a new KSK for the zones.
       
   333 
       
   334 =item B<--rm>
       
   335 
       
   336 Remote all key material from the zones.
       
   337 
       
   338 =item B<--check>
       
   339 
       
   340 ???
   344 
   341 
   345 =back
   342 =back
   346 
   343 
   347 =cut
   344 =cut
   348 
   345