1 /* $NetBSD: main.c,v 1.6.6.2 2008/11/27 15:25:26 vanhu Exp $ */
2
3 /* Id: main.c,v 1.25 2006/06/20 20:31:34 manubsd Exp */
4
5 /*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include "config.h"
35
36 #include <sys/types.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
39 #include <sys/stat.h>
40
41 #include <netinet/in.h>
42
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <string.h>
46 #include <errno.h>
47 #include <limits.h>
48 #ifdef HAVE_UNISTD_H
49 #include <unistd.h>
50 #endif
51 #include <paths.h>
52 #include <err.h>
53
54 /*
55 * If we're using a debugging malloc library, this may define our
56 * wrapper stubs.
57 */
58 #define RACOON_MAIN_PROGRAM
59 #include "gcmalloc.h"
60
61 #include "var.h"
62 #include "misc.h"
63 #include "vmbuf.h"
64 #include "plog.h"
65 #include "debug.h"
66
67 #include "cfparse_proto.h"
68 #include "isakmp_var.h"
69 #ifdef ENABLE_HYBRID
70 #include <resolv.h>
71 #include "isakmp.h"
72 #include "isakmp_xauth.h"
73 #include "isakmp_cfg.h"
74 #endif
75 #include "remoteconf.h"
76 #include "localconf.h"
77 #include "session.h"
78 #include "oakley.h"
79 #include "pfkey.h"
80 #include "policy.h"
81 #include "crypto_openssl.h"
82 #include "backupsa.h"
83 #include "vendorid.h"
84
85 #include "package_version.h"
86
87 int f_local = 0; /* local test mode. behave like a wall. */
88 int vflag = 1; /* for print-isakmp.c */
89 static int loading_sa = 0; /* install sa when racoon boots up. */
90 static int dump_config = 0; /* dump parsed config file. */
91
92 #ifdef TOP_PACKAGE
93 static char version[] = "@(#)" TOP_PACKAGE_STRING " (" TOP_PACKAGE_URL ")";
94 #else /* TOP_PACKAGE */
95 static char version[] = "@(#) racoon / IPsec-tools";
96 #endif /* TOP_PACKAGE */
97
98 int main __P((int, char **));
99 static void usage __P((void));
100 static void parse __P((int, char **));
101 #if 0
102 static void cleanup_pidfile __P((void));
103 #endif
104
105 void
usage()106 usage()
107 {
108 printf("usage: racoon [-BdFv%s] %s[-f (file)] [-l (file)] [-p (port)]\n",
109 #ifdef INET6
110 "46",
111 #else
112 "",
113 #endif
114 #ifdef ENABLE_ADMINPORT
115 "[-a (port)] "
116 #else
117 ""
118 #endif
119 );
120 printf(" -B: install SA to the kernel from the file "
121 "specified by the configuration file.\n");
122 printf(" -d: debug level, more -d will generate more debug message.\n");
123 printf(" -C: dump parsed config file.\n");
124 printf(" -L: include location in debug messages\n");
125 printf(" -F: run in foreground, do not become daemon.\n");
126 printf(" -v: be more verbose\n");
127 #ifdef INET6
128 printf(" -4: IPv4 mode.\n");
129 printf(" -6: IPv6 mode.\n");
130 #endif
131 #ifdef ENABLE_ADMINPORT
132 printf(" -a: port number for admin port.\n");
133 #endif
134 printf(" -f: pathname for configuration file.\n");
135 printf(" -l: pathname for log file.\n");
136 printf(" -p: port number for isakmp (default: %d).\n", PORT_ISAKMP);
137 printf(" -P: port number for NAT-T (default: %d).\n", PORT_ISAKMP_NATT);
138 exit(1);
139 }
140
141 int
main(ac,av)142 main(ac, av)
143 int ac;
144 char **av;
145 {
146 int error;
147
148 if (geteuid() != 0) {
149 errx(1, "must be root to invoke this program.");
150 /* NOTREACHED*/
151 }
152
153 /*
154 * Don't let anyone read files I write. Although some files (such as
155 * the PID file) can be other readable, we dare to use the global mask,
156 * because racoon uses fopen(3), which can't specify the permission
157 * at the creation time.
158 */
159 umask(077);
160 if (umask(077) != 077) {
161 errx(1, "could not set umask");
162 /* NOTREACHED*/
163 }
164
165 #ifdef DEBUG_RECORD_MALLOCATION
166 DRM_init();
167 #endif
168
169 #ifdef HAVE_SECCTX
170 init_avc();
171 #endif
172 eay_init();
173 initlcconf();
174 initrmconf();
175 oakley_dhinit();
176 compute_vendorids();
177
178 parse(ac, av);
179
180 ploginit();
181
182 plog(LLV_INFO, LOCATION, NULL, "%s\n", version);
183 plog(LLV_INFO, LOCATION, NULL, "@(#)"
184 "This product linked %s (http://www.openssl.org/)"
185 "\n", eay_version());
186 plog(LLV_INFO, LOCATION, NULL, "Reading configuration from \"%s\"\n",
187 lcconf->racoon_conf);
188
189 if (pfkey_init() < 0) {
190 errx(1, "something error happened "
191 "while pfkey initializing.");
192 /* NOTREACHED*/
193 }
194
195 #ifdef ENABLE_HYBRID
196 if (isakmp_cfg_init(ISAKMP_CFG_INIT_COLD))
197 errx(1, "could not initialize ISAKMP mode config structures");
198 #endif
199
200 #ifdef HAVE_LIBLDAP
201 if (xauth_ldap_init() != 0)
202 errx(1, "could not initialize libldap");
203 #endif
204
205 /*
206 * in order to prefer the parameters by command line,
207 * saving some parameters before parsing configuration file.
208 */
209 save_params();
210 error = cfparse();
211 if (error != 0)
212 errx(1, "failed to parse configuration file.");
213 restore_params();
214
215 #ifdef ENABLE_HYBRID
216 if(isakmp_cfg_config.network4 && isakmp_cfg_config.pool_size == 0)
217 if ((error = isakmp_cfg_resize_pool(ISAKMP_CFG_MAX_CNX)) != 0)
218 return error;
219 #endif
220
221 if (dump_config)
222 dumprmconf ();
223
224 #ifdef HAVE_LIBRADIUS
225 if (xauth_radius_init() != 0) {
226 errx(1, "could not initialize libradius");
227 /* NOTREACHED*/
228 }
229 #endif
230
231 /*
232 * install SAs from the specified file. If the file is not specified
233 * by the configuration file, racoon will exit.
234 */
235 if (loading_sa && !f_local) {
236 if (backupsa_from_file() != 0)
237 errx(1, "something error happened "
238 "SA recovering.");
239 }
240
241 if (f_foreground)
242 close(0);
243 else {
244 if (daemon(0, 0) < 0) {
245 errx(1, "failed to be daemon. (%s)",
246 strerror(errno));
247 }
248 #ifndef __linux__
249 /*
250 * In case somebody has started inetd manually, we need to
251 * clear the logname, so that old servers run as root do not
252 * get the user's logname..
253 */
254 if (setlogin("") < 0) {
255 plog(LLV_ERROR, LOCATION, NULL,
256 "cannot clear logname: %s\n", strerror(errno));
257 /* no big deal if it fails.. */
258 }
259 #endif
260 if (!f_local) {
261 #if 0
262 if (atexit(cleanup_pidfile) < 0) {
263 plog(LLV_ERROR, LOCATION, NULL,
264 "cannot register pidfile cleanup");
265 }
266 #endif
267 }
268 }
269
270 session();
271
272 exit(0);
273 }
274
275 #if 0
276 static void
277 cleanup_pidfile()
278 {
279 pid_t p = getpid();
280
281 /* if it's not child process, clean everything */
282 if (racoon_pid == p) {
283 const char *pid_file = _PATH_VARRUN "racoon.pid";
284
285 (void) unlink(pid_file);
286 }
287 }
288 #endif
289
290 static void
parse(ac,av)291 parse(ac, av)
292 int ac;
293 char **av;
294 {
295 extern char *optarg;
296 extern int optind;
297 int c;
298 #ifdef YYDEBUG
299 extern int yydebug;
300 #endif
301
302 pname = strrchr(*av, '/');
303 if (pname)
304 pname++;
305 else
306 pname = *av;
307
308 while ((c = getopt(ac, av, "dLFp:P:a:f:l:vZBC"
309 #ifdef YYDEBUG
310 "y"
311 #endif
312 #ifdef INET6
313 "46"
314 #endif
315 )) != -1) {
316 switch (c) {
317 case 'd':
318 loglevel++;
319 break;
320 case 'L':
321 print_location = 1;
322 break;
323 case 'F':
324 printf("Foreground mode.\n");
325 f_foreground = 1;
326 break;
327 case 'p':
328 lcconf->port_isakmp = atoi(optarg);
329 break;
330 case 'P':
331 lcconf->port_isakmp_natt = atoi(optarg);
332 break;
333 case 'a':
334 #ifdef ENABLE_ADMINPORT
335 lcconf->port_admin = atoi(optarg);
336 break;
337 #else
338 fprintf(stderr, "%s: the option is disabled "
339 "in the configuration\n", pname);
340 exit(1);
341 #endif
342 case 'f':
343 lcconf->racoon_conf = optarg;
344 break;
345 case 'l':
346 plogset(optarg);
347 break;
348 case 'v':
349 vflag++;
350 break;
351 case 'Z':
352 /*
353 * only local test.
354 * To specify -Z option and to choice a appropriate
355 * port number for ISAKMP, you can launch some racoons
356 * on the local host for debug.
357 * pk_sendadd() on initiator side is always failed
358 * even if this flag is used. Because there is same
359 * spi in the SAD which is inserted by pk_sendgetspi()
360 * on responder side.
361 */
362 printf("Local test mode.\n");
363 f_local = 1;
364 break;
365 #ifdef YYDEBUG
366 case 'y':
367 yydebug = 1;
368 break;
369 #endif
370 #ifdef INET6
371 case '4':
372 lcconf->default_af = AF_INET;
373 break;
374 case '6':
375 lcconf->default_af = AF_INET6;
376 break;
377 #endif
378 case 'B':
379 loading_sa++;
380 break;
381 case 'C':
382 dump_config++;
383 break;
384 default:
385 usage();
386 /* NOTREACHED */
387 }
388 }
389 ac -= optind;
390 av += optind;
391
392 if (ac != 0) {
393 usage();
394 /* NOTREACHED */
395 }
396
397 return;
398 }
399