1 /* $NetBSD: main.c,v 1.5 2005/11/21 14:20:29 manu Exp $ */ 2 3 /* Id: main.c,v 1.14.2.3 2005/11/06 17:18:26 monas 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 HAVE_LIBRADIUS 70 #include "isakmp.h" 71 #include "isakmp_xauth.h" 72 #endif 73 #include "remoteconf.h" 74 #include "localconf.h" 75 #include "session.h" 76 #include "oakley.h" 77 #include "pfkey.h" 78 #include "crypto_openssl.h" 79 #include "backupsa.h" 80 #include "vendorid.h" 81 82 #include "package_version.h" 83 84 int f_local = 0; /* local test mode. behave like a wall. */ 85 int vflag = 1; /* for print-isakmp.c */ 86 static int loading_sa = 0; /* install sa when racoon boots up. */ 87 static int dump_config = 0; /* dump parsed config file. */ 88 89 #ifdef TOP_PACKAGE 90 static char version[] = "@(#)" TOP_PACKAGE_STRING " (" TOP_PACKAGE_URL ")"; 91 #else /* TOP_PACKAGE */ 92 static char version[] = "@(#) racoon / IPsec-tools"; 93 #endif /* TOP_PACKAGE */ 94 95 int main __P((int, char **)); 96 static void usage __P((void)); 97 static void parse __P((int, char **)); 98 static void restore_params __P((void)); 99 static void save_params __P((void)); 100 static void saverestore_params __P((int)); 101 #if 0 102 static void cleanup_pidfile __P((void)); 103 #endif 104 105 void 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 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 eay_init(); 170 initlcconf(); 171 initrmconf(); 172 oakley_dhinit(); 173 compute_vendorids(); 174 175 parse(ac, av); 176 177 ploginit(); 178 179 plog(LLV_INFO, LOCATION, NULL, "%s\n", version); 180 plog(LLV_INFO, LOCATION, NULL, "@(#)" 181 "This product linked %s (http://www.openssl.org/)" 182 "\n", eay_version()); 183 184 if (pfkey_init() < 0) { 185 errx(1, "something error happened " 186 "while pfkey initializing."); 187 /* NOTREACHED*/ 188 } 189 190 /* 191 * in order to prefer the parameters by command line, 192 * saving some parameters before parsing configuration file. 193 */ 194 save_params(); 195 error = cfparse(); 196 if (error != 0) 197 errx(1, "failed to parse configuration file."); 198 restore_params(); 199 200 #ifdef HAVE_LIBRADIUS 201 if (xauth_radius_init() != 0) { 202 errx(1, "could not initialize libradius"); 203 /* NOTREACHED*/ 204 } 205 #endif 206 207 if (dump_config) 208 dumprmconf (); 209 210 /* 211 * install SAs from the specified file. If the file is not specified 212 * by the configuration file, racoon will exit. 213 */ 214 if (loading_sa && !f_local) { 215 if (backupsa_from_file() != 0) 216 errx(1, "something error happened " 217 "SA recovering."); 218 } 219 220 if (f_foreground) 221 close(0); 222 else { 223 if (daemon(0, 0) < 0) { 224 errx(1, "failed to be daemon. (%s)", 225 strerror(errno)); 226 } 227 #ifndef __linux__ 228 /* 229 * In case somebody has started inetd manually, we need to 230 * clear the logname, so that old servers run as root do not 231 * get the user's logname.. 232 */ 233 if (setlogin("") < 0) { 234 plog(LLV_ERROR, LOCATION, NULL, 235 "cannot clear logname: %s\n", strerror(errno)); 236 /* no big deal if it fails.. */ 237 } 238 #endif 239 if (!f_local) { 240 #if 0 241 if (atexit(cleanup_pidfile) < 0) { 242 plog(LLV_ERROR, LOCATION, NULL, 243 "cannot register pidfile cleanup"); 244 } 245 #endif 246 } 247 } 248 249 session(); 250 251 exit(0); 252 } 253 254 #if 0 255 static void 256 cleanup_pidfile() 257 { 258 pid_t p = getpid(); 259 260 /* if it's not child process, clean everything */ 261 if (racoon_pid == p) { 262 const char *pid_file = _PATH_VARRUN "racoon.pid"; 263 264 (void) unlink(pid_file); 265 } 266 } 267 #endif 268 269 static void 270 parse(ac, av) 271 int ac; 272 char **av; 273 { 274 extern char *optarg; 275 extern int optind; 276 int c; 277 #ifdef YYDEBUG 278 extern int yydebug; 279 #endif 280 281 pname = strrchr(*av, '/'); 282 if (pname) 283 pname++; 284 else 285 pname = *av; 286 287 while ((c = getopt(ac, av, "dLFp:P:a:f:l:vZBC" 288 #ifdef YYDEBUG 289 "y" 290 #endif 291 #ifdef INET6 292 "46" 293 #endif 294 )) != -1) { 295 switch (c) { 296 case 'd': 297 loglevel++; 298 break; 299 case 'L': 300 print_location = 1; 301 break; 302 case 'F': 303 printf("Foreground mode.\n"); 304 f_foreground = 1; 305 break; 306 case 'p': 307 lcconf->port_isakmp = atoi(optarg); 308 break; 309 case 'P': 310 lcconf->port_isakmp_natt = atoi(optarg); 311 break; 312 case 'a': 313 #ifdef ENABLE_ADMINPORT 314 lcconf->port_admin = atoi(optarg); 315 break; 316 #else 317 fprintf(stderr, "%s: the option is disabled " 318 "in the configuration\n", pname); 319 exit(1); 320 #endif 321 case 'f': 322 lcconf->racoon_conf = optarg; 323 break; 324 case 'l': 325 plogset(optarg); 326 break; 327 case 'v': 328 vflag++; 329 break; 330 case 'Z': 331 /* 332 * only local test. 333 * To specify -Z option and to choice a appropriate 334 * port number for ISAKMP, you can launch some racoons 335 * on the local host for debug. 336 * pk_sendadd() on initiator side is always failed 337 * even if this flag is used. Because there is same 338 * spi in the SAD which is inserted by pk_sendgetspi() 339 * on responder side. 340 */ 341 printf("Local test mode.\n"); 342 f_local = 1; 343 break; 344 #ifdef YYDEBUG 345 case 'y': 346 yydebug = 1; 347 break; 348 #endif 349 #ifdef INET6 350 case '4': 351 lcconf->default_af = AF_INET; 352 break; 353 case '6': 354 lcconf->default_af = AF_INET6; 355 break; 356 #endif 357 case 'B': 358 loading_sa++; 359 break; 360 case 'C': 361 dump_config++; 362 break; 363 default: 364 usage(); 365 /* NOTREACHED */ 366 } 367 } 368 ac -= optind; 369 av += optind; 370 371 if (ac != 0) { 372 usage(); 373 /* NOTREACHED */ 374 } 375 376 return; 377 } 378 379 static void 380 restore_params() 381 { 382 saverestore_params(1); 383 } 384 385 static void 386 save_params() 387 { 388 saverestore_params(0); 389 } 390 391 static void 392 saverestore_params(f) 393 int f; 394 { 395 static u_int16_t s_port_isakmp; 396 #ifdef ENABLE_ADMINPORT 397 static u_int16_t s_port_admin; 398 #endif 399 400 /* 0: save, 1: restore */ 401 if (f) { 402 lcconf->port_isakmp = s_port_isakmp; 403 #ifdef ENABLE_ADMINPORT 404 lcconf->port_admin = s_port_admin; 405 #endif 406 } else { 407 s_port_isakmp = lcconf->port_isakmp; 408 #ifdef ENABLE_ADMINPORT 409 s_port_admin = lcconf->port_admin; 410 #endif 411 } 412 } 413