1/* $NetBSD: main.c,v 1.12 2009/01/26 18:13:06 tteras 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#include "remoteconf.h" 70#include "localconf.h" 71#include "session.h" 72#include "oakley.h" 73#include "pfkey.h" 74#include "policy.h" 75#include "crypto_openssl.h" 76#include "backupsa.h" 77#include "vendorid.h" 78 79#include "package_version.h" 80 81int dump_config = 0; /* dump parsed config file. */ 82int f_local = 0; /* local test mode. behave like a wall. */ 83int vflag = 1; /* for print-isakmp.c */ 84static int loading_sa = 0; /* install sa when racoon boots up. */ 85 86#ifdef TOP_PACKAGE 87static char version[] = "@(#)" TOP_PACKAGE_STRING " (" TOP_PACKAGE_URL ")"; 88#else /* TOP_PACKAGE */ 89static char version[] = "@(#) racoon / IPsec-tools"; 90#endif /* TOP_PACKAGE */ 91 92static void 93print_version() 94{ 95 printf("%s\n" 96 "\n" 97 "Compiled with:\n" 98 "- %s (http://www.openssl.org/)\n" 99#ifdef INET6 100 "- IPv6 support\n" 101#endif 102#ifdef ENABLE_DPD 103 "- Dead Peer Detection\n" 104#endif 105#ifdef ENABLE_FRAG 106 "- IKE fragmentation\n" 107#endif 108#ifdef ENABLE_HYBRID 109 "- Hybrid authentication\n" 110#endif 111#ifdef ENABLE_GSSAPI 112 "- GSS-API authentication\n" 113#endif 114#ifdef ENABLE_NATT 115 "- NAT Traversal\n" 116#endif 117#ifdef ENABLE_STATS 118 "- Timing statistics\n" 119#endif 120#ifdef ENABLE_ADMINPORT 121 "- Admin port\n" 122#endif 123#ifdef HAVE_CLOCK_MONOTONIC 124 "- Monotonic clock\n" 125#endif 126#ifdef HAVE_SECCTX 127 "- Security context\n" 128#endif 129 "\n", 130 version, 131 eay_version()); 132 exit(0); 133} 134 135static void 136usage() 137{ 138 printf("usage: racoon [-BdFv" 139#ifdef INET6 140 "46" 141#endif 142 "] [-f (file)] [-l (file)] [-p (port)] [-P (natt port)]\n" 143 " -B: install SA to the kernel from the file " 144 "specified by the configuration file.\n" 145 " -d: debug level, more -d will generate more debug message.\n" 146 " -C: dump parsed config file.\n" 147 " -L: include location in debug messages\n" 148 " -F: run in foreground, do not become daemon.\n" 149 " -v: be more verbose\n" 150 " -V: print version and exit\n" 151#ifdef INET6 152 " -4: IPv4 mode.\n" 153 " -6: IPv6 mode.\n" 154#endif 155 " -f: pathname for configuration file.\n" 156 " -l: pathname for log file.\n" 157 " -p: port number for isakmp (default: %d).\n" 158 " -P: port number for NAT-T (default: %d).\n" 159 "\n", 160 PORT_ISAKMP, PORT_ISAKMP_NATT); 161 exit(1); 162} 163 164static void 165parse(ac, av) 166 int ac; 167 char **av; 168{ 169 extern char *optarg; 170 extern int optind; 171 int c; 172#ifdef YYDEBUG 173 extern int yydebug; 174#endif 175 176 pname = strrchr(*av, '/'); 177 if (pname) 178 pname++; 179 else 180 pname = *av; 181 182 while ((c = getopt(ac, av, "dLFp:P:f:l:vVZBC" 183#ifdef YYDEBUG 184 "y" 185#endif 186#ifdef INET6 187 "46" 188#endif 189 )) != -1) { 190 switch (c) { 191 case 'd': 192 loglevel++; 193 break; 194 case 'L': 195 print_location = 1; 196 break; 197 case 'F': 198 printf("Foreground mode.\n"); 199 f_foreground = 1; 200 break; 201 case 'p': 202 lcconf->port_isakmp = atoi(optarg); 203 break; 204 case 'P': 205 lcconf->port_isakmp_natt = atoi(optarg); 206 break; 207 case 'f': 208 lcconf->racoon_conf = optarg; 209 break; 210 case 'l': 211 plogset(optarg); 212 break; 213 case 'v': 214 vflag++; 215 break; 216 case 'V': 217 print_version(); 218 break; 219 case 'Z': 220 /* 221 * only local test. 222 * To specify -Z option and to choice a appropriate 223 * port number for ISAKMP, you can launch some racoons 224 * on the local host for debug. 225 * pk_sendadd() on initiator side is always failed 226 * even if this flag is used. Because there is same 227 * spi in the SAD which is inserted by pk_sendgetspi() 228 * on responder side. 229 */ 230 printf("Local test mode.\n"); 231 f_local = 1; 232 break; 233#ifdef YYDEBUG 234 case 'y': 235 yydebug = 1; 236 break; 237#endif 238#ifdef INET6 239 case '4': 240 lcconf->default_af = AF_INET; 241 break; 242 case '6': 243 lcconf->default_af = AF_INET6; 244 break; 245#endif 246 case 'B': 247 loading_sa++; 248 break; 249 case 'C': 250 dump_config++; 251 break; 252 default: 253 usage(); 254 /* NOTREACHED */ 255 } 256 } 257 ac -= optind; 258 av += optind; 259 260 if (ac != 0) { 261 usage(); 262 /* NOTREACHED */ 263 } 264} 265 266int 267main(ac, av) 268 int ac; 269 char **av; 270{ 271 int error; 272 273 initlcconf(); 274 parse(ac, av); 275 276 if (geteuid() != 0) { 277 errx(1, "must be root to invoke this program."); 278 /* NOTREACHED*/ 279 } 280 281 /* 282 * Don't let anyone read files I write. Although some files (such as 283 * the PID file) can be other readable, we dare to use the global mask, 284 * because racoon uses fopen(3), which can't specify the permission 285 * at the creation time. 286 */ 287 umask(077); 288 if (umask(077) != 077) { 289 errx(1, "could not set umask"); 290 /* NOTREACHED*/ 291 } 292 293#ifdef DEBUG_RECORD_MALLOCATION 294 DRM_init(); 295#endif 296 297#ifdef HAVE_SECCTX 298 init_avc(); 299#endif 300 eay_init(); 301 initrmconf(); 302 oakley_dhinit(); 303 compute_vendorids(); 304 305 ploginit(); 306 307 plog(LLV_INFO, LOCATION, NULL, "%s\n", version); 308 plog(LLV_INFO, LOCATION, NULL, "@(#)" 309 "This product linked %s (http://www.openssl.org/)" 310 "\n", eay_version()); 311 plog(LLV_INFO, LOCATION, NULL, "Reading configuration from \"%s\"\n", 312 lcconf->racoon_conf); 313 314 /* 315 * install SAs from the specified file. If the file is not specified 316 * by the configuration file, racoon will exit. 317 */ 318 if (loading_sa && !f_local) { 319 if (backupsa_from_file() != 0) 320 errx(1, "something error happened " 321 "SA recovering."); 322 } 323 324 if (f_foreground) 325 close(0); 326 else { 327 if (daemon(0, 0) < 0) { 328 errx(1, "failed to be daemon. (%s)", 329 strerror(errno)); 330 } 331#ifndef __linux__ 332 /* 333 * In case somebody has started inetd manually, we need to 334 * clear the logname, so that old servers run as root do not 335 * get the user's logname.. 336 */ 337 if (setlogin("") < 0) { 338 plog(LLV_ERROR, LOCATION, NULL, 339 "cannot clear logname: %s\n", strerror(errno)); 340 /* no big deal if it fails.. */ 341 } 342#endif 343 } 344 345 session(); 346 347 return 0; 348} 349 350