1 /*	$NetBSD: zkt-conf.c,v 1.1.1.1 2015/07/08 15:37:48 christos Exp $	*/
2 
3 /*****************************************************************
4 **
5 **	@(#) zkt-conf.c (c) Jan 2005 / Jan 2010  Holger Zuleger  hznet.de
6 **
7 **	A config file utility for the DNSSEC Zone Key Tool
8 **
9 **	Copyright (c) 2005 - 2008, Holger Zuleger HZnet. All rights reserved.
10 **
11 **	This software is open source.
12 **
13 **	Redistribution and use in source and binary forms, with or without
14 **	modification, are permitted provided that the following conditions
15 **	are met:
16 **
17 **	Redistributions of source code must retain the above copyright notice,
18 **	this list of conditions and the following disclaimer.
19 **
20 **	Redistributions in binary form must reproduce the above copyright notice,
21 **	this list of conditions and the following disclaimer in the documentation
22 **	and/or other materials provided with the distribution.
23 **
24 **	Neither the name of Holger Zuleger HZnet nor the names of its contributors may
25 **	be used to endorse or promote products derived from this software without
26 **	specific prior written permission.
27 **
28 **	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 **	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 **	TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 **	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
32 **	LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 **	CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 **	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 **	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 **	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 **	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 **	POSSIBILITY OF SUCH DAMAGE.
39 **
40 *****************************************************************/
41 
42 # include <stdio.h>
43 # include <stdlib.h>	/* abort(), exit(), ... */
44 # include <string.h>
45 # include <dirent.h>
46 # include <assert.h>
47 # include <unistd.h>
48 # include <ctype.h>
49 # include <time.h>
50 
51 #ifdef HAVE_CONFIG_H
52 # include <config.h>
53 #endif
54 # include "config_zkt.h"
55 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
56 # include <getopt.h>
57 #endif
58 
59 # include "debug.h"
60 # include "misc.h"
61 # include "zfparse.h"
62 # include "zconf.h"
63 
64 extern  int	optopt;
65 extern  int	opterr;
66 extern  int	optind;
67 extern  char	*optarg;
68 const	char	*progname;
69 
70 static	const	char	*view = "";
71 static	int	writeflag = 0;
72 static	int	allflag = 0;
73 static	int	testflag = 0;
74 
75 # define	short_options	":aC:c:O:dlstvwV:rh"
76 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
77 static struct option long_options[] = {
78 	{"compability",		required_argument, NULL, 'C'},
79 	{"config",		required_argument, NULL, 'c'},
80 	{"option",		required_argument, NULL, 'O'},
81 	{"config-option",	required_argument, NULL, 'O'},
82 	{"default",		no_argument, NULL, 'd'},
83 	{"sidecfg",		no_argument, NULL, 's'},
84 	{"localcfg",		no_argument, NULL, 'l'},
85 	{"all-values",		no_argument, NULL, 'a'},
86 	{"test",		no_argument, NULL, 't'},
87 	{"overwrite",		no_argument, NULL, 'w'},
88 	{"version",		no_argument, NULL, 'v' },
89 	{"write",		no_argument, NULL, 'w'},
90 	{"view",		required_argument, NULL, 'V' },
91 	{"help",		no_argument, NULL, 'h'},
92 	{0, 0, 0, 0}
93 };
94 #endif
95 
96 static	void    usage (char *mesg);
97 
98 
99 int	main (int argc, char *argv[])
100 {
101 	int	c;
102 	int	opt_index;
103 	int	major = 0;
104 	int	minor = 0;
105 	int	revision = 0;
106 	const	char	*file;
107 	const	char	*defconfname = NULL;
108 	const	char	*confname = NULL;
109 	char	*p;
110 	char	str[254+1];
111 	zconf_t	*refconfig = NULL;
112 	zconf_t	*config;
113 
114 	progname = *argv;
115 	if ( (p = strrchr (progname, '/')) )
116 		progname = ++p;
117 	view = getnameappendix (progname, "zkt-conf");
118 
119 	defconfname = getdefconfname (view);
120 	dbg_val0 ("Load built in config\n");
121 	config = loadconfig ("", (zconf_t *)NULL);	/* load built in config */
122 
123 	if ( fileexist (defconfname) )			/* load default config file */
124 	{
125 		dbg_val ("Load site wide config file \"%s\"\n", defconfname);
126 		config = loadconfig (defconfname, config);
127 	}
128 	if ( config == NULL )
129 		fatal ("Out of memory\n");
130 	confname = defconfname;
131 
132         opterr = 0;
133 	opt_index = 0;
134 
135 	/* set current config version based on ZKT version */
136 	switch ( sscanf (ZKT_VERSION, "%d.%d.%d", &major, &minor, &revision) )
137 	{
138 	case 3:	major = (major * 100) + (minor * 10) + revision;	break;
139 	case 2:	major = (major * 100) + (minor * 10);	break;
140 	case 1: major = major * 100;	break;
141 	default:
142 		usage ("illegal release number");
143 	}
144 	setconfigversion (major);
145 
146 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
147 	while ( (c = getopt_long (argc, argv, short_options, long_options, &opt_index)) != -1 )
148 #else
149 	while ( (c = getopt (argc, argv, short_options)) != -1 )
150 #endif
151 	{
152 		switch ( c )
153 		{
154 		case 'V':		/* view name */
155 			view = optarg;
156 			defconfname = getdefconfname (view);
157 			if ( fileexist (defconfname) )		/* load default config file */
158 				config = loadconfig (defconfname, config);
159 			if ( config == NULL )
160 				fatal ("Out of memory\n");
161 			confname = defconfname;
162 			break;
163 		case 'O':		/* read option from commandline */
164 			config = loadconfig_fromstr (optarg, config);
165 			break;
166 		case 'C':
167 			switch ( sscanf (optarg, "%d.%d.%d", &major, &minor, &revision) )
168 			{
169 			case 3:	major = (major * 100) + (minor * 10) + revision;	break;
170 			case 2:	major = (major * 100) + (minor * 10);	break;
171 			case 1: major = major * 100;	break;
172 			default:
173 				usage ("illegal release number");
174 			}
175 			setconfigversion (major);
176 			break;
177 		case 'c':
178 			if ( *optarg == '\0' )
179 				usage ("empty config file name");
180 			config = loadconfig (optarg, config);
181 			if ( *optarg == '-' || strcmp (optarg, "stdin") == 0 )
182 				confname = "stdout";
183 			else
184 				confname = optarg;
185 			break;
186 		case 'd':		/* built-in default config */
187 			config = loadconfig ("", config);	/* load built-in config */
188 			confname = defconfname;
189 			break;
190 		case 's':		/* side wide config */
191 			/* this is the default **/
192 			break;
193 		case 'a':		/* set all flag */
194 			allflag = 1;
195 			break;
196 		case 'l':		/* local config file */
197 			refconfig = dupconfig (config);	/* duplicate current config */
198 			confname = LOCALCONF_FILE;
199 			if ( fileexist (LOCALCONF_FILE) )	/* try to load local config file */
200 			{
201 				dbg_val ("Load local config file \"%s\"\n", LOCALCONF_FILE);
202 				config = loadconfig (LOCALCONF_FILE, config);
203 			}
204 			else if ( !writeflag )
205 				usage ("error: no local config file found");
206 			break;
207 		case 't':		/* test config */
208 			testflag = 1;
209 			break;
210 		case 'v':		/* version */
211 			fprintf (stderr, "%s version %s compiled for BIND version %d\n",
212 							progname, ZKT_VERSION, BIND_VERSION);
213 			fprintf (stderr, "ZKT %s\n", ZKT_COPYRIGHT);
214 			return 0;
215 			break;
216 		case 'w':		/* write back conf file */
217 			writeflag = 1;
218 			break;
219 		case 'h':		/* print help */
220 			usage ("");
221 			break;
222 		case ':':
223 			snprintf (str, sizeof(str), "option \"-%c\" requires an argument.",
224 										optopt);
225 			usage (str);
226 			break;
227 		case '?':
228 			if ( isprint (optopt) )
229 				snprintf (str, sizeof(str), "Unknown option \"-%c\".",
230 										optopt);
231 			else
232 				snprintf (str, sizeof (str), "Unknown option char \\x%x.",
233 										optopt);
234 			usage (str);
235 			break;
236 		default:
237 			abort();
238 		}
239 	}
240 
241 	c = optind;
242 	if ( c >= argc )	/* no arguments given on commandline */
243 	{
244 		if ( testflag )
245 		{
246 			if ( checkconfig (config) )
247 				fprintf (stderr, "All config file parameter seems to be ok\n");
248 		}
249 		else
250 		{
251 			if ( !writeflag )	/* print to stdout */
252 				confname = "stdout";
253 
254 			if ( refconfig )	/* have we seen a local config file ? */
255 				if ( allflag )
256 					printconfig (confname, config);
257 				else
258 					printconfigdiff (confname, refconfig, config);
259 			else
260 				printconfig (confname, config);
261 		}
262 	}
263 	else	/* command line argument found: use it as name of zone file */
264 	{
265 		char	includefiles[1023+1];	/* list of include files */
266 		size_t	filelistsize;		/* size of list */
267 		long	minttl;
268 		long	maxttl;
269 		int	keydbfound;
270 		char	*dnskeydb;
271 
272 		file = argv[c++];
273 
274 		dnskeydb = config->keyfile;
275 
276 		minttl = 0x7FFFFFFF;
277 		maxttl = 0;
278 		includefiles[0] = '\0';
279 		filelistsize = sizeof (includefiles);
280 		keydbfound = parsezonefile (file, &minttl, &maxttl, dnskeydb, includefiles, &filelistsize);
281 		if ( keydbfound < 0 )
282 			error ("can't parse zone file %s\n", file);
283 
284 		if ( dnskeydb && !keydbfound )
285 		{
286 			if ( writeflag )
287 			{
288 				addkeydb (file, dnskeydb);
289 				printf ("\"$INCLUDE %s\" directive added to \"%s\"\n", dnskeydb, file);
290 			}
291 			else
292 				printf ("\"$INCLUDE %s\" should be added to \"%s\" (run with option -w)\n",
293 							dnskeydb, file);
294 		}
295 
296 		if ( isflistdelim (*includefiles) )
297 		{
298 			printf ("InclFiles:\t\"%s\"\n", includefiles+1);
299 		}
300 
301 		if ( minttl < (10 * MINSEC) )
302 			fprintf (stderr, "MinimumTTL of %s (%ld seconds) is too low to use it in a signed zone (see RFC4641)\n",
303 							timeint2str (minttl), minttl);
304 		else
305 			fprintf (stderr, "MinimumTTL:\t%s\t# (%ld seconds)\n", timeint2str (minttl), minttl);
306 		fprintf (stdout, "MaximumTTL:\t%s\t# (%ld seconds)\n", timeint2str (maxttl), maxttl);
307 
308 		if ( writeflag )
309 		{
310 			refconfig = dupconfig (config);	/* duplicate current config */
311 			confname = LOCALCONF_FILE;
312 			if ( fileexist (LOCALCONF_FILE) )	/* try to load local config file */
313 			{
314 				dbg_val ("Load local config file \"%s\"\n", LOCALCONF_FILE);
315 				config = loadconfig (LOCALCONF_FILE, config);
316 			}
317 			setconfigpar (config, "MaximumTTL", &maxttl);
318 			printconfigdiff (confname, refconfig, config);
319 		}
320 	}
321 
322 
323 	return 0;
324 }
325 
326 # define	sopt_usage(mesg, value)	fprintf (stderr, mesg, value)
327 #if defined(HAVE_GETOPT_LONG) && HAVE_GETOPT_LONG
328 # define	lopt_usage(mesg, value)	fprintf (stderr, mesg, value)
329 # define	loptstr(lstr, sstr)	lstr
330 #else
331 # define	lopt_usage(mesg, value)
332 # define	loptstr(lstr, sstr)	sstr
333 #endif
334 static	void    usage (char *mesg)
335 {
336 	fprintf (stderr, "%s version %s\n", progname, ZKT_VERSION);
337         if ( mesg && *mesg )
338                 fprintf (stderr, "%s\n", mesg);
339         fprintf (stderr, "\n");
340         fprintf (stderr, "usage: %s -h\n", progname);
341         fprintf (stderr, "usage: %s [-V view] [-w|-t]      -d  [-O <optstr>]\n", progname);
342         fprintf (stderr, "usage: %s [-V view] [-w|-t]     [-s] [-c config] [-O <optstr>]\n", progname);
343         fprintf (stderr, "usage: %s [-V view] [-w|-t] [-a] -l  [-c config] [-O <optstr>]\n", progname);
344         fprintf (stderr, "\n");
345         fprintf (stderr, "usage: %s [-c config] [-w] <zonefile>\n", progname);
346         fprintf (stderr, "\n");
347 	fprintf (stderr, " -V name%s", loptstr (", --view=name\n", ""));
348 	fprintf (stderr, "\t\t specify the view name \n");
349         fprintf (stderr, " -d%s\tprint built-in default config parameter\n", loptstr (", --default", ""));
350         fprintf (stderr, " -s%s\tprint site wide config file parameter (this is the default)\n", loptstr (", --sitecfg", ""));
351         fprintf (stderr, " -l%s\tprint local config file parameter\n", loptstr (", --localcfg", ""));
352         fprintf (stderr, " -a%s\tprint all parameter not only the different one\n", loptstr (", --all", ""));
353         fprintf (stderr, " -c file%s", loptstr (", --config=file\n", ""));
354 	fprintf (stderr, " \t\tread config from <file> instead of %s\n", CONFIG_FILE);
355         fprintf (stderr, " -O optstr%s", loptstr (", --config-option=\"optstr\"\n", ""));
356 	fprintf (stderr, " \t\tread config options from commandline\n");
357         fprintf (stderr, " -t%s\ttest the config parameter if they are useful \n", loptstr (", --test", "\t"));
358         fprintf (stderr, " -w%s\twrite or rewrite config file \n", loptstr (", --write", "\t"));
359         fprintf (stderr, " -h%s\tprint this help \n", loptstr (", --help", "\t"));
360         exit (1);
361 }
362 
363