dnssec-signer.c revision 484076c3255e0cc5b179ad736cd930900e4bb06b
/***************************************************************** ** A wrapper around the BIND dnssec-signzone command which is able ** to resign a zone if necessary and doing a zone or key signing key rollover. ** Copyright (c) 2005 - 2008, 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 ** 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 ** and/or other materials provided with the distribution. ** 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. *****************************************************************/ /** function declaration **/ /** global command line options **/ fatal (
"Couldn't load config: Out of memory\n");
case 'V':
/* view name */ fatal (
"Out of memory\n");
case 'c':
/* load config from file */ fatal (
"Out of memory\n");
case 'O':
/* load config option from commandline */ fatal (
"Out of memory\n");
case 'L':
/* error log file|directory */ /* dynamic zone requires a name server reload... */ reloadflag = 0;
/* ...but "rndc thaw" reloads the zone anyway */ if ( !
dynamic_zone )
/* dynamic zones don't need a rndc reload (see "-d" */ "Unknown option \"-%c\".\n",
optopt);
"Unknown option char \\x%x.\n",
optopt);
/* store some of the commandline parameter in the config structure */ if (
origin )
/* option -o ? */ if ( (
argc -
optind) <= 0 )
/* no arguments left ? */ /* anyway, "delete" all (remaining) arguments */ /* complain if nothing could read in */ *p =
'\0';
/* remove trailing path seperator */ fatal (
"Can't read directory tree %s\n",
dir);
fatal (
"No signed zone found in directory tree %s\n",
dir);
/* none of the above: read current directory tree */ fprintf (
stderr,
"\t\t set config options on the commandline\n");
fprintf (
stderr,
"\t\t specify file or directory for the log output\n");
fprintf (
stderr,
"\t\t parse the given directory tree for a list of secure zones \n");
fprintf (
stderr,
"\t\t get the list of secure zones out of the named like config file \n");
fprintf (
stderr,
"\t-n%s\t no execution of external signing command\n",
loptstr (
", --noexec",
"\t"));
// fprintf (stderr, "\t-r%s\t reload zone via <rndc reload zone> (or via the external distribution command)\n", loptstr (", --reload", "\t")); fprintf (
stderr,
"\t-v%s\t be verbose (use twice to be very verbose)\n",
loptstr (
", --verbose",
"\t"));
fprintf (
stderr,
"\t[zone]\t sign only those zones given as argument\n");
fprintf (
stderr,
"\tif neither -D nor -N nor -o is given, the directory tree specified\n");
/** fill zonelist with infos coming out of named.conf **/ error (
"zone \"%s\" in view \"%s\" found in name server config, but no matching view was set on startup\n",
zone,
view);
lg_mesg (
LG_ERROR,
"\"%s\" in view \"%s\" found in name server config, but no matching view was set on startup",
zone,
view);
error (
"Not a secure zone directory (%s)!\n",
zp->
dir);
/* check rfc5011 key signing keys, create new one if necessary */ dbg_msg(
"parsezonedir check rfc 5011 ksk ");
if ( (
newkey & 0
2) != 0
2 )
/* not a rfc 5011 zone ? */ verbmesg (
2,
zp->
conf,
"\t\t->not a rfc5011 zone, looking for a regular ksk rollover\n");
/* check key signing keys, create new one if necessary */ dbg_msg(
"parsezonedir check ksk ");
newkey &= ~0
2;
/* reset bit 2 */ /* check age of zone keys, probably retire (depreciate) or remove old keys */ dbg_msg(
"parsezonedir check zsk ");
/* check age of "dnskey.db" file against age of keyfiles */ dbg_val(
"parsezonedir check_keydb_timestamp (%s)\n",
path);
/* check if there is a new keyset- file */ /* if we work in subdir mode, check if there is a new keyset- file */ ** Check if it is time to do a re-sign. This is the case if ** a) the command line flag -f is set, or ** b) new keys are generated, or ** c) we found a new KSK of a delegated domain, or ** d) the "dnskey.db" file is newer than "zone.db" ** e) the "zone.db" is newer than "zone.db.signed" or ** f) "zone.db.signed" is older than the re-sign interval verbmesg (
2,
zp->
conf,
"\tCheck if there is a parent file to copy\n");
return 0;
/* nothing to do */ /* let's start signing the zone */ /* create new "dnskey.db" file */ if ( !
dynamic_zone )
/* increment serial no in static zone files */ error (
"could not increment serialno of domain %s in file %s: %s!\n",
"zone \"%s\": couldn't increment serialno in file %s: %s",
/* at last, sign the zone file */ /* dynamic zones uses incremental signing, so we have to */ /* prepare the old (signed) file as new input file */ if (
filesize (
path) == 0L )
/* initial signing request ? */ verbmesg (
1,
zp->
conf,
"\tDynamic Zone signing: Initial signing request: Add DNSKEYs to zonefile\n");
verbmesg (
1,
zp->
conf,
"\tDynamic Zone signing: zone file manually edited: Use it as new input file\n");
verbmesg (
1,
zp->
conf,
"\tDynamic Zone signing: copy old signed zone file %s to new input file %s\n",
if (
newkey )
/* if we have new keys, they should be added to the zone file */ else /* else we can do a simple file copy */ /* announce "new" and active key signing keys */ logmesg (
"\tRegister new KSK with tag %d for domain %s\n",
* This function is not working with symbolic links to keyset- files, * because file_mtime() returns the mtime of the underlying file, and *not* * that of the symlink file. * This is bad, because the keyset-file will be newly generated by dnssec-signzone * on every re-signing call. * Instead, in the case of a hierarchical directory structure, we copy the file * (and so we change the timestamp) only if it was modified after the last * generation (checked with cmpfile(), see func sign_zone()). fprintf (
fp,
";\t!!! Don\'t edit this file by hand.\n");
fprintf (
fp,
"; *** List of Key Signing Keys ***\n");
fprintf (
fp,
"; *** List of Zone Signing Keys ***\n");
char salt[
510+
1];
/* salt has a maximum of 255 bytes == 510 hex nibbles */ snprintf (
cmd,
sizeof (
cmd),
"cd %s; %s %s %s%s%s%s%s-o %s -e +%ld %s -N increment -f %s.dsigned %s K*.private 2>&1",
dir,
SIGNCMD,
param,
nsec3param,
gends,
pseudo,
rparam,
keysetdir,
domain,
conf->
sigvalidity,
str,
file,
file);
snprintf (
cmd,
sizeof (
cmd),
"cd %s; %s %s %s%s%s%s%s-o %s -e +%ld %s %s K*.private 2>&1",
dir,
SIGNCMD,
param,
nsec3param,
gends,
pseudo,
rparam,
keysetdir,
domain,
conf->
sigvalidity,
str,
file);
while (
fgets (
str,
sizeof str,
fp) !=
NULL )
/* eat up all output until the last line */ /* propagate "keyset"-file to parent dir */ /* check if special parent-file exist (ksk rollover) */ /* verbmesg (2, conf, "\t check \"%s\" against parent dir\n", fromfile); */ error (
"Couldn't copy \"%s\" to parent dir (%d:%s)\n",