/*****************************************************************
**
** @(#) zkt-keyman.c (c) Jan 2005 - Apr 2010 Holger Zuleger hznet.de
**
** ZKT key managing tool (formely knon as dnsses-zkt)
** A wrapper command around the BIND dnssec-keygen utility
**
** Copyright (c) 2005 - 2010, Holger Zuleger HZnet. All rights reserved.
**
** This software is open source.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** Redistributions of source code must retain the above copyright notice,
** this list of conditions and the following disclaimer.
**
** Redistributions in binary form must reproduce the above copyright notice,
** this list of conditions and the following disclaimer in the documentation
**
** Neither the name of Holger Zuleger HZnet nor the names of its contributors may
** be used to endorse or promote products derived from this software without
** specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
** CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
** SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
** CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
** POSSIBILITY OF SUCH DAMAGE.
**
*****************************************************************/
# include <stdio.h>
# include <stdlib.h> /* abort(), exit(), ... */
# include <string.h>
# include <dirent.h>
# include <assert.h>
# include <unistd.h>
# include <ctype.h>
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
# include "config_zkt.h"
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
# include <getopt.h>
#endif
# include "debug.h"
# include "misc.h"
# include "strlist.h"
# include "zconf.h"
# include "dki.h"
# include "zkt.h"
extern int optopt;
extern int opterr;
extern int optind;
extern char *optarg;
const char *progname;
int ageflag = 0;
int lifetime = 0;
int lifetimeflag = 0;
int exptimeflag = 0;
int pathflag = 0;
int ljustflag = 0;
static int dirflag = 0;
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
{0, 0, 0, 0}
};
#endif
{
}
{
int c;
int opt_index;
int action;
const char *file;
char *p;
int searchtag;
progname = ++p;
fatal ("Out of memory\n");
opterr = 0;
opt_index = 0;
action = 0;
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
#else
#endif
{
switch ( c )
{
case '9': /* ksk rollover help */
exit (1);
case '1': /* ksk rollover: create new key */
case '2': /* ksk rollover: publish DS */
case '3': /* ksk rollover: delete old key */
case '0': /* ksk rollover: show current status */
action = c;
if ( !optarg )
break;
case 'h':
case 'K':
case 'Z':
action = c;
break;
case 'C':
/* fall through */
case 'P':
case 'S':
case 'A':
case 'D':
case 'R':
case 's':
case 19:
case 20:
action = c;
break;
case 'F': /* set key lifetime */
action = c;
break;
case 'V': /* view name */
fatal ("Out of memory\n");
break;
case 'c':
break;
case 'O': /* read option from commandline */
break;
case 'd': /* ignore directory arg */
dirflag = 1;
break;
case 'k': /* ksk only */
zskflag = 0;
break;
case 'r': /* switch recursive flag */
break;
case 'z': /* zsk only */
kskflag = 0;
break;
case ':':
optopt);
break;
case '?':
optopt);
else
optopt);
break;
default:
abort();
}
}
c = optind;
do {
if ( c >= argc ) /* no args left */
else
if ( is_directory (file) )
else
} while ( c < argc ); /* for all arguments */
switch ( action )
{
case 'h':
case 'C':
break;
case 'P':
case 'S':
case 'A':
case 'D':
else if ( dkp == (void *) 01 )
break;
case 19: /* remove (rename) key file */
else if ( dkp == (void *) 01 )
dki_remove (dkp);
break;
case 20: /* destroy the key (remove the files!) */
else if ( dkp == (void *) 01 )
dki_destroy (dkp);
break;
case 'R':
else if ( dkp == (void *) 01 )
break;
case '1': /* ksk rollover new key */
case '2': /* ksk rollover publish DS */
case '3': /* ksk rollover delete old key */
case '0': /* ksk rollover status */
break;
case 'F':
/* fall through */
default:
}
return 0;
}
#if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
#else
#endif
{
fprintf (stderr, "Remove (rename) or destroy (delete) specified key (<keyspec> := tag | tag:name) \n");
fprintf (stderr, "('%s -9%s' prints out a brief description)\n", progname, loptstr ("|--ksk-rollover", ""));
fprintf (stderr, "\t-r%s\t recursive mode on/off (default: %s)\n", loptstr(", --recursive", "\t"), recflag ? "on": "off");
exit (1);
}
{
fatal ("Create key: no keyname!");
/* search for already existent key to get the directory name */
{
{
}
}
if ( zskflag )
dkp = dki_new (dir, keyname, DKI_ZSK, conf->k_algo, conf->z_bits, conf->z_random, conf->z_life / DAYSEC);
else
dkp = dki_new (dir, keyname, DKI_KSK, conf->k_algo, conf->k_bits, conf->k_random, conf->k_life / DAYSEC);
/* create a new key always in state published, which means "standby" for ksk */
}
{
int phase;
return -1;
phase = 0;
phase = 0;
return phase;
}
{
const char *dir;
int parent_exist;
int parent_age;
int parent_phase;
int parent_propagation;
int key_ttl;
int ksk;
{
fprintf (stderr, "\t to all the parent name server, plus the old DS TTL before going to step three.\n");
return;
}
fatal ("ksk rollover: no domain!");
/* search for already existent key to get the directory name */
/* try to read local config file */
{
}
/* check if parent-file already exist */
parent_phase = parent_age = 0;
{
}
// parent_propagation = 2 * DAYSEC;
ksk = 0; /* count active(!) key signing keys */
{
ksk++;
}
switch ( phase )
{
case 0: /* print status (debug) */
if ( parent_exist )
fprintf (stdout, "\t parent_propagation %d %s\n", parent_propagation, str_delspace (age2str (parent_propagation)));
{
/* TODO: Nur zum testen */
}
break;
case 1:
fatal ("Can\'t create new ksk because there is already an ksk rollover in progress\n");
dkp = dki_new (dir, keyname, DKI_KSK, conf->k_algo, conf->k_bits, conf->k_random, conf->k_life / DAYSEC);
if ( standby )
{
}
// dkp = keylist; /* use old key to create the parent file */
if ( (dkp = (dki_t *)dki_findalgo (keylist, 1, conf->k_algo, 'a', 1)) == NULL ) /* find the oldest active ksk to create the parent file */
fatal ("ksk_rollover phase1: Couldn't find the old active key\n");
break;
case 2:
if ( ksk < 2 )
fatal ("Can\'t publish new key because no one exist\n");
if ( !parent_exist )
fatal ("More than one KSK but no parent file found!\n");
if ( parent_phase != 1 )
fatal ("ksk_rollover (phase2): you have to wait for the propagation of the new KSK (at least %dsec or %s)\n",
break;
case 3:
fatal ("ksk-delkey only allowed after ksk-publish\n");
if ( parent_phase != 2 )
fatal ("ksk_rollover (phase3): you have to wait for DS propagation (at least %dsec or %s)\n",
/* remove the parentfile */
/* remove or rename the old key */
dki_remove (dkp);
break;
}
}
/*****************************************************************
** create_parent_file ()
*****************************************************************/
{
return 0;
if ( phase == 1 )
else
return phase;
}
{
if ( dirflag )
return 0;
return 0;
{
continue;
{
}
{
// fprintf (stderr, "parsedir: tssearch (%d %s)\n", dkp, dkp->name);
#else
#endif
}
}
return 1;
}
{
/* file arg contains path ? ... */
{
#else
#endif
else
}
}
{
const char *p;
*tagp = 0;
str++;
p = str;
if ( isdigit (*p) ) /* keytag starts with digit */
{
do /* eat up to the end of the number */
p++;
while ( isdigit (*p) );
if ( *p == ':' ) /* label follows ? */
return p+1; /* return that */
if ( *p == '\0' )
return NULL; /* no label */
}
return str; /* return as label string if not a numeric keytag */
}