1 /*
2  * checkconf.c - Miredo conf parser unit test
3  */
4 
5 /***********************************************************************
6  *  Copyright © 2005-2007 Rémi Denis-Courmont.                         *
7  *  This program is free software; you can redistribute and/or modify  *
8  *  it under the terms of the GNU General Public License as published  *
9  *  by the Free Software Foundation; version 2 of the license, or (at  *
10  *  your option) any later version.                                    *
11  *                                                                     *
12  *  This program is distributed in the hope that it will be useful,    *
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of     *
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.               *
15  *  See the GNU General Public License for more details.               *
16  *                                                                     *
17  *  You should have received a copy of the GNU General Public License  *
18  *  along with this program; if not, you can get it from:              *
19  *  http://www.gnu.org/copyleft/gpl.html                               *
20  ***********************************************************************/
21 
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25 
26 #include <gettext.h>
27 #include <locale.h>
28 #include "binreloc.h"
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 #include <string.h>
34 #include <stdbool.h>
35 
36 #include <unistd.h>
37 #include <inttypes.h>
38 #include <netinet/in.h>
39 #include "miredo.h"
40 #include "conf.h"
41 
42 #ifdef HAVE_GETOPT_H
43 # include <getopt.h>
44 #endif
45 
logger(void * fail,bool error,const char * fmt,va_list ap)46 static void logger (void *fail, bool error, const char *fmt, va_list ap)
47 {
48 	*((bool *)fail) = true;
49 	(void)error;
50 
51 	vfprintf (stderr, fmt, ap);
52 	fputc ('\n', stderr);
53 }
54 
55 /* FIXME: use same more clever code as in main.c */
56 static const char conffile[] = SYSCONFDIR"/miredo/miredo.conf";
57 
miredo_checkconf(miredo_conf * conf)58 static int miredo_checkconf (miredo_conf *conf)
59 {
60 	int i, res = 0;
61 	if (!miredo_conf_parse_syslog_facility (conf, "SyslogFacility", &i))
62 		res = -1;
63 
64 	bool client = true;
65 
66 	unsigned line;
67 	char *val = miredo_conf_get (conf, "RelayType", &line);
68 
69 	if (val != NULL)
70 	{
71 		if ((strcasecmp (val, "client") == 0)
72 		 || (strcasecmp (val, "autoclient") == 0))
73 			client = true;
74 		else
75 		if ((strcasecmp (val, "relay") == 0)
76 		 || (strcasecmp (val, "cone") == 0)
77 		 || (strcasecmp (val, "restricted") == 0))
78 			client = false;
79 		else
80 		{
81 			fprintf (stderr, _("Invalid relay type \"%s\" at line %u"),
82 			         val, line);
83 			fputc ('\n', stderr);
84 			res = -1;
85 		}
86 		free (val);
87 	}
88 
89 	uint32_t u32;
90 	uint16_t u16;
91 
92 	if (client)
93 	{
94 #ifdef MIREDO_TEREDO_CLIENT
95 		uint32_t ip = 0;
96 
97 		if (!miredo_conf_parse_IPv4 (conf, "ServerAddress", &ip)
98 		 || !miredo_conf_parse_IPv4 (conf, "ServerAddress2", &u32))
99 			res = -1;
100 
101 		if (ip == 0)
102 		{
103 			fprintf (stderr, "%s\n", _("Server address not specified"));
104 			res = -1;
105 		}
106 #else
107 		fprintf (stderr, "%s\n", _("Unsupported Teredo client mode"));
108 		res = -1;
109 #endif
110 	}
111 	else
112 	{
113 		uint32_t pref;
114 		if (!miredo_conf_parse_teredo_prefix (conf, "Prefix", &pref)
115 		 || !miredo_conf_get_int16 (conf, "InterfaceMTU", &u16, NULL))
116 			res = -1;
117 	}
118 
119 	if (!miredo_conf_parse_IPv4 (conf, "BindAddress", &u32)
120 	 || !miredo_conf_get_int16 (conf, "BindPort", &u16, NULL))
121 		res = -1;
122 
123 	char *str = miredo_conf_get (conf, "InterfaceName", NULL);
124 	if (str != NULL)
125 		free (str);
126 
127 	miredo_conf_clear (conf, 5);
128 	return res;
129 }
130 
131 
miredo_checkconffile(const char * filename)132 static int miredo_checkconffile (const char *filename)
133 {
134 	bool failed = false;
135 	miredo_conf *conf = miredo_conf_create (logger, &failed);
136 
137 	if (conf == NULL)
138 		return -1;
139 
140 	if (!miredo_conf_read_file (conf, filename))
141 		failed = true;
142 	else
143 	if (miredo_checkconf (conf))
144 		failed = true;
145 
146 	miredo_conf_destroy (conf);
147 	if (failed)
148 	{
149 		fprintf (stderr, "%s\n", _("Fatal configuration error"));
150 		return -1;
151 	}
152 	return 0;
153 }
154 
155 
usage(const char * path)156 static int usage (const char *path)
157 {
158 	printf ("Usage: %s [CONF_FILE]\n", path);
159 	return 0;
160 }
161 
162 
main(int argc,char * argv[])163 int main(int argc, char *argv[])
164 {
165 	(void)br_init (NULL);
166 	(void)setlocale (LC_ALL, "");
167 	char *path = br_find_locale_dir (LOCALEDIR);
168 	(void)bindtextdomain (PACKAGE_NAME, path);
169 	free (path);
170 	path = NULL;
171 
172 	static const struct option opts[] =
173 	{
174 		{ "conf",       required_argument, NULL, 'c' },
175 		{ "config",     required_argument, NULL, 'c' },
176 		{ "foreground", no_argument,       NULL, 'f' },
177 		{ "help",       no_argument,       NULL, 'h' },
178 		{ "pidfile",    required_argument, NULL, 'p' },
179 		{ "chroot",     required_argument, NULL, 't' },
180 		{ "chrootdir",  required_argument, NULL, 't' },
181 		{ "user",       required_argument, NULL, 'u' },
182 		{ "username",   required_argument, NULL, 'u' },
183 		{ "version",    no_argument,       NULL, 'V' },
184 		{ NULL,         no_argument,       NULL, '\0'}
185 	};
186 
187 	const char *filename = NULL;
188 
189 	int c;
190 	while ((c = getopt_long (argc, argv, "c:fhp:t:u:V", opts, NULL)) != -1)
191 		switch (c)
192 		{
193 			case 'c':
194 				filename = optarg;
195 				break;
196 
197 			case 'h':
198 				return usage(argv[0]);
199 
200 			case 'V':
201 				return miredo_version();
202 		}
203 
204 	if (optind < argc)
205 		filename = argv[optind++];
206 	else
207 	if (filename == NULL)
208 	{
209 		/* No parameters provided - attempt in source tree test */
210 		const char *srcdir = getenv ("srcdir");
211 
212 		if (srcdir != NULL)
213 			filename = "../misc/miredo.conf";
214 		else
215 			filename = conffile;
216 	}
217 
218 	int res = miredo_checkconffile (filename);
219 
220 	if (path != NULL)
221 		free (path);
222 
223 	return res;
224 }
225