1 /* $NetBSD: main.c,v 1.15 2018/05/19 19:23:15 maxv 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 81 int dump_config = 0; /* dump parsed config file. */ 82 int f_local = 0; /* local test mode. behave like a wall. */ 83 int vflag = 1; /* for print-isakmp.c */ 84 static int loading_sa = 0; /* install sa when racoon boots up. */ 85 86 #ifdef TOP_PACKAGE 87 static char version[] = "@(#)" TOP_PACKAGE_STRING " (" TOP_PACKAGE_URL ")"; 88 #else 89 static char version[] = "@(#) racoon / IPsec-tools"; 90 #endif 91 92 static void 93 print_version(void) 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 135 static void 136 usage(void) 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 164 static void 165 parse(int ac, char **av) 166 { 167 extern char *optarg; 168 extern int optind; 169 int c; 170 #ifdef YYDEBUG 171 extern int yydebug; 172 #endif 173 174 pname = strrchr(*av, '/'); 175 if (pname) 176 pname++; 177 else 178 pname = *av; 179 180 while ((c = getopt(ac, av, "dLFp:P:f:l:vVZBC" 181 #ifdef YYDEBUG 182 "y" 183 #endif 184 #ifdef INET6 185 "46" 186 #endif 187 )) != -1) { 188 switch (c) { 189 case 'd': 190 loglevel++; 191 break; 192 case 'L': 193 print_location = 1; 194 break; 195 case 'F': 196 printf("Foreground mode.\n"); 197 f_foreground = 1; 198 break; 199 case 'p': 200 lcconf->port_isakmp = atoi(optarg); 201 break; 202 case 'P': 203 lcconf->port_isakmp_natt = atoi(optarg); 204 break; 205 case 'f': 206 lcconf->racoon_conf = optarg; 207 break; 208 case 'l': 209 plogset(optarg); 210 break; 211 case 'v': 212 vflag++; 213 break; 214 case 'V': 215 print_version(); 216 break; 217 case 'Z': 218 /* 219 * only local test. 220 * To specify -Z option and to choice a appropriate 221 * port number for ISAKMP, you can launch some racoons 222 * on the local host for debug. 223 * pk_sendadd() on initiator side is always failed 224 * even if this flag is used. Because there is same 225 * spi in the SAD which is inserted by pk_sendgetspi() 226 * on responder side. 227 */ 228 printf("Local test mode.\n"); 229 f_local = 1; 230 break; 231 #ifdef YYDEBUG 232 case 'y': 233 yydebug = 1; 234 break; 235 #endif 236 #ifdef INET6 237 case '4': 238 lcconf->default_af = AF_INET; 239 break; 240 case '6': 241 lcconf->default_af = AF_INET6; 242 break; 243 #endif 244 case 'B': 245 loading_sa++; 246 break; 247 case 'C': 248 dump_config++; 249 break; 250 default: 251 usage(); 252 /* NOTREACHED */ 253 } 254 } 255 ac -= optind; 256 av += optind; 257 258 if (ac != 0) { 259 usage(); 260 /* NOTREACHED */ 261 } 262 } 263 264 int 265 main(int ac, char **av) 266 { 267 initlcconf(); 268 parse(ac, av); 269 270 if (geteuid() != 0) { 271 errx(1, "must be root to invoke this program."); 272 /* NOTREACHED*/ 273 } 274 275 /* 276 * Don't let anyone read files I write. Although some files (such as 277 * the PID file) can be other readable, we dare to use the global mask, 278 * because racoon uses fopen(3), which can't specify the permission 279 * at the creation time. 280 */ 281 umask(077); 282 if (umask(077) != 077) { 283 errx(1, "could not set umask"); 284 /* NOTREACHED*/ 285 } 286 287 ploginit(); 288 289 #ifdef DEBUG_RECORD_MALLOCATION 290 DRM_init(); 291 #endif 292 293 #ifdef HAVE_SECCTX 294 init_avc(); 295 #endif 296 eay_init(); 297 initrmconf(); 298 oakley_dhinit(); 299 compute_vendorids(); 300 301 plog(LLV_INFO, LOCATION, NULL, "%s\n", version); 302 plog(LLV_INFO, LOCATION, NULL, "@(#)" 303 "This product linked %s (http://www.openssl.org/)" 304 "\n", eay_version()); 305 plog(LLV_INFO, LOCATION, NULL, "Reading configuration from \"%s\"\n", 306 lcconf->racoon_conf); 307 308 /* 309 * install SAs from the specified file. If the file is not specified 310 * by the configuration file, racoon will exit. 311 */ 312 if (loading_sa && !f_local) { 313 if (backupsa_from_file() != 0) 314 errx(1, "something error happened " 315 "SA recovering."); 316 } 317 318 if (f_foreground) 319 close(0); 320 else { 321 if (daemon(0, 0) < 0) { 322 errx(1, "failed to be daemon. (%s)", 323 strerror(errno)); 324 } 325 #ifndef __linux__ 326 /* 327 * In case somebody has started inetd manually, we need to 328 * clear the logname, so that old servers run as root do not 329 * get the user's logname.. 330 */ 331 if (setlogin("") < 0) { 332 plog(LLV_ERROR, LOCATION, NULL, 333 "cannot clear logname: %s\n", strerror(errno)); 334 /* no big deal if it fails.. */ 335 } 336 #endif 337 } 338 339 session(); 340 341 return 0; 342 } 343