1 /*	$NetBSD: zconf.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $	*/
2 
3 /****************************************************************
4 **
5 **	@(#) zconf.c -- configuration file parser for dnssec.conf
6 **
7 **	The initial code of this module is from the SixXS Heartbeat Client
8 **	written by Jeroen Massar <jeroen@sixxs.net>
9 **
10 **	New config types and many code changes by Holger Zuleger
11 **
12 **	Copyright (c) Aug 2005, Jeroen Massar.
13 **	Copyright (c) Aug 2005 - Nov 2010, Holger Zuleger.
14 **	All rights reserved.
15 **
16 **	This software is open source.
17 **
18 **	Redistribution and use in source and binary forms, with or without
19 **	modification, are permitted provided that the following conditions
20 **	are met:
21 **
22 **	Redistributions of source code must retain the above copyright notice,
23 **	this list of conditions and the following disclaimer.
24 **
25 **	Redistributions in binary form must reproduce the above copyright notice,
26 **	this list of conditions and the following disclaimer in the documentation
27 **	and/or other materials provided with the distribution.
28 **
29 **	Neither the name of Jeroen Masar or Holger Zuleger nor the
30 **	names of its contributors may be used to endorse or promote products
31 **	derived from this software without specific prior written permission.
32 **
33 **	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34 **	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
35 **	TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36 **	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
37 **	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 **	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 **	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 **	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 **	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 **	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 **	POSSIBILITY OF SUCH DAMAGE.
44 **
45 ****************************************************************/
46 # include <sys/types.h>
47 # include <stdio.h>
48 # include <errno.h>
49 # include <unistd.h>
50 # include <stdlib.h>
51 # include <stdarg.h>
52 # include <string.h>
53 # include <strings.h>
54 # include <assert.h>
55 # include <ctype.h>
56 
57 #ifdef HAVE_CONFIG_H
58 # include "config.h"
59 #endif
60 # include "config_zkt.h"
61 # include "debug.h"
62 # include "misc.h"
63 #define extern
64 # include "zconf.h"
65 #undef extern
66 # include "dki.h"
67 
68 # define	ISTRUE(val)	(strcasecmp (val, "yes") == 0 || \
69 				strcasecmp (val, "true") == 0    )
70 # define	ISCOMMENT(cp)	(*(cp) == '#' || *(cp) == ';' || \
71 				(*(cp) == '/' && *((cp)+1) == '/') )
72 # define	ISDELIM(c)	(isspace (c) || (c) == ':' || (c) == '=')
73 
74 
75 # define	cmdln	(0)
76 # define	first	(1)
77 # define	last	(0x7FFF)
78 
79 # define	iscmdline(x)	((x)->used_since == cmdln)
80 # define	iscompatible(x)	((x)->used_since != cmdln && compversion >= (x)->used_since && \
81 				((x)->used_till == 1 || (compversion <= (x)->used_till)))
82 
83 typedef enum {
84 	CONF_END = 0,
85 	CONF_STRING,
86 	CONF_INT,
87 	CONF_TIMEINT,
88 	CONF_BOOL,
89 	CONF_ALGO,
90 	CONF_SERIAL,
91 	CONF_FACILITY,
92 	CONF_LEVEL,
93 	CONF_NSEC3,
94 	CONF_COMMENT,
95 	CONF_VERSION,
96 } ctype_t;
97 
98 /*****************************************************************
99 **	private (static) variables
100 *****************************************************************/
101 static	int	compversion;
102 
103 static	zconf_t	def = {
104 	ZONEDIR, RECURSIVE,
105 	PRINTTIME, PRINTAGE, LJUST, LSCOLORTERM,
106 	SIG_VALIDITY, MAX_TTL, KEY_TTL, PROPTIME, Unixtime,
107 	RESIGN_INT,
108 	KEY_ALGO, ADDITIONAL_KEY_ALGO,
109 	KSK_LIFETIME, KSK_BITS, KSK_RANDOM,
110 	ZSK_LIFETIME, ZSK_BITS, ZSK_ALWAYS, ZSK_RANDOM,
111 	NSEC3_OFF, SALTLEN,
112 	NULL, /* viewname cmdline parameter */
113 	0, /* noexec cmdline parameter */
114 	LOGFILE, LOGLEVEL, LOGDOMAINDIR, SYSLOGFACILITY, SYSLOGLEVEL, VERBOSELOG, 0,
115 	DNSKEYFILE, ZONEFILE, KEYSETDIR,
116 	LOOKASIDEDOMAIN,
117 	SIG_RANDOM, SIG_PSEUDO, SIG_GENDS, SIG_DNSKEY_KSK, SIG_PARAM,
118 	DEPENDFILES,
119 	DIST_CMD,	/* defaults to NULL which means to run "rndc reload" */
120 	NAMED_CHROOT
121 };
122 
123 typedef	struct {
124 	char	*label;		/* the name of the parameter */
125 	short	used_since;	/* compability (from version; 0 == command line) */
126 	short	used_till;	/* compability (to version) */
127 	ctype_t	type;		/* the parameter type */
128 	void	*var;		/* pointer to the parameter variable */
129 	const char	*desc;
130 	const void	*var2;	/* pointer to a second parameter variable */
131 				/* this is a ugly hack needed by cmpconfig () */
132 } zconf_para_t;
133 
134 static	zconf_para_t	confpara[] = {
135 	{ "",			first,	last,	CONF_COMMENT,	""},
136 	{ "",			first,	last,	CONF_COMMENT,	"\t@(#) dnssec.conf "},
137 	{ "",			first,	last,	CONF_VERSION,	"" },
138 	{ "",			first,	last,	CONF_COMMENT,	""},
139 	{ "",			first,	last,	CONF_COMMENT,	NULL },
140 
141 	{ "",			first,	99,	CONF_COMMENT,	"dnssec-zkt options" },
142 	{ "",			100,	last,	CONF_COMMENT,	"zkt-ls options" },
143 	{ "ZoneDir",		first,	last,	CONF_STRING,	&def.zonedir, "default zone file directory (also used by zkt-signer)"},
144 	{ "Recursive",		first,	last,	CONF_BOOL,	&def.recursive, "looking for keys down the directory tree?" },
145 	{ "PrintTime",		first,	last,	CONF_BOOL,	&def.printtime, "print absolute key generation time?" },
146 	{ "PrintAge",		first,	last,	CONF_BOOL,	&def.printage, "print relative key age?" },
147 	{ "LeftJustify",	first,	last,	CONF_BOOL,	&def.ljust, "zone name is printed left justified?" },
148 	{ "lsColor",		100,	last,	CONF_STRING,	&def.colorterm, "terminal name (for coloring)" },
149 
150 	{ "",			first,	last,	CONF_COMMENT,	NULL },
151 	{ "",			first,	last,	CONF_COMMENT,	"zone specific values" },
152 	{ "ResignInterval",	first,	last,	CONF_TIMEINT,	&def.resign },
153 	{ "SigValidity",	first,	last,	CONF_TIMEINT,	&def.sigvalidity },
154 	{ "Max_TTL",		first,	100,	CONF_TIMEINT,	&def.max_ttl },
155 	{ "MaximumTTL",		101,	last,	CONF_TIMEINT,	&def.max_ttl },
156 	{ "Propagation",	first,	last,	CONF_TIMEINT,	&def.proptime },
157 	{ "Key_TTL",		90,	100,	CONF_TIMEINT,	&def.key_ttl },
158 	{ "DnsKeyTTL",		101,	last,	CONF_TIMEINT,	&def.key_ttl },
159 #if defined (DEF_TTL)
160 	{ "def_ttl",		first,	last,	CONF_TIMEINT,	&def.def_ttl },
161 #endif
162 	{ "SerialFormat",	92,	last,	CONF_SERIAL,	&def.serialform },
163 
164 	{ "",			first,	last,	CONF_COMMENT,	NULL },
165 	{ "",			first,	last,	CONF_COMMENT,	"signing key parameters"},
166 	{ "Key_Algo",		99,	100,	CONF_ALGO,	&def.k_algo },	/* now used as general KEY algorithm (KSK & ZSK) */
167 	{ "KeyAlgo",		101,	last,	CONF_ALGO,	&def.k_algo },	/* now used as general KEY algorithm (KSK & ZSK) */
168 	{ "AddKey_Algo",	99,	100,	CONF_ALGO,	&def.k2_algo },		/* second key algorithm added (v0.99) */
169 	{ "AddKeyAlgo",		101,	last,	CONF_ALGO,	&def.k2_algo },		/* second key algorithm added (v0.99) */
170 	{ "KSK_lifetime",	first,	100,	CONF_TIMEINT,	&def.k_life },
171 	{ "KSKlifetime",	101,	last,	CONF_TIMEINT,	&def.k_life },
172 	{ "KSK_algo",		first,	98,	CONF_ALGO,	&def.k_algo },	/* old KSK value changed to key algorithm */
173 	{ "KSK_bits",		first,	100,	CONF_INT,	&def.k_bits },
174 	{ "KSKbits",		101,	last,	CONF_INT,	&def.k_bits },
175 	{ "KSK_randfile",	first,	100,	CONF_STRING,	&def.k_random },
176 	{ "KSKrandfile",	101,	last,	CONF_STRING,	&def.k_random },
177 	{ "ZSK_lifetime",	first,	100,	CONF_TIMEINT,	&def.z_life },
178 	{ "ZSKlifetime",	101,	last,	CONF_TIMEINT,	&def.z_life },
179 	/* { "ZSK_algo",			1,	CONF_ALGO,	&def.z_algo },		ZSK algo removed (set to same as ksk) */
180 	{ "ZSK_algo",		first,	98,	CONF_ALGO,	&def.k2_algo },		/* if someone using it already, map the algo to the additional key algorithm */
181 	{ "ZSK_bits",		first,	100,	CONF_INT,	&def.z_bits },
182 	{ "ZSKbits",		101,	last,	CONF_INT,	&def.z_bits },
183 #if defined(ALLOW_ALWAYS_PREPUBLISH_ZSK) && ALLOW_ALWAYS_PREPUBLISH_ZSK
184 	{ "ZSKpermanent",	102,	last,	CONF_BOOL,	&def.z_always, "Always add a pre-publish zone signing key?" },
185 #endif
186 	{ "ZSK_randfile",	first,	100,	CONF_STRING,	&def.z_random },
187 	{ "ZSKrandfile",	101,	last,	CONF_STRING,	&def.z_random },
188 	{ "NSEC3",		100,	last,	CONF_NSEC3,	&def.nsec3 },
189 	{ "SaltBits",		98,	last,	CONF_INT,	&def.saltbits, },
190 
191 	{ "",			first,	last,	CONF_COMMENT,	NULL },
192 	{ "",			first,	99,	CONF_COMMENT,	"dnssec-signer options"},
193 	{ "",			100,	last,	CONF_COMMENT,	"zkt-signer options"},
194 	{ "--view",		cmdln,	last,	CONF_STRING,	&def.view },
195 	{ "--noexec",		cmdln,	last,	CONF_BOOL,	&def.noexec },
196 	{ "LogFile",		96,	last,	CONF_STRING,	&def.logfile },
197 	{ "LogLevel",		96,	last,	CONF_LEVEL,	&def.loglevel },
198 	{ "LogDomainDir",	96,	last,	CONF_STRING,	&def.logdomaindir },
199 	{ "SyslogFacility",	96,	last,	CONF_FACILITY,	&def.syslogfacility },
200 	{ "SyslogLevel",	96,	last,	CONF_LEVEL,	&def.sysloglevel },
201 	{ "VerboseLog",		96,	last,	CONF_INT,	&def.verboselog },
202 	{ "-v",			cmdln,	last,	CONF_INT,	&def.verbosity },
203 	{ "KeyFile",		first,	last,	CONF_STRING,	&def.keyfile },
204 	{ "ZoneFile",		first,	last,	CONF_STRING,	&def.zonefile },
205 	{ "KeySetDir",		first,	last,	CONF_STRING,	&def.keysetdir },
206 	{ "DLV_Domain",		first,	100,	CONF_STRING,	&def.lookaside },
207 	{ "DLVdomain",		101,	last,	CONF_STRING,	&def.lookaside },
208 	{ "Sig_Randfile",	first,	100,	CONF_STRING,	&def.sig_random },
209 	{ "SigRandfile",	101,	last,	CONF_STRING,	&def.sig_random, "a file containing random data" },
210 	{ "Sig_Pseudorand",	first,	100,	CONF_BOOL,	&def.sig_pseudo },
211 	{ "SigPseudorand",	101,	last,	CONF_BOOL,	&def.sig_pseudo, "use pseudorandom data (faster but less secure)?" },
212 	{ "Sig_GenerateDS",	first,	100,	CONF_BOOL,	&def.sig_gends },
213 	{ "SigGenerateDS",	101,	last,	CONF_BOOL,	&def.sig_gends, "update DS records based on child zone\' dsset-* files?" },
214 	{ "Sig_DnsKeyKSK",	99,	100,	CONF_BOOL,	&def.sig_dnskeyksk },
215 	{ "SigDnsKeyKSK",	101,	last,	CONF_BOOL,	&def.sig_dnskeyksk, "sign dns keyset with ksk only?" },
216 	{ "Sig_Parameter",	first,	100,	CONF_STRING,	&def.sig_param },
217 	{ "SigParameter",	101,	last,	CONF_STRING,	&def.sig_param, "additional dnssec-signzone parameter (if any)" },
218 	{ "DependFiles",	113,	last,	CONF_STRING,	&def.dependfiles, "list of files included in ZoneFile (except KeyFile)" },
219 	{ "Distribute_Cmd",	97,	100,	CONF_STRING,	&def.dist_cmd },
220 	{ "DistributeCmd",	101,	last,	CONF_STRING,	&def.dist_cmd },
221 	{ "NamedChrootDir",	99,	last,	CONF_STRING,	&def.chroot_dir },
222 
223 	{ NULL,			0,	0,	CONF_END,	NULL},
224 };
225 
226 /*****************************************************************
227 **	private (static) function deklaration and definition
228 *****************************************************************/
bool2str(int val)229 static	const char	*bool2str (int val)
230 {
231 	return val ? "True" : "False";
232 }
233 
set_varptr(char * entry,void * ptr,const void * ptr2)234 static	int set_varptr (char *entry, void *ptr, const void *ptr2)
235 {
236 	zconf_para_t	*c;
237 
238 	for ( c = confpara; c->label; c++ )
239 		if ( strcasecmp (entry, c->label) == 0 )
240 		{
241 			c->var = ptr;
242 			c->var2 = ptr2;
243 			return 1;
244 		}
245 	return 0;
246 }
247 
set_all_varptr(zconf_t * cp,const zconf_t * cp2)248 static	void set_all_varptr (zconf_t *cp, const zconf_t *cp2)
249 {
250 	set_varptr ("zonedir", &cp->zonedir, cp2 ? &cp2->zonedir: NULL);
251 	set_varptr ("recursive", &cp->recursive, cp2 ? &cp2->recursive: NULL);
252 	set_varptr ("printage", &cp->printage, cp2 ? &cp2->printage: NULL);
253 	set_varptr ("printtime", &cp->printtime, cp2 ? &cp2->printtime: NULL);
254 	set_varptr ("leftjustify", &cp->ljust, cp2 ? &cp2->ljust: NULL);
255 	set_varptr ("lscolor", &cp->colorterm, cp2 ? &cp2->colorterm: NULL);
256 
257 	set_varptr ("resigninterval", &cp->resign, cp2 ? &cp2->resign: NULL);
258 	set_varptr ("sigvalidity", &cp->sigvalidity, cp2 ? &cp2->sigvalidity: NULL);
259 	set_varptr ("max_ttl", &cp->max_ttl, cp2 ? &cp2->max_ttl: NULL);
260 	set_varptr ("maximumttl", &cp->max_ttl, cp2 ? &cp2->max_ttl: NULL);
261 	set_varptr ("key_ttl", &cp->key_ttl, cp2 ? &cp2->key_ttl: NULL);
262 	set_varptr ("dnskeyttl", &cp->key_ttl, cp2 ? &cp2->key_ttl: NULL);
263 	set_varptr ("propagation", &cp->proptime, cp2 ? &cp2->proptime: NULL);
264 #if defined (DEF_TTL)
265 	set_varptr ("def_ttl", &cp->def_ttl, cp2 ? &cp2->def_ttl: NULLl);
266 #endif
267 	set_varptr ("serialformat", &cp->serialform, cp2 ? &cp2->serialform: NULL);
268 
269 	set_varptr ("key_algo", &cp->k_algo, cp2 ? &cp2->k_algo: NULL);
270 	set_varptr ("keyalgo", &cp->k_algo, cp2 ? &cp2->k_algo: NULL);
271 	set_varptr ("addkey_algo", &cp->k2_algo, cp2 ? &cp2->k2_algo: NULL);
272 	set_varptr ("addkeyalgo", &cp->k2_algo, cp2 ? &cp2->k2_algo: NULL);
273 	set_varptr ("ksk_lifetime", &cp->k_life, cp2 ? &cp2->k_life: NULL);
274 	set_varptr ("ksklifetime", &cp->k_life, cp2 ? &cp2->k_life: NULL);
275 	set_varptr ("ksk_algo", &cp->k_algo, cp2 ? &cp2->k_algo: NULL);		/* used only in compability mode */
276 	set_varptr ("ksk_bits", &cp->k_bits, cp2 ? &cp2->k_bits: NULL);
277 	set_varptr ("kskbits", &cp->k_bits, cp2 ? &cp2->k_bits: NULL);
278 	set_varptr ("ksk_randfile", &cp->k_random, cp2 ? &cp2->k_random: NULL);
279 	set_varptr ("kskrandfile", &cp->k_random, cp2 ? &cp2->k_random: NULL);
280 
281 	set_varptr ("zsk_lifetime", &cp->z_life, cp2 ? &cp2->z_life: NULL);
282 	set_varptr ("zsklifetime", &cp->z_life, cp2 ? &cp2->z_life: NULL);
283 	// set_varptr ("zsk_algo", &cp->z_algo, cp2 ? &cp2->z_algo: NULL);
284 	set_varptr ("zsk_algo", &cp->k2_algo, cp2 ? &cp2->k2_algo: NULL);
285 	set_varptr ("zsk_bits", &cp->z_bits, cp2 ? &cp2->z_bits: NULL);
286 	set_varptr ("zskbits", &cp->z_bits, cp2 ? &cp2->z_bits: NULL);
287 #if defined(ALLOW_ALWAYS_PREPUBLISH_ZSK) && ALLOW_ALWAYS_PREPUBLISH_ZSK
288 	set_varptr ("zskpermanent", &cp->z_always, cp2 ? &cp2->z_always: NULL);
289 #endif
290 	set_varptr ("zsk_randfile", &cp->z_random, cp2 ? &cp2->z_random: NULL);
291 	set_varptr ("zskrandfile", &cp->z_random, cp2 ? &cp2->z_random: NULL);
292 	set_varptr ("nsec3", &cp->nsec3, cp2 ? &cp2->nsec3: NULL);
293 	set_varptr ("saltbits", &cp->saltbits, cp2 ? &cp2->saltbits: NULL);
294 
295 	set_varptr ("--view", &cp->view, cp2 ? &cp2->view: NULL);
296 	set_varptr ("--noexec", &cp->noexec, cp2 ? &cp2->noexec: NULL);
297 	set_varptr ("logfile", &cp->logfile, cp2 ? &cp2->logfile: NULL);
298 	set_varptr ("loglevel", &cp->loglevel, cp2 ? &cp2->loglevel: NULL);
299 	set_varptr ("logdomaindir", &cp->logdomaindir, cp2 ? &cp2->logdomaindir: NULL);
300 	set_varptr ("syslogfacility", &cp->syslogfacility, cp2 ? &cp2->syslogfacility: NULL);
301 	set_varptr ("sysloglevel", &cp->sysloglevel, cp2 ? &cp2->sysloglevel: NULL);
302 	set_varptr ("verboselog", &cp->verboselog, cp2 ? &cp2->verboselog: NULL);
303 	set_varptr ("-v", &cp->verbosity, cp2 ? &cp2->verbosity: NULL);
304 	set_varptr ("keyfile", &cp->keyfile, cp2 ? &cp2->keyfile: NULL);
305 	set_varptr ("zonefile", &cp->zonefile, cp2 ? &cp2->zonefile: NULL);
306 	set_varptr ("keysetdir", &cp->keysetdir, cp2 ? &cp2->keysetdir: NULL);
307 	set_varptr ("dlv_domain", &cp->lookaside, cp2 ? &cp2->lookaside: NULL);
308 	set_varptr ("dlvdomain", &cp->lookaside, cp2 ? &cp2->lookaside: NULL);
309 	set_varptr ("sig_randfile", &cp->sig_random, cp2 ? &cp2->sig_random: NULL);
310 	set_varptr ("sigrandfile", &cp->sig_random, cp2 ? &cp2->sig_random: NULL);
311 	set_varptr ("sig_pseudorand", &cp->sig_pseudo, cp2 ? &cp2->sig_pseudo: NULL);
312 	set_varptr ("sigpseudorand", &cp->sig_pseudo, cp2 ? &cp2->sig_pseudo: NULL);
313 	set_varptr ("sig_generateds", &cp->sig_gends, cp2 ? &cp2->sig_gends: NULL);
314 	set_varptr ("siggenerateds", &cp->sig_gends, cp2 ? &cp2->sig_gends: NULL);
315 	set_varptr ("sig_dnskeyksk", &cp->sig_dnskeyksk, cp2 ? &cp2->sig_dnskeyksk: NULL);
316 	set_varptr ("sigdnskeyksk", &cp->sig_dnskeyksk, cp2 ? &cp2->sig_dnskeyksk: NULL);
317 	set_varptr ("sig_parameter", &cp->sig_param, cp2 ? &cp2->sig_param: NULL);
318 	set_varptr ("sigparameter", &cp->sig_param, cp2 ? &cp2->sig_param: NULL);
319 	set_varptr ("dependfiles", &cp->dependfiles, cp2 ? &cp2->dependfiles: NULL);
320 	set_varptr ("distribute_cmd", &cp->dist_cmd, cp2 ? &cp2->dist_cmd: NULL);
321 	set_varptr ("distributecmd", &cp->dist_cmd, cp2 ? &cp2->dist_cmd: NULL);
322 	set_varptr ("namedchrootdir", &cp->chroot_dir, cp2 ? &cp2->chroot_dir: NULL);
323 }
324 
parseconfigline(char * buf,unsigned int line,zconf_t * z)325 static	void	parseconfigline (char *buf, unsigned int line, zconf_t *z)
326 {
327 	char		*end, *val, *p;
328 	char		*tag;
329 	unsigned int	found;
330 	zconf_para_t	*c;
331 
332 	assert (buf[0] != '\0');
333 
334 	p = &buf[strlen(buf)-1];        /* Chop off white space at eol */
335 	while ( p >= buf && isspace (*p) )
336 		*p-- = '\0';
337 
338 	for (p = buf; isspace (*p); p++ )	/* Ignore leading white space */
339 		;
340 
341 	/* Ignore comments and emtpy lines */
342 	if ( *p == '\0' || ISCOMMENT (p) )
343 		return;
344 
345 	tag = p;
346 	/* Get the end of the first argument */
347 	end = &buf[strlen(buf)-1];
348 	while ( p < end && !ISDELIM (*p) )      /* Skip until delim */
349 		p++;
350 	*p++ = '\0';    /* Terminate this argument */
351 	dbg_val1 ("Parsing \"%s\"\n", tag);
352 
353 	while ( p < end && ISDELIM (*p) )	/* Skip delim chars */
354 		p++;
355 
356 	val = p;	/* Start of the value */
357 	dbg_val1 ("\tgot value \"%s\"\n", val);
358 
359 	/* If starting with quote, skip until next quote */
360 	if ( *p == '"' || *p == '\'' )
361 	{
362 		p++;    /* Find next quote */
363 		while ( p <= end && *p && *p != *val )
364 			p++;
365 		*p = '\0';
366 		val++;          /* Skip the first quote */
367 	}
368 	else    /* Otherwise check if there is any comment char at the end */
369 	{
370 		while ( p < end && *p && !ISCOMMENT(p) )
371 			p++;
372 		if ( ISCOMMENT (p) )
373 		{
374 			do      /* Chop off white space before comment */
375 				*p-- = '\0';
376 			while ( p >= val && isspace (*p) );
377 		}
378 	}
379 
380 	/* Otherwise it is already terminated above */
381 	found = 0;
382 	c = confpara;
383 	while ( !found && c->type != CONF_END )
384 	{
385 		if ( strcasecmp (tag, c->label) == 0 )
386 		{
387 			char	**str;
388 			char	quantity;
389 			long	lval;
390 
391 			found = 1;
392 			switch ( c->type )
393 			{
394 			case CONF_VERSION:
395 				break;
396 			case CONF_LEVEL:
397 			case CONF_FACILITY:
398 			case CONF_STRING:
399 				str = (char **)c->var;
400 				*str = strdup (val);
401 				str_untaint (*str);	/* remove "bad" characters */
402 				break;
403 			case CONF_INT:
404 				sscanf (val, "%d", (int *)c->var);
405 				break;
406 			case CONF_TIMEINT:
407 				quantity = 'd';
408 				if ( *val == 'u' || *val == 'U' )
409 					lval = 0L;
410 				else
411 					sscanf (val, "%ld%c", &lval, &quantity);
412 				if  ( quantity == 'm' )
413 					lval *= MINSEC;
414 				else if  ( quantity == 'h' )
415 					lval *= HOURSEC;
416 				else if  ( quantity == 'd' )
417 					lval *= DAYSEC;
418 				else if  ( quantity == 'w' )
419 					lval *= WEEKSEC;
420 				else if  ( quantity == 'y' )
421 					lval *= YEARSEC;
422 				(*(long *)c->var) = lval;
423 				break;
424 			case CONF_ALGO:
425 				if ( strcmp (val, "1") == 0 || strcasecmp (val, "rsa") == 0 ||
426 								strcasecmp (val, "rsamd5") == 0 )
427 					*((int *)c->var) = DK_ALGO_RSA;
428 				else if ( strcmp (val, "3") == 0 ||
429 					  strcasecmp (val, "dsa") == 0 )
430 					*((int *)c->var) = DK_ALGO_DSA;
431 				else if ( strcmp (val, "5") == 0 ||
432 					  strcasecmp (val, "rsasha1") == 0 )
433 					*((int *)c->var) = DK_ALGO_RSASHA1;
434 				else if ( strcmp (val, "6") == 0 ||
435 					  strcasecmp (val, "nsec3dsa") == 0 ||
436 				          strcasecmp (val, "n3dsa") == 0 )
437 					*((int *)c->var) = DK_ALGO_NSEC3DSA;
438 				else if ( strcmp (val, "7") == 0 ||
439 					  strcasecmp (val, "nsec3rsasha1") == 0 ||
440 					  strcasecmp (val, "n3rsasha1") == 0 )
441 					*((int *)c->var) = DK_ALGO_NSEC3RSASHA1;
442 				else if ( strcmp (val, "8") == 0 ||
443 					  strcasecmp (val, "rsasha2") == 0 ||
444 				          strcasecmp (val, "rsasha256") == 0 ||
445 					  strcasecmp (val, "nsec3rsasha2") == 0 ||
446 					  strcasecmp (val, "n3rsasha2") == 0 ||
447 					  strcasecmp (val, "nsec3rsasha256") == 0 ||
448 					  strcasecmp (val, "n3rsasha256") == 0 )
449 					*((int *)c->var) = DK_ALGO_RSASHA256;
450 				else if ( strcmp (val, "10") == 0 ||
451 					  strcasecmp (val, "rsasha5") == 0 ||
452 				          strcasecmp (val, "rsasha512") == 0 ||
453 					  strcasecmp (val, "nsec3rsasha5") == 0 ||
454 					  strcasecmp (val, "n3rsasha5") == 0 ||
455 					  strcasecmp (val, "nsec3rsasha512") == 0 ||
456 					  strcasecmp (val, "n3rsasha512") == 0 )
457 					*((int *)c->var) = DK_ALGO_RSASHA512;
458 				else
459 					error ("Illegal algorithm \"%s\" "
460 						"in line %d.\n" , val, line);
461 				break;
462 			case CONF_SERIAL:
463 				if ( strcasecmp (val, "unixtime") == 0 )
464 					*((serial_form_t *)c->var) = Unixtime;
465 				else if ( strcasecmp (val, "incremental") == 0 || strcasecmp (val, "inc") == 0 )
466 					*((serial_form_t *)c->var) = Incremental;
467 				else
468 					error ("Illegal serial no format \"%s\" "
469 						"in line %d.\n" , val, line);
470 				break;
471 			case CONF_NSEC3:
472 				if ( strcasecmp (val, "off") == 0 )
473 					*((nsec3_t *)c->var) = NSEC3_OFF;
474 				else if ( strcasecmp (val, "on") == 0 )
475 					*((nsec3_t *)c->var) = NSEC3_ON;
476 				else if ( strcasecmp (val, "optout") == 0 )
477 					*((nsec3_t *)c->var) = NSEC3_OPTOUT;
478 				else
479 					error ("Illegal NSEC3 format \"%s\" "
480 						"in line %d.\n" , val, line);
481 				break;
482 			case CONF_BOOL:
483 				*((int *)c->var) = ISTRUE (val);
484 				break;
485 			default:
486 				fatal ("Illegal configuration type in line %d.\n", line);
487 			}
488 		}
489 		c++;
490 	}
491 	if ( !found )
492 		error ("Unknown configuration statement: %s \"%s\"\n", tag, val);
493 	return;
494 }
495 
printconfigline(FILE * fp,zconf_para_t * cp)496 static	void	printconfigline (FILE *fp, zconf_para_t *cp)
497 {
498 	int	i;
499 	long	lval;
500 	int	printnl;
501 
502 	assert (fp != NULL);
503 	assert (cp != NULL);
504 
505 	printnl = 0;
506 	switch ( cp->type )
507 	{
508 	case CONF_VERSION:
509 			fprintf (fp, "#\tZKT config file for version %d.%d.%d\n",
510 								compversion / 100,
511 								(compversion / 10 ) % 10,
512 								compversion % 10);
513 		break;
514 	case CONF_COMMENT:
515 		if ( cp->var )
516 			fprintf (fp, "#   %s", (char *)cp->var);
517 		printnl = 1;
518 		break;
519 	case CONF_LEVEL:
520 	case CONF_FACILITY:
521 		if ( *(char **)cp->var != NULL )
522 		{
523 			if ( **(char **)cp->var != '\0' )
524 			{
525 				char	*p;
526 
527 				fprintf (fp, "%s:\t", cp->label);
528 				for ( p = *(char **)cp->var; *p; p++ )
529 					putc (toupper (*p), fp);
530 				// fprintf (fp, "\n");
531 			}
532 			else
533 				fprintf (fp, "%s:\tNONE", cp->label);
534 		}
535 		if ( cp->type == CONF_LEVEL )
536 			fprintf (fp, "\t\t# (NONE|DEBUG|INFO|NOTICE|WARNING|ERROR|FATAL)\n");
537 		else
538 			fprintf (fp, "\t\t# (NONE|USER|DAEMON|LOCAL[0-7])\n");
539 		break;
540 	case CONF_STRING:
541 		if ( *(char **)cp->var )
542 			printnl = fprintf (fp, "%s:\t\"%s\"", cp->label, *(char **)cp->var);
543 		break;
544 	case CONF_BOOL:
545 		fprintf (fp, "%s:\t%s", cp->label, bool2str ( *(int*)cp->var ));
546 		printnl = 1;
547 		break;
548 	case CONF_TIMEINT:
549 		lval = *(ulong*)cp->var;	/* in that case it should be of type ulong */
550 		fprintf (fp, "%s:\t%s", cp->label, timeint2str (lval));
551 		if ( lval )
552 			fprintf (fp, "\t\t# (%ld seconds)", lval);
553 		printnl = 1;
554 		break;
555 	case CONF_ALGO:
556 		i = *(int*)cp->var;
557 		if ( i )
558 		{
559 			fprintf (fp, "%s:\t%s ", cp->label, dki_algo2str (i));
560 			fprintf (fp, "\t# (Algorithm ID %d)\n", i);
561 		}
562 		break;
563 	case CONF_SERIAL:
564 		fprintf (fp, "%s:\t", cp->label);
565 		if ( *(serial_form_t*)cp->var == Unixtime )
566 			fprintf (fp, "UnixTime");
567 		else
568 			fprintf (fp, "Incremental");
569 		fprintf (fp, "\t# (UnixTime|Incremental)\n");
570 		break;
571 	case CONF_NSEC3:
572 		fprintf (fp, "%s:\t\t", cp->label);
573 		if ( *(nsec3_t*)cp->var == NSEC3_OFF )
574 			fprintf (fp, "Off");
575 		else if ( *(nsec3_t*)cp->var == NSEC3_ON )
576 			fprintf (fp, "On");
577 		else if ( *(nsec3_t*)cp->var == NSEC3_OPTOUT )
578 			fprintf (fp, "OptOut");
579 		fprintf (fp, "\t\t# (On|Off|OptOut)\n");
580 		break;
581 	case CONF_INT:
582 		fprintf (fp, "%s:\t%d", cp->label, *(int *)cp->var);
583 		printnl = 1;
584 		break;
585 	case CONF_END:
586 		/* NOTREACHED */
587 		break;
588 	}
589 	if ( printnl )
590 	{
591 		if ( cp->desc )
592 		{
593 			if ( printnl < 20 )
594 				putc ('\t', fp);
595 			fprintf (fp, "\t# %s\n", cp->desc);
596 		}
597 		else
598 			putc ('\n', fp);
599 
600 	}
601 }
602 
603 /*****************************************************************
604 **	public function definition
605 *****************************************************************/
606 
setconfigversion(int version)607 void	setconfigversion (int version)
608 {
609 	compversion = version;
610 }
611 
timeint2str(unsigned long val)612 const char	*timeint2str (unsigned long val)
613 {
614 	static	char	str[20+1];
615 
616 	if ( val == 0 )
617 		snprintf (str, sizeof (str), "Unset");
618 	else if ( val % YEARSEC == 0 )
619 		snprintf (str, sizeof (str), "%luy", val / YEARSEC);
620 	else if ( val % WEEKSEC == 0 )
621 		snprintf (str, sizeof (str), "%luw", val / WEEKSEC);
622 	else if ( val % DAYSEC == 0 )
623 		snprintf (str, sizeof (str), "%lud", val / DAYSEC);
624 	else if ( val % HOURSEC == 0 )
625 		snprintf (str, sizeof (str), "%luh", val / HOURSEC);
626 	else if ( val % MINSEC == 0 )
627 		snprintf (str, sizeof (str), "%lum", val / MINSEC);
628 	else
629 		snprintf (str, sizeof (str), "%lus", val);
630 
631 	return str;
632 }
633 
634 
635 /*****************************************************************
636 **	loadconfig (file, conf)
637 **	Loads a config file into the "conf" structure pointed to by "z".
638 **	If "z" is NULL then a new conf struct will be dynamically
639 **	allocated.
640 **	If no filename is given the conf struct will be initialized
641 **	with the builtin default config
642 *****************************************************************/
loadconfig(const char * filename,zconf_t * z)643 zconf_t	*loadconfig (const char *filename, zconf_t *z)
644 {
645 	FILE		*fp;
646 	char		buf[1023+1];
647 	unsigned int	line;
648 
649 	if ( z == NULL )	/* allocate new memory for zconf_t */
650 	{
651 		if ( (z = calloc (1, sizeof (zconf_t))) == NULL )
652 			return NULL;
653 
654 		if ( filename && *filename )
655 			memcpy (z, &def, sizeof (zconf_t));	/* init new struct with defaults */
656 	}
657 
658 	if ( filename == NULL || *filename == '\0' )	/* no file name given... */
659 	{
660 		dbg_val0("loadconfig (NULL)\n");
661 		memcpy (z, &def, sizeof (zconf_t));		/* ..then init with defaults */
662 		return z;
663 	}
664 
665 	dbg_val1 ("loadconfig (%s)\n", filename);
666 	set_all_varptr (z, NULL);
667 
668 	if ( (fp = fopen(filename, "r")) == NULL )
669 		fatal ("Could not open config file \"%s\"\n", filename);
670 
671 	line = 0;
672 	while (fgets(buf, sizeof(buf), fp))
673 		parseconfigline (buf, ++line, z);
674 
675 	fclose(fp);
676 	return z;
677 }
678 
679 # define	STRCONFIG_DELIMITER	";\r\n"
loadconfig_fromstr(const char * str,zconf_t * z)680 zconf_t	*loadconfig_fromstr (const char *str, zconf_t *z)
681 {
682 	char		*buf;
683 	char		*tok,	*toksave;
684 	unsigned int	line;
685 
686 	if ( z == NULL )
687 	{
688 		if ( (z = calloc (1, sizeof (zconf_t))) == NULL )
689 			return NULL;
690 		memcpy (z, &def, sizeof (zconf_t));		/* init with defaults */
691 	}
692 
693 	if ( str == NULL || *str == '\0' )
694 	{
695 		dbg_val0("loadconfig_fromstr (NULL)\n");
696 		memcpy (z, &def, sizeof (zconf_t));		/* init with defaults */
697 		return z;
698 	}
699 
700 	dbg_val1 ("loadconfig_fromstr (\"%s\")\n", str);
701 	set_all_varptr (z, NULL);
702 
703 	/* str is const, so we have to copy it into a new buffer */
704 	if ( (buf = strdup (str)) == NULL )
705 		fatal ("loadconfig_fromstr: Out of memory");
706 
707 	line = 0;
708 	tok = strtok_r (buf, STRCONFIG_DELIMITER, &toksave);
709 	while ( tok )
710 	{
711 		line++;
712 		parseconfigline (tok, line, z);
713 		tok = strtok_r (NULL, STRCONFIG_DELIMITER, &toksave);
714 	}
715 	free (buf);
716 	return z;
717 }
718 
719 /*****************************************************************
720 **	dupconfig (config)
721 **	duplicate config struct and return a ptr to the new struct
722 *****************************************************************/
dupconfig(const zconf_t * conf)723 zconf_t	*dupconfig (const zconf_t *conf)
724 {
725 	zconf_t	*z;
726 
727 	assert (conf != NULL);
728 
729 	if ( (z = calloc (1, sizeof (zconf_t))) == NULL )
730 		return NULL;
731 
732 	memcpy (z, conf, sizeof (zconf_t));
733 
734 	return z;
735 }
736 
737 /*****************************************************************
738 **	freeconfig (config)
739 **	free memory for config struct and return a NULL ptr
740 *****************************************************************/
freeconfig(zconf_t * conf)741 zconf_t	*freeconfig (zconf_t *conf)
742 {
743 	if (conf != NULL);
744 		free (conf);
745 
746 	return (zconf_t *)NULL;
747 }
748 
749 /*****************************************************************
750 **	setconfigpar (entry, pval)
751 *****************************************************************/
setconfigpar(zconf_t * config,char * entry,const void * pval)752 int	setconfigpar (zconf_t *config, char *entry, const void *pval)
753 {
754 	char	*str;
755 	zconf_para_t	*c;
756 
757 	set_all_varptr (config, NULL);
758 
759 	for ( c = confpara; c->type != CONF_END; c++ )
760 		if ( strcasecmp (entry, c->label) == 0 )
761 		{
762 			switch ( c->type )
763 			{
764 			case CONF_VERSION:
765 				break;
766 			case CONF_LEVEL:
767 			case CONF_FACILITY:
768 			case CONF_STRING:
769 				if ( pval )
770 				{
771 					str = strdup ((char *)pval);
772 					str_untaint (str);	/* remove "bad" characters */
773 				}
774 				else
775 					str = NULL;
776 				*((char **)c->var) = str;
777 				break;
778 			case CONF_BOOL:
779 				/* fall through */
780 			case CONF_ALGO:
781 				/* fall through */
782 			case CONF_INT:
783 				*((int *)c->var) = *((int *)pval);
784 				break;
785 			case CONF_TIMEINT:
786 				*((long *)c->var) = *((long *)pval);
787 				break;
788 			case CONF_NSEC3:
789 				*((nsec3_t *)c->var) = *((nsec3_t *)pval);
790 				break;
791 			case CONF_SERIAL:
792 				*((serial_form_t *)c->var) = *((serial_form_t *)pval);
793 				break;
794 			case CONF_COMMENT:
795 			case CONF_END:
796 				/* NOTREACHED */
797 				break;
798 			}
799 			return 1;
800 		}
801 	return 0;
802 }
803 
804 /*****************************************************************
805 **	printconfig (fname, config)
806 *****************************************************************/
printconfig(const char * fname,const zconf_t * z)807 int	printconfig (const char *fname, const zconf_t *z)
808 {
809 	zconf_para_t	*cp;
810 	FILE	*fp;
811 
812 	if ( z == NULL )
813 		return 0;
814 
815 	fp = stdout;
816 	if ( fname && *fname )
817 	{
818 		if ( strcmp (fname, "stdout") == 0 )
819 			fp = stdout;
820 		else if ( strcmp (fname, "stderr") == 0 )
821 			fp = stderr;
822 		else if ( (fp = fopen(fname, "w")) == NULL )
823 		{
824 			error ("Could not open config file \"%s\" for writing\n", fname);
825 			return -1;
826 		}
827 	}
828 
829 	set_all_varptr ((zconf_t *)z, NULL);
830 
831 	for ( cp = confpara; cp->type != CONF_END; cp++ )	/* loop through all parameter */
832 		if ( iscompatible (cp) )	/* is parameter compatible to current version? */
833 			printconfigline (fp, cp);	/* print it out */
834 
835 	if ( fp && fp != stdout && fp != stderr )
836 		fclose (fp);
837 
838 	return 1;
839 }
840 
841 /*****************************************************************
842 **	printconfigdiff (fname, conf_a, conf_b)
843 *****************************************************************/
printconfigdiff(const char * fname,const zconf_t * ref,const zconf_t * z)844 int	printconfigdiff (const char *fname, const zconf_t *ref, const zconf_t *z)
845 {
846 	zconf_para_t	*cp;
847 	int	eq;
848 	char	*p1,	*p2;
849 	FILE	*fp;
850 
851 	if ( ref == NULL || z == NULL )
852 		return 0;
853 
854 	fp = NULL;
855 	if ( fname && *fname )
856 	{
857 		if ( strcmp (fname, "stdout") == 0 )
858 			fp = stdout;
859 		else if ( strcmp (fname, "stderr") == 0 )
860 			fp = stderr;
861 		else if ( (fp = fopen(fname, "w")) == NULL )
862 		{
863 			error ("Could not open config file \"%s\" for writing\n", fname);
864 			return -1;
865 		}
866 	}
867 
868 	set_all_varptr ((zconf_t *)z, ref);
869 
870 	for ( cp = confpara; cp->type != CONF_END; cp++ )	/* loop through all parameter */
871 	{
872 		eq = 0;
873 		if ( iscmdline (cp) )	/* skip command line parameter */
874 			continue;
875 
876 		if ( !iscompatible (cp) )	/* is parameter compatible to current version? */
877 			continue;
878 
879 		if ( cp->type == CONF_VERSION || cp->type == CONF_END || cp->type == CONF_COMMENT )
880 			continue;
881 
882 		dbg_val5 ("printconfigdiff: %d: %s %d %d %d\n", cp->type, cp->label,
883 						compversion, cp->used_since, cp->used_till);
884 		assert ( cp->var2 != NULL );
885 
886 		switch ( cp->type )
887 		{
888 		case CONF_VERSION:
889 		case CONF_END:
890 		case CONF_COMMENT:
891 			continue;
892 		case CONF_NSEC3:
893 			eq = ( *(nsec3_t *)cp->var == *(nsec3_t *)cp->var2 );
894 			break;
895 		case CONF_SERIAL:
896 			eq = ( *(serial_form_t *)cp->var == *(serial_form_t *)cp->var2 );
897 			break;
898 		case CONF_BOOL:
899 		case CONF_ALGO:
900 		case CONF_INT:
901 			eq = ( *(int *)cp->var == *(int *)cp->var2 );
902 			break;
903 		case CONF_TIMEINT:
904 			eq = ( *(long *)cp->var == *(long *)cp->var2 );
905 			break;
906 		case CONF_LEVEL:
907 		case CONF_FACILITY:
908 		case CONF_STRING:
909 			p1 = *(char **)cp->var;
910 			p2 = *(char **)cp->var2;
911 			if ( p1 && p2 )
912 				eq = strcmp (p1, p2) == 0;
913 			else if ( p1 == NULL || p2 == NULL )
914 				eq = 0;
915 			else
916 				eq = 1;
917 		}
918 		if ( !eq )
919 			printconfigline (fp, cp);	/* print it out */
920 	}
921 
922 	if ( fp && fp != stdout && fp != stderr )
923 		fclose (fp);
924 
925 	return 1;
926 }
927 
928 /*****************************************************************
929 **	checkconfig (config)
930 *****************************************************************/
checkconfig(const zconf_t * z)931 int	checkconfig (const zconf_t *z)
932 {
933 	int	ret;
934 	long	max_ttl;
935 
936 	if ( z == NULL )
937 		return 1;
938 
939 	max_ttl = z->max_ttl;
940 	if ( max_ttl <= 0 )
941 		max_ttl = z->sigvalidity;
942 
943 	ret = 0;
944 	if ( z->k_random && strcmp (z->k_random, "/dev/urandom") == 0 )
945 		ret = fprintf (stderr, "random device without enough entropie used for KSK generation \n");
946 	if ( z->z_random && strcmp (z->z_random, "/dev/urandom") == 0 )
947 		ret = fprintf (stderr, "random device without enough entropie used for ZSK generation\n");
948 
949 	if ( z->k_bits < 512 || z->z_bits < 512 )
950 		ret = fprintf (stderr, "Algorithm requires a bit size of at least 512 \n");
951 
952 	if ( z->k_algo == DK_ALGO_RSASHA512 && ( z->k_bits < 1024 || z->z_bits < 1024 ) )
953 		ret = fprintf (stderr, "Algorithm RSASHA 512 requires a bit size of at least 1024 \n");
954 
955 	if ( z->saltbits < 4 )
956 		ret = fprintf (stderr, "Saltlength must be at least 4 bits\n");
957 	if ( z->saltbits > 128 )
958 	{
959 		fprintf (stderr, "While the maximum is 520 bits of salt, it's not recommended to use more than 128 bits.\n");
960 		ret = fprintf (stderr, "The current value is %d bits\n", z->saltbits);
961 	}
962 
963 	if ( z->sigvalidity < (1 * DAYSEC) || z->sigvalidity > (12 * WEEKSEC) )
964 	{
965 		fprintf (stderr, "Signature should be valid for at least 1 day and no longer than 3 month (12 weeks)\n");
966 		ret = fprintf (stderr, "The current value is %s\n", timeint2str (z->sigvalidity));
967 	}
968 
969 	if ( z->max_ttl <= 0 )
970 	{
971 		ret = fprintf (stderr, "The max TTL is unknown which results in suboptimal key rollover.\n");
972 		fprintf (stderr, "Please set max_ttl to the maximum ttl used in the zone (run zkt-conf -w zone.db)\n");
973 	}
974 	else
975 		if ( max_ttl > z->sigvalidity/2 )
976 			ret = fprintf (stderr, "Max TTL (%ld) should be a few times smaller than the signature validity (%ld)\n",
977 								max_ttl, z->sigvalidity);
978 
979 	// if ( z->resign > (z->sigvalidity*5/6) - (max_ttl + z->proptime) )
980 	if ( z->resign > (z->sigvalidity*5/6) )
981 	{
982 		fprintf (stderr, "Re-signing interval (%s) should be less than ", timeint2str (z->resign));
983 		ret = fprintf (stderr, "5/6 of sigvalidity (%s)\n", timeint2str (z->sigvalidity));
984 	}
985 
986 	if ( z->max_ttl > 0 && z->resign > (z->sigvalidity - max_ttl) )
987 	{
988 		fprintf (stderr, "Re-signing interval (%s) should be ", timeint2str (z->resign));
989 		fprintf (stderr, "end at least one max_ttl (%ld) before the end of ", max_ttl);
990 		ret = fprintf (stderr, "signature lifetime (%ld) (%s)\n", z->sigvalidity, timeint2str(z->sigvalidity - max_ttl));
991 	}
992 
993 	if ( z->z_life > (24 * WEEKSEC) * (z->z_bits / 512.) )
994 	{
995 		fprintf (stderr, "Lifetime of zone signing key (%s) ", timeint2str (z->z_life));
996 		fprintf (stderr, "seems a little bit high ");
997 		ret = fprintf (stderr, "(In respect of key size (%d))\n", z->z_bits);
998 	}
999 
1000 	if ( z->k_life > 0 && z->k_life <= z->z_life )
1001 	{
1002 		fprintf (stderr, "Lifetime of key signing key (%s) ", timeint2str (z->k_life));
1003 		ret = fprintf (stderr, "should be greater than lifetime of zsk\n");
1004 	}
1005 	if ( z->k_life > 0 && z->k_life > (52 * WEEKSEC) * (z->k_bits / 512.) )
1006 	{
1007 		fprintf (stderr, "Lifetime of key signing key (%s) ", timeint2str (z->k_life));
1008 		fprintf (stderr, "seems a little bit high ");
1009 		ret = fprintf (stderr, "(In respect of key size (%d))\n", z->k_bits);
1010 	}
1011 
1012 	return !ret;
1013 }
1014 
1015 #ifdef CONF_TEST
1016 const char *progname;
1017 static	zconf_t	*config;
1018 
main(int argc,char * argv[])1019 main (int argc, char *argv[])
1020 {
1021 	char	*optstr;
1022 	int	val;
1023 
1024 	progname = *argv;
1025 
1026 	config = loadconfig ("", (zconf_t *) NULL);	/* load built in defaults */
1027 
1028 	while ( --argc >= 1 )
1029 	{
1030 		optstr = *++argv;
1031 		config = loadconfig_fromstr (optstr, config);
1032 	}
1033 
1034 	val = 1;
1035 	setconfigpar (config, "-v", &val);
1036 	val = 2;
1037 	setconfigpar (config, "verboselog", &val);
1038 	val = 1;
1039 	setconfigpar (config, "recursive", &val);
1040 	val = 1200;
1041 	setconfigpar (config, "propagation", &val);
1042 
1043 	printconfig ("stdout", config);
1044 }
1045 #endif
1046