int main(int argc, char *argv[]) { int opt; extern int optind; int errflg = 0; const char *version = ipsec_version_code(); const char **notice = ipsec_copyright_notice(); const char **co; while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF) switch (opt) { case 'h': /* help */ printf("%s\n", usage); exit(0); break; case 'v': /* version */ printf("%s %s\n", me, version); exit(0); break; case '?': default: errflg = 1; break; } if (errflg || optind != argc) { fprintf(stderr, "%s\n", usage); exit(2); } for (co = notice; *co != NULL; co++) printf("%s\n", *co); exit(0); }
/** * Print the 'ipsec whackinit --help' message */ static void help(void) { fprintf(stderr , "Usage:\n\n" "all forms:" " [--ctlbase <path>]" " [--label <string>]" "\n\n" "help: whack" " [--help]" " [--version]" "\n\n" "connection: whack" " whack" " (--initiate | --terminate)" " --name <connection_name>" " [--asynchronous]" " [--xauthname name]" " [--xauthpass pass]" "\n\n" "status: whack" " --status" "\n\n" "Libreswan %s\n" , ipsec_version_code()); }
IPSEC_PROCFS_DEBUG_NO_STATIC int ipsec_version_show(struct seq_file *seq, void *offset) { KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, "klips_debug:ipsec_version_show: seq=%p offset=%p\n", seq, offset); seq_printf(seq, "Libreswan version: %s\n", ipsec_version_code()); return 0; }
static void usage(const char *mess) { if (mess != NULL && *mess != '\0') fprintf(stderr, "%s\n", mess); fprintf(stderr, "Usage: pluto" " [--help]" " [--version]" " [--optionsfrom <filename>]" " \\\n\t" "[--nofork]" " [--stderrlog]" " [--noklips]" " [--nocrsend]" " [--uniqueids]" " \\\n\t" "[--interface <ifname>]" " [--ikeport <port-number>]" " \\\n\t" "[--ctlbase <path>]" " \\\n\t" "[--secretsfile <secrets-file>]" " \\\n\t" "[--adns <pathname>]" #ifdef DEBUG " \\\n\t" "[--debug-none]" " [--debug-all]" " \\\n\t" "[--debug-raw]" " [--debug-crypt]" " [--debug-parsing]" " [--debug-emitting]" " \\\n\t" "[--debug-control]" " [--debug-klips]" " [--debug-dns]" " [ --debug-private]" #endif #ifdef NAT_TRAVERSAL " [ --debug-nat_t]" " \\\n\t" "[--nat_traversal] [--keep_alive <delay_sec>]" " \\\n\t" "[--force_keepalive] [--disable_port_floating]" #endif #ifdef VIRTUAL_IP " \\\n\t" "[--virtual_private <network_list>]" #endif "\n" "FreeS/WAN %s\n", ipsec_version_code()); exit_pluto(mess == NULL? 0 : 1); }
/* * invocation_fail - print diagnostic and usage hint message and exit * * @param mess String - diagnostic message to print */ static void invocation_fail(const char *mess) { if (mess != NULL) fprintf(stderr, "%s\n", mess); fprintf(stderr, "For usage information: %s --help\n" "Libreswan %s\n", pluto_name, ipsec_version_code()); /* not exit_pluto because we are not initialized yet */ exit(1); }
void show_setup_plutomain(void) { whack_log(RC_COMMENT, "config setup options:"); /* spacer */ whack_log(RC_COMMENT, " "); /* spacer */ whack_log(RC_COMMENT, "configdir=%s, configfile=%s, secrets=%s, ipsecdir=%s, nssdir=%s, dumpdir=%s, statsbin=%s", oco->confdir, oco->conffile, oco->secretsfile, oco->confddir, oco->nssdb, coredir, pluto_stats_binary == NULL ? "unset" : pluto_stats_binary); whack_log(RC_COMMENT, "sbindir=%s, libexecdir=%s", IPSEC_SBINDIR, IPSEC_EXECDIR); whack_log(RC_COMMENT, "pluto_version=%s, pluto_vendorid=%s", ipsec_version_code(), pluto_vendorid); whack_log(RC_COMMENT, "nhelpers=%d, uniqueids=%s, perpeerlog=%s, shuntlifetime=%lus, xfrmlifetime=%ds", nhelpers, uniqueIDs ? "yes" : "no", !log_to_perpeer ? "no" : base_perpeer_logdir, deltasecs(pluto_shunt_lifetime), pluto_xfrmlifetime ); whack_log(RC_COMMENT, "ddos-cookies-threshold=%d, ddos-max-halfopen=%d, ddos-mode=%s", pluto_max_halfopen, pluto_ddos_threshold, (pluto_ddos_mode == DDOS_AUTO) ? "auto" : (pluto_ddos_mode == DDOS_FORCE_BUSY) ? "busy" : "unlimited"); whack_log(RC_COMMENT, "ikeport=%d, strictcrlpolicy=%s, crlcheckinterval=%lu, listen=%s, nflog-all=%d", pluto_port, strict_crl_policy ? "yes" : "no", deltasecs(crl_check_interval), pluto_listen != NULL ? pluto_listen : "<any>", pluto_nflog_group ); #ifdef HAVE_LABELED_IPSEC whack_log(RC_COMMENT, "secctx-attr-type=%d", secctx_attr_type); #else whack_log(RC_COMMENT, "secctx-attr-type=<unsupported>"); #endif }
static void usage(const char *mess) { if (mess != NULL && *mess != '\0') fprintf(stderr, "%s\n", mess); fprintf(stderr , "Usage: pluto\n" "\t [--help]\n" "\t [--version]\n" " [--start ]<...>:\n" " [--user ]<...>:\n" "\t [--debug-none]\n" "\t [--debug-all]\n" "\t [--debug-nat]\n" "\t [--debug-raw]\n" "\t [--debug-crypto]\n" "\t [--debug-parsing]\n" "\t [--debug-emitting]\n" "\t [--debug-control]\n" "\t [--debug-lifecycle]\n" "\t [--debug-klips]\n" "\t [--debug-netkey]\n" "\t [--debug-x509]\n" "\t [--debug-dns]\n" "\t [--debug-error]\n" "\t [--debug-dpd]\n" "\t [--debug-xauth]\n" "\t [--debug-private]\n" "\t [--debug-pfkey]\n" "\t [--debug-controlmore]\n" "\t [--debug-connection <name>]\n" "\t [--debug-host <remote-ip>]\n" "\t [--debug-stop]\n" "\t [--log-openinfo]\n" "\t [--log-openwar]\n" "\t [--log-openerr]\n" "\t [--log-openuserlog]\n" "\t [--log-openradiuslog]\n" "\t [--log-openpri]\n" "\t [--log-opensyserr]\n" "\t [--log-closeall]\n" "\t [--counter]\n" "\t [--isa-counter]\n\n" " [--krl] <...>:\n" "\t [--krc] --- clear ipsec counter\n" "\t [--kss] <sip> --- set counter sip\n" "\t [--kpc] --- print ipsec counter\n" "\t [--kprt] <eth_xx> (--kspi) (--kdst) (--kdnet) (--kid)\n" "\t ---print policy template ,if appent filter print sa\n" "Openswan %s\n" , ipsec_version_code()); exit(mess == NULL? 0 : 1); /* not exit_pluto because we are not initialized yet */ }
/* print full usage (from long_opts[]) */ static void usage(void) { const struct option *opt; char line[72]; size_t lw; snprintf(line, sizeof(line), "Usage: %s", pluto_name); lw = strlen(line); for (opt = long_opts; opt->name != NULL; opt++) { const char *nm = opt->name; const char *meta = nm + strlen(nm) + 1; bool force_nl = FALSE; char chunk[sizeof(line) - 1]; int cw; switch (*meta) { case '_': case '>': case '!': /* ignore these entries */ break; case '^': force_nl = TRUE; meta++; /* eat ^ */ /* FALL THROUGH */ default: if (*meta == '\0') snprintf(chunk, sizeof(chunk), "[--%s]", nm); else snprintf(chunk, sizeof(chunk), "[--%s %s]", nm, meta); cw = strlen(chunk); if (force_nl || lw + cw + 2 >= sizeof(line)) { fprintf(stderr, "%s\n", line); line[0] = '\t'; lw = 1; } else { line[lw++] = ' '; } passert(lw + cw + 1 < sizeof(line)); strcpy(&line[lw], chunk); lw += cw; } } fprintf(stderr, "%s\n", line); fprintf(stderr, "Libreswan %s\n", ipsec_version_code()); /* not exit_pluto because we are not initialized yet */ exit(0); }
IPSEC_PROCFS_DEBUG_NO_STATIC int ipsec_saref_show(struct seq_file *seq, void *offset) { KLIPS_PRINT(debug_tunnel & DB_TN_PROCFS, "klips_debug:ipsec_saref_show: seq=%p offset=%p\n", seq, offset); #ifdef IP_IPSEC_REFINFO seq_printf(seq, "refinfo patch applied\n"); #endif #ifdef IP_IPSEC_BINDREF seq_printf(seq, "bindref patch applied\n"); #endif #ifdef CONFIG_INET_IPSEC_SAREF seq_printf(seq, "saref enabled (%s)\n", ipsec_version_code()); #else seq_printf(seq, "saref disabled (%s)\n", ipsec_version_code()); #endif return 0; }
static void help(void) { fprintf(stderr, "Usage:\n\n" "showpolicy" " [--cgi] lookup the particulars from CGI variables.\n" " [--socket] lookup the particulars from the socket on stdin.\n" " [--textual] dump output in human friendly form\n" " [--plaintext X] string to dump if no security\n" " [--vpntext X] string to dump if VPN configured tunnel\n" " [--privacytext X] string to dump if just plain DNS OE\n" " [--dnssectext X] string to dump if just DNSSEC OE\n" "\n\n" "FreeS/WAN %s\n", ipsec_version_code()); }
static void help(void) { fprintf(stderr, "Usage:\n\n" "showpolicy" " [--cgi] lookup the particulars from CGI variables.\n" " [--socket] lookup the particulars from the socket on stdin.\n" " [--udp X] open a UDP socket on port X\n" " [--tcp X] open a TCP socket on port X\n" " [--sockpolicy] dump based upon IP_IPSEC_RECVREF.\n" " [--textual] dump output in human friendly form\n" " [--plaintext X] string to dump if no security\n" " [--vpntext X] string to dump if VPN configured tunnel\n" " [--privacytext X] string to dump if just plain DNS OE\n" " [--dnssectext X] string to dump if just DNSSEC OE\n" "\n\n" "Openswan %s\n", ipsec_version_code()); }
static void help(void) { fprintf(stderr, "Usage:\n\n" "ikeping" " [--listen] causes IKEping to open a socket and reply to requests.\n" " [--verbose] causes IKEping to hexdump all packets sent/received.\n" " [--ikeport <port-number>] port to listen on/send from\n" " [--ikeaddress <address>] address to listen on/send from\n" " [--inet] just send/listen on IPv4 socket\n" " [--inet6] just send/listen on IPv6 socket\n" " [--version] just dump version number and exit\n" " [--nat-t] enabled NONESP encapsulation on port\n" " [--exchangenum num] use num instead of 244 for the exchange type.\n" " [--wait seconds] time to wait for replies, defaults to 3 seconds.\n" " host/port ...\n\n" "Openswan %s\n", ipsec_version_code()); }
int main(int argc, char **argv) { bool fork_desired = TRUE; int lockfd; char* ocspuri = NULL; int nhelpers = -1; char *coredir; const struct osw_conf_options *oco; #ifdef NAT_TRAVERSAL /** Overridden by nat_traversal= in ipsec.conf */ bool nat_traversal = FALSE; bool nat_t_spf = TRUE; /* support port floating */ unsigned int keep_alive = 0; bool force_keepalive = FALSE; #endif /** Overridden by virtual_private= in ipsec.conf */ char *virtual_private = NULL; #ifdef LEAK_DETECTIVE leak_detective=1; #else leak_detective=0; #endif #ifdef HAVE_LIBCAP_NG /* Drop capabilities */ capng_clear(CAPNG_SELECT_BOTH); capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_NET_BIND_SERVICE, CAP_NET_ADMIN, CAP_NET_RAW, CAP_IPC_LOCK, -1); /* our children must be able to CAP_NET_ADMIN to change routes. */ capng_updatev(CAPNG_ADD, CAPNG_BOUNDING_SET, CAP_NET_ADMIN, -1); capng_apply(CAPNG_SELECT_BOTH); #endif global_argv = argv; global_argc = argc; #ifdef DEBUG openswan_passert_fail = passert_fail; #endif /* see if there is an environment variable */ coredir = getenv("PLUTO_CORE_DIR"); if(getenv("PLUTO_WAIT_FOR_GDB")) { sleep(120); } /* handle arguments */ for (;;) { # define DBG_OFFSET 256 static const struct option long_opts[] = { /* name, has_arg, flag, val */ { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "optionsfrom", required_argument, NULL, '+' }, { "nofork", no_argument, NULL, 'd' }, { "stderrlog", no_argument, NULL, 'e' }, { "noklips", no_argument, NULL, 'n' }, { "use-nostack", no_argument, NULL, 'n' }, { "use-none", no_argument, NULL, 'n' }, { "force_busy", no_argument, NULL, 'D' }, { "nocrsend", no_argument, NULL, 'c' }, { "strictcrlpolicy", no_argument, NULL, 'r' }, { "crlcheckinterval", required_argument, NULL, 'x'}, { "ocsprequestcert", required_argument, NULL, 'q'}, { "ocspuri", required_argument, NULL, 'o'}, { "uniqueids", no_argument, NULL, 'u' }, { "useklips", no_argument, NULL, 'k' }, { "use-klips", no_argument, NULL, 'k' }, { "use-auto", no_argument, NULL, 'G' }, { "usenetkey", no_argument, NULL, 'K' }, { "use-netkey", no_argument, NULL, 'K' }, { "use-mast", no_argument, NULL, 'M' }, { "use-mastklips", no_argument, NULL, 'M' }, { "use-bsdkame", no_argument, NULL, 'F' }, { "interface", required_argument, NULL, 'i' }, { "listen", required_argument, NULL, 'L' }, { "ikeport", required_argument, NULL, 'p' }, { "ctlbase", required_argument, NULL, 'b' }, { "secretsfile", required_argument, NULL, 's' }, { "foodgroupsdir", required_argument, NULL, 'f' }, { "perpeerlogbase", required_argument, NULL, 'P' }, { "perpeerlog", no_argument, NULL, 'l' }, { "noretransmits", no_argument, NULL, 'R' }, { "coredir", required_argument, NULL, 'C' }, { "ipsecdir", required_argument, NULL, 'f' }, { "ipsec_dir", required_argument, NULL, 'f' }, #ifdef USE_LWRES { "lwdnsq", required_argument, NULL, 'a' }, #else /* !USE_LWRES */ { "adns", required_argument, NULL, 'a' }, #endif /* !USE_LWRES */ #ifdef NAT_TRAVERSAL { "nat_traversal", no_argument, NULL, '1' }, { "keep_alive", required_argument, NULL, '2' }, { "force_keepalive", no_argument, NULL, '3' }, { "disable_port_floating", no_argument, NULL, '4' }, { "debug-nat_t", no_argument, NULL, '5' }, { "debug-nattraversal", no_argument, NULL, '5' }, { "debug-nat-t", no_argument, NULL, '5' }, #endif { "virtual_private", required_argument, NULL, '6' }, { "nhelpers", required_argument, NULL, 'j' }, #ifdef DEBUG { "debug-none", no_argument, NULL, 'N' }, { "debug-all", no_argument, NULL, 'A' }, { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET }, { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET }, { "debug-crypto", no_argument, NULL, DBG_CRYPT + DBG_OFFSET }, { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET }, { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET }, { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET }, { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET }, { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET }, { "debug-netkey", no_argument, NULL, DBG_NETKEY + DBG_OFFSET }, { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET }, { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET }, { "debug-oppoinfo", no_argument, NULL, DBG_OPPOINFO + DBG_OFFSET }, { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET }, { "debug-dpd", no_argument, NULL, DBG_DPD + DBG_OFFSET }, { "debug-x509", no_argument, NULL, DBG_X509 + DBG_OFFSET }, { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET }, { "debug-pfkey", no_argument, NULL, DBG_PFKEY + DBG_OFFSET }, { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET }, { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET }, { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET }, { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET }, { "impair-sa-creation", no_argument, NULL, IMPAIR_SA_CREATION + DBG_OFFSET }, { "impair-die-oninfo", no_argument, NULL, IMPAIR_DIE_ONINFO + DBG_OFFSET }, { "impair-jacob-two-two", no_argument, NULL, IMPAIR_JACOB_TWO_TWO + DBG_OFFSET }, #endif { 0,0,0,0 } }; /* Note: we don't like the way short options get parsed * by getopt_long, so we simply pass an empty string as * the list. It could be "hvdenp:l:s:" "NARXPECK". */ int c = getopt_long(argc, argv, "", long_opts, NULL); /** Note: "breaking" from case terminates loop */ switch (c) { case EOF: /* end of flags */ break; case 0: /* long option already handled */ continue; case ':': /* diagnostic already printed by getopt_long */ case '?': /* diagnostic already printed by getopt_long */ usage(""); break; /* not actually reached */ case 'h': /* --help */ usage(NULL); break; /* not actually reached */ case 'C': coredir = clone_str(optarg, "coredir"); break; case 'v': /* --version */ { const char **sp = ipsec_copyright_notice(); printf("%s%s\n", ipsec_version_string(), compile_time_interop_options); for (; *sp != NULL; sp++) puts(*sp); } exit(0); /* not exit_pluto because we are not initialized yet */ break; /* not actually reached */ case '+': /* --optionsfrom <filename> */ optionsfrom(optarg, &argc, &argv, optind, stderr); /* does not return on error */ continue; case 'j': /* --nhelpers */ if (optarg == NULL || !isdigit(optarg[0])) usage("missing number of pluto helpers"); { char *endptr; long count = strtol(optarg, &endptr, 0); if (*endptr != '\0' || endptr == optarg || count < -1) usage("<nhelpers> must be a positive number, 0 or -1"); nhelpers = count; } continue; case 'd': /* --nofork*/ fork_desired = FALSE; continue; case 'e': /* --stderrlog */ log_to_stderr_desired = TRUE; continue; case 'G': /* --use-auto */ kern_interface = AUTO_PICK; continue; case 'k': /* --use-klips */ kern_interface = USE_KLIPS; continue; case 'L': /* --listen ip_addr */ { ip_address lip; err_t e = ttoaddr(optarg,0,0,&lip); if(e) { openswan_log("invalid listen argument ignored: %s\n",e); } else { pluto_listen = clone_str(optarg, "pluto_listen"); openswan_log("bind() will be filtered for %s\n",pluto_listen); } } continue; case 'M': /* --use-mast */ kern_interface = USE_MASTKLIPS; continue; case 'F': /* --use-bsdkame */ kern_interface = USE_BSDKAME; continue; case 'K': /* --use-netkey */ kern_interface = USE_NETKEY; continue; case 'n': /* --use-nostack */ kern_interface = NO_KERNEL; continue; case 'D': /* --force_busy */ force_busy = TRUE; continue ; case 'c': /* --nocrsend */ no_cr_send = TRUE; continue ; case 'r': /* --strictcrlpolicy */ strict_crl_policy = TRUE; continue ; case 'R': no_retransmits = TRUE; continue; case 'x': /* --crlcheckinterval <time>*/ if (optarg == NULL || !isdigit(optarg[0])) usage("missing interval time"); { char *endptr; long interval = strtol(optarg, &endptr, 0); if (*endptr != '\0' || endptr == optarg || interval <= 0) usage("<interval-time> must be a positive number"); crl_check_interval = interval; } continue ; case 'o': /* --ocspuri */ ocspuri = optarg; continue; case 'u': /* --uniqueids */ uniqueIDs = TRUE; continue; case 'i': /* --interface <ifname|ifaddr> */ if (!use_interface(optarg)) usage("too many --interface specifications"); continue; /* * This option does not really work, as this is the "left" * site only, you also need --to --ikeport again later on * It will result in: yourport -> 500, still not bypassing filters */ case 'p': /* --ikeport <portnumber> */ if (optarg == NULL || !isdigit(optarg[0])) usage("missing port number"); { char *endptr; long port = strtol(optarg, &endptr, 0); if (*endptr != '\0' || endptr == optarg || port <= 0 || port > 0x10000) usage("<port-number> must be a number between 1 and 65535"); pluto_port = port; } continue; case 'b': /* --ctlbase <path> */ ctlbase = optarg; if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path) , "%s%s", ctlbase, CTL_SUFFIX) == -1) usage("<path>" CTL_SUFFIX " too long for sun_path"); if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path) , "%s%s", ctlbase, INFO_SUFFIX) == -1) usage("<path>" INFO_SUFFIX " too long for sun_path"); if (snprintf(pluto_lock, sizeof(pluto_lock) , "%s%s", ctlbase, LOCK_SUFFIX) == -1) usage("<path>" LOCK_SUFFIX " must fit"); continue; case 's': /* --secretsfile <secrets-file> */ pluto_shared_secrets_file = optarg; continue; case 'f': /* --ipsecdir <ipsec-dir> */ (void)osw_init_ipsecdir(optarg); continue; case 'a': /* --adns <pathname> */ pluto_adns_option = optarg; continue; #ifdef DEBUG case 'N': /* --debug-none */ base_debugging = DBG_NONE; continue; case 'A': /* --debug-all */ base_debugging = DBG_ALL; continue; #endif case 'P': /* --perpeerlogbase */ base_perpeer_logdir = optarg; continue; case 'l': log_to_perpeer = TRUE; continue; #ifdef NAT_TRAVERSAL case '1': /* --nat_traversal */ nat_traversal = TRUE; continue; case '2': /* --keep_alive */ keep_alive = atoi(optarg); continue; case '3': /* --force_keepalive */ force_keepalive = TRUE; continue; case '4': /* --disable_port_floating */ nat_t_spf = FALSE; continue; #ifdef DEBUG case '5': /* --debug-nat_t */ base_debugging |= DBG_NATT; continue; #endif #endif case '6': /* --virtual_private */ virtual_private = optarg; continue; default: #ifdef DEBUG if (c >= DBG_OFFSET) { base_debugging |= c - DBG_OFFSET; continue; } # undef DBG_OFFSET #endif bad_case(c); } break; } if (optind != argc) usage("unexpected argument"); reset_debugging(); #ifdef HAVE_NO_FORK fork_desired = FALSE; nhelpers = 0; #endif /* if a core dir was set, chdir there */ if(coredir) if(chdir(coredir) == -1) { int e = errno; openswan_log("pluto: chdir() do dumpdir failed (%d %s)\n", e, strerror(e)); } oco = osw_init_options(); lockfd = create_lock(); /* select between logging methods */ if (log_to_stderr_desired) log_to_syslog = FALSE; else log_to_stderr = FALSE; #ifdef DEBUG #if 0 if(kernel_ops->set_debug) { (*kernel_ops->set_debug)(cur_debugging, DBG_log, DBG_log); } #endif #endif /** create control socket. * We must create it before the parent process returns so that * there will be no race condition in using it. The easiest * place to do this is before the daemon fork. */ { err_t ugh = init_ctl_socket(); if (ugh != NULL) { fprintf(stderr, "pluto: %s", ugh); exit_pluto(1); } } #ifdef IPSECPOLICY /* create info socket. */ { err_t ugh = init_info_socket(); if (ugh != NULL) { fprintf(stderr, "pluto: %s", ugh); exit_pluto(1); } } #endif /* If not suppressed, do daemon fork */ if (fork_desired) { { pid_t pid = fork(); if (pid < 0) { int e = errno; fprintf(stderr, "pluto: fork failed (%d %s)\n", errno, strerror(e)); exit_pluto(1); } if (pid != 0) { /* parent: die, after filling PID into lock file. * must not use exit_pluto: lock would be removed! */ exit(fill_lock(lockfd, pid)? 0 : 1); } } if (setsid() < 0) { int e = errno; fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n", errno, strerror(e)); exit_pluto(1); } } else { /* no daemon fork: we have to fill in lock file */ (void) fill_lock(lockfd, getpid()); fprintf(stdout, "Pluto initialized\n"); fflush(stdout); } /** Close everything but ctl_fd and (if needed) stderr. * There is some danger that a library that we don't know * about is using some fd that we don't know about. * I guess we'll soon find out. */ { int i; for (i = getdtablesize() - 1; i >= 0; i--) /* Bad hack */ if ((!log_to_stderr || i != 2) #ifdef IPSECPOLICY && i != info_fd #endif && i != ctl_fd) close(i); /* make sure that stdin, stdout, stderr are reserved */ if (open("/dev/null", O_RDONLY) != 0) osw_abort(); if (dup2(0, 1) != 1) osw_abort(); if (!log_to_stderr && dup2(0, 2) != 2) osw_abort(); } init_constants(); pluto_init_log(); #ifdef HAVE_LIBNSS char buf[100]; snprintf(buf, sizeof(buf), "%s",oco->confddir); loglog(RC_LOG_SERIOUS,"nss directory plutomain: %s",buf); SECStatus nss_init_status= NSS_InitReadWrite(buf); if (nss_init_status != SECSuccess) { loglog(RC_LOG_SERIOUS, "NSS initialization failed (err %d)\n", PR_GetError()); exit_pluto(10); } else { loglog(RC_LOG_SERIOUS, "NSS Initialized"); PK11_SetPasswordFunc(getNSSPassword); #ifdef FIPS_CHECK const char *package_files[]= { IPSECLIBDIR"/setup", IPSECLIBDIR"/addconn", IPSECLIBDIR"/auto", IPSECLIBDIR"/barf", IPSECLIBDIR"/_copyright", IPSECLIBDIR"/eroute", IPSECLIBDIR"/ikeping", IPSECLIBDIR"/_include", IPSECLIBDIR"/_keycensor", IPSECLIBDIR"/klipsdebug", IPSECLIBDIR"/look", IPSECLIBDIR"/newhostkey", IPSECLIBDIR"/pf_key", IPSECLIBDIR"/_pluto_adns", IPSECLIBDIR"/_plutoload", IPSECLIBDIR"/_plutorun", IPSECLIBDIR"/ranbits", IPSECLIBDIR"/_realsetup", IPSECLIBDIR"/rsasigkey", IPSECLIBDIR"/pluto", IPSECLIBDIR"/_secretcensor", IPSECLIBDIR"/secrets", IPSECLIBDIR"/showdefaults", IPSECLIBDIR"/showhostkey", IPSECLIBDIR"/showpolicy", IPSECLIBDIR"/spi", IPSECLIBDIR"/spigrp", IPSECLIBDIR"/_startklips", IPSECLIBDIR"/_startnetkey", IPSECLIBDIR"/tncfg", IPSECLIBDIR"/_updown", IPSECLIBDIR"/_updown.klips", IPSECLIBDIR"/_updown.mast", IPSECLIBDIR"/_updown.netkey", IPSECLIBDIR"/verify", IPSECLIBDIR"/whack", IPSECSBINDIR"/ipsec", NULL }; if (Pluto_IsFIPS() && !FIPSCHECK_verify_files(package_files)) { loglog(RC_LOG_SERIOUS, "FIPS integrity verification test failed"); exit_pluto(10); } #endif } #endif /* Note: some scripts may look for this exact message -- don't change * ipsec barf was one, but it no longer does. */ { const char *vc = ipsec_version_code(); #ifdef PLUTO_SENDS_VENDORID const char *v = init_pluto_vendorid(); openswan_log("Starting Pluto (Openswan Version %s%s; Vendor ID %s) pid:%u" , vc, compile_time_interop_options, v, getpid()); #else openswan_log("Starting Pluto (Openswan Version %s%s) pid:%u" , vc, compile_time_interop_options, getpid()); #endif #ifdef HAVE_LIBNSS if(Pluto_IsFIPS()) { openswan_log("Pluto is running in FIPS mode"); } #endif if((vc[0]=='c' && vc[1]=='v' && vc[2]=='s') || (vc[2]=='g' && vc[3]=='i' && vc[4]=='t')) { /* * when people build RPMs from CVS or GIT, make sure they * get blamed appropriately, and that we get some way to * identify who did it, and when they did it. Use string concat, * so that strings the binary can or classic SCCS "what", will find * stuff too. */ openswan_log("@(#) built on "__DATE__":" __TIME__ " by " BUILDER); } #if defined(USE_1DES) openswan_log("WARNING: 1DES is enabled"); #endif } if(coredir) { openswan_log("core dump dir: %s", coredir); } #ifdef LEAK_DETECTIVE openswan_log("LEAK_DETECTIVE support [enabled]"); #else openswan_log("LEAK_DETECTIVE support [disabled]"); #endif #ifdef HAVE_OCF { struct stat buf; errno=0; if( stat("/dev/crypto",&buf) != -1) openswan_log("OCF support for IKE via /dev/crypto [enabled]"); else openswan_log("OCF support for IKE via /dev/crypto [failed:%s]", strerror(errno)); } #else openswan_log("OCF support for IKE [disabled]"); #endif /* Check for SAREF support */ #ifdef KLIPS_MAST #include <ipsec_saref.h> { int e, sk, saref; saref = 1; errno=0; sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_REFINFO, &saref, sizeof(saref)); if (e == -1 ) { openswan_log("SAref support [disabled]: %s" , strerror(errno)); } else { openswan_log("SAref support [enabled]"); } errno=0; e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_BINDREF, &saref, sizeof(saref)); if (e == -1 ) { openswan_log("SAbind support [disabled]: %s" , strerror(errno)); } else { openswan_log("SAbind support [enabled]"); } close(sk); } #endif #ifdef HAVE_LIBNSS openswan_log("NSS support [enabled]"); #else openswan_log("NSS support [disabled]"); #endif #ifdef HAVE_STATSD openswan_log("HAVE_STATSD notification via /bin/openswan-statsd enabled"); #else openswan_log("HAVE_STATSD notification support not compiled in"); #endif /** Log various impair-* functions if they were enabled */ if(DBGP(IMPAIR_BUST_MI2)) openswan_log("Warning: IMPAIR_BUST_MI2 enabled"); if(DBGP(IMPAIR_BUST_MR2)) openswan_log("Warning: IMPAIR_BUST_MR2 enabled"); if(DBGP(IMPAIR_SA_CREATION)) openswan_log("Warning: IMPAIR_SA_CREATION enabled"); if(DBGP(IMPAIR_JACOB_TWO_TWO)) openswan_log("Warning: IMPAIR_JACOB_TWO_TWO enabled"); if(DBGP(IMPAIR_DIE_ONINFO)) openswan_log("Warning: IMPAIR_DIE_ONINFO enabled"); if(DBGP(IMPAIR_DELAY_ADNS_KEY_ANSWER)) openswan_log("Warning: IMPAIR_DELAY_ADNS_KEY_ANSWER enabled"); if(DBGP(IMPAIR_DELAY_ADNS_TXT_ANSWER)) openswan_log("Warning: IMPAIR_DELAY_ADNS_TXT_ANSWER enabled"); /** Initialize all of the various features */ #ifdef NAT_TRAVERSAL init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf); #endif init_virtual_ip(virtual_private); init_rnd_pool(); init_timer(); init_secret(); init_states(); init_connections(); init_crypto(); init_crypto_helpers(nhelpers); load_oswcrypto(); init_demux(); init_kernel(); init_adns(); init_id(); #ifdef TPM init_tpm(); #endif #ifdef HAVE_THREADS init_fetch(); #endif ocsp_set_default_uri(ocspuri); /* loading X.509 CA certificates */ load_authcerts("CA cert", oco->cacerts_dir, AUTH_CA); /* loading X.509 AA certificates */ load_authcerts("AA cert", oco->aacerts_dir, AUTH_AA); /* loading X.509 OCSP certificates */ load_authcerts("OCSP cert", oco->ocspcerts_dir, AUTH_OCSP); /* loading X.509 CRLs */ load_crls(); /* loading attribute certificates (experimental) */ load_acerts(); #ifdef HAVE_LIBNSS /*Loading CA certs from NSS DB*/ load_authcerts_from_nss("CA cert", AUTH_CA); #endif daily_log_event(); call_server(); return -1; /* Shouldn't ever reach this */ }
/** usage - print help messages * * @param mess String - alternate message to print */ static void usage(const char *mess) { if (mess != NULL && *mess != '\0') fprintf(stderr, "%s\n", mess); fprintf(stderr , "Usage: pluto" " [--help]" " [--version]" " [--optionsfrom <filename>]" " \\\n\t" "[--nofork]" " [--stderrlog]" " [--force_busy]" " [--nocrsend]" " [--strictcrlpolicy]" " [--crlcheckinterval]" " [--ocspuri]" " [--uniqueids]" " [--use-auto]" " [--use-klips]" " [--use-netkey]" " [--use-mast]" " [--use-bsdkame]" " [--use-nostack]" /* old --no_klips */ " \\\n\t" "[--interface <ifname|ifaddr>]" " [--ikeport <port-number>]" "[--listen <ifaddr>]" " \\\n\t" "[--ctlbase <path>]" " \\\n\t" "[--perpeerlogbase <path>] [--perpeerlog]" " \\\n\t" "[--coredir <dirname>] [--noretransmits]" " \\\n\t" "[--secretsfile <secrets-file>]" " [--ipsecdir <ipsec-dir>]" " \\\n\t" "[--adns <pathname>]" "[--nhelpers <number>]" #ifdef DEBUG " \\\n\t" "[--debug-none]" " [--debug-all]" " \\\n\t" "[--debug-raw]" " [--debug-crypt]" " [--debug-crypto]" " [--debug-parsing]" " [--debug-emitting]" " \\\n\t" "[--debug-control]" "[--debug-lifecycle]" " [--debug-klips]" " [--debug-netkey]" " [--debug-x509]" " [--debug-dns]" " [--debug-oppo]" " [--debug-oppoinfo]" " [--debug-dpd]" " [ --debug-private]" " [ --debug-pfkey]" #endif #ifdef NAT_TRAVERSAL " [ --debug-nat-t]" " \\\n\t" "[--nat_traversal] [--keep_alive <delay_sec>]" " \\\n\t" "[--force_keepalive] [--disable_port_floating]" #endif " \\\n\t" "[--virtual_private <network_list>]" "\n" "Openswan %s\n" , ipsec_version_code()); exit(mess == NULL? 0 : 1); /* not exit_pluto because we are not initialized yet */ }
int main(int argc, char *argv[]) { struct ipsec_policy_cmd_query q; err_t ret; int c, fd = -1; unsigned short port; char *foo; /* set the defaults */ char lookup_style = 'i'; char output_style = 's'; char *plaintext = "clear"; char *vpntext = "vpn"; char *privacytext = "private"; char *dnssectext = "secure"; while((c = getopt_long(argc, argv, "hVighc:v:p:s:", long_opts, 0))!=EOF) { switch (c) { default: case 'h': /* --help */ help(); return 0; /* GNU coding standards say to stop here */ case 'V': /* --version */ fprintf(stderr, "Openswan %s\n", ipsec_version_code()); return 0; /* GNU coding standards say to stop here */ case 'i': fd = 0; if(isatty(0)) { printf("please run this connected to a socket\n"); exit(1); } lookup_style = 'i'; break; case 'U': port = strtol(optarg, &foo, 0); if(*foo != '\0') { fprintf(stderr, "invalid port number: %s\n", optarg); help(); } fd = open_udp_sock(port); break; case 'T': port = strtol(optarg, &foo, 0); if(*foo != '\0') { fprintf(stderr, "invalid port number: %s\n", optarg); help(); } fd = open_tcp_sock(port); break; case 'N': maxpacketcount = strtol(optarg, &foo, 0); if(*foo != '\0') { fprintf(stderr, "invalid packetcount number: %s\n", optarg); help(); } break; case 'P': lookup_style = 'P'; break; case 'g': lookup_style = 'g'; break; case 't': output_style = 't'; break; case 'c': plaintext = optarg; break; case 'v': vpntext = optarg; break; case 'p': privacytext = optarg; break; case 's': dnssectext = optarg; break; } } if(lookup_style != 'P') { if((ret = ipsec_policy_init()) != NULL) { perror(ret); exit(2); } } switch(lookup_style) { case 'i': if((ret = ipsec_policy_lookup(fd, &q)) != NULL) { perror(ret); exit(3); } break; case 'g': if((ret = ipsec_policy_cgilookup(&q)) != NULL) { perror(ret); exit(3); } break; case 'P': udp_recv_loop(fd); break; default: abort(); break; } if(output_style == 't') { dump_policyreply(&q); } else { /* start by seeing if there was any crypto */ if(q.strength < IPSEC_PRIVACY_PRIVATE) { /* no, so say clear */ puts(plaintext); exit(0); } /* we now it is crypto, but authentic is it? */ if(q.credential_count == 0) { puts(vpntext); exit(0); } switch(q.credentials[0].ii_format) { case CERT_DNS_SIGNED_KEY: puts(dnssectext); exit(0); case CERT_RAW_RSA: puts(vpntext); exit(0); default: puts(privacytext); exit(0); } } exit(0); }
static void help(void) { fprintf(stderr, "Usage:\n\n" "all forms:" " [--optionsfrom <filename>]" " [--ctlbase <path>]" " [--label <string>]" "\n\n" "help: whack" " [--help]" " [--version]" "\n\n" "connection: whack" " --name <connection_name>" " \\\n " " [--ipv4 | --ipv6 ]" " [--tunnelipv4 | --tunnelipv6 ]" " \\\n " " (--host <ip-address> | --id <identity> | --cert <path>)" " [--ikeport <port-number>]" " \\\n " " " " [--nexthop <ip-address>]" " [--client <subnet>] | [--clientwithin <address range>])" " [--clientprotoport <protocol>/<port>]" " [--updown <updown>]" " --to" " (--host <ip-address> | --id <identity> | --cert <path>)" " [--ikeport <port-number>]" " \\\n " " " " [--nexthop <ip-address>]" " [--client <subnet>] | [--clientwithin <address range>])" " [--clientprotoport <protocol>/<port>]" " [--updown <updown>]" " [--aggrmode]" " [--psk]" " [--rsasig]" " \\\n " " [--encrypt]" " [--authenticate]" " [--compress]" " [--tunnel]" " [--pfs]" " \\\n " " [--ikelifetime <seconds>]" " [--ipseclifetime <seconds>]" " \\\n " " [--reykeymargin <seconds>]" " [--reykeyfuzz <percentage>]" " \\\n " " [--keyingtries <count>]" " \\\n " " [--esp <esp-algos>]" " \\\n " " [--dpddelay <seconds> --dpdtimeout <seconds>]" " [--cipher_p1 <Phase 1 encryption algorithm> --dhg_p1 <Phase 1 Diffie Helman group>]" " [--hash_p1 <Phase 1 hash algorithm>]" " [--dontrekey]" "\n\n" "routing: whack" " (--route | --unroute)" " --name <connection_name>" "\n\n" "initiation: whack" " (--initiate | --terminate)" " --name <connection_name>" " [--asynchronous]" "\n\n" "opportunistic initiation:" "\n" " whack" " [--ipv4 | --ipv6 ]" " [--tunnelipv4 | --tunnelipv6 ]" " \\\n " " --oppohere <ip-address>" " --oppothere <ip-address>" "\n\n" "delete: whack" " --delete" " --name <connection_name>" "\n\n" "deletestate: whack" " --deletestate <state_object_number>" "\n\n" "pubkey: whack" " --keyid <id>" " [--addkey]" " [--pubkeyrsa <key>]" "\n\n" #ifdef DEBUG "debug: whack [--name <connection_name>]" " \\\n " " [--debug-none]" " [--debug-all]" " \\\n " " [--debug-raw]" " [--debug-crypt]" " [--debug-parsing]" " [--debug-emitting]" " \\\n " " [--debug-control]" " [--debug-klips]" " [--debug-dns]" " [--debug-private]" "\n\n" #endif "listen: whack" " (--listen | --unlisten)" "\n\n" "list: whack [--utc]" " [--listpubkeys]" " [--listcerts]" " [--listcacerts]" " [--listcrls]" " [--listall]" "\n\n" "reread: whack" " [--rereadsecrets]" " [--rereadmycert]" " [--rereadcacerts]" " [--rereadcrls]" " [--rereadall]" "\n\n" "status: whack" " --status" "\n\n" "shutdown: whack" " --shutdown" "\n\n" "FreeS/WAN %s\n", ipsec_version_code()); }
/* - main - mostly argument parsing */ int main(int argc, char *argv[]) { const struct lsw_conf_options *oco = lsw_init_options(); int opt; int nbits = 0; int seedbits = DEFAULT_SEED_BITS; char *configdir = oco->confddir; /* where the NSS databases reside */ char *password = NULL; /* password for token authentication */ while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF) switch (opt) { case 'n': case 'p': fprintf(stderr, "%s: --noopt and --rounds options have been obsoleted - ignored\n", me); break; case 'v': /* verbose description */ verbose = 1; break; case 'r': fprintf(stderr, "%s: Warning: --random is obsoleted for --seeddev. It no longer specifies the random device used for obtaining random key material", me); /* FALLTHROUGH */ case 'S': /* nonstandard random device for seed */ device = optarg; break; case 'H': /* set hostname for output */ { size_t full_len = strlen(optarg); bool oflow = sizeof(outputhostname) - 1 < full_len; size_t copy_len = oflow ? sizeof(outputhostname) - 1 : full_len; memcpy(outputhostname, optarg, copy_len); outputhostname[copy_len] = '\0'; } break; case 'h': /* help */ printf("Usage:\t%s\n", usage); exit(0); break; case 'V': /* version */ printf("%s %s\n", me, ipsec_version_code()); exit(0); break; case 'c': /* nss configuration directory */ case 'd': /* -d is used for configdir with nss tools */ configdir = optarg; break; case 'P': /* token authentication password */ password = optarg; break; case 's': /* seed bits */ seedbits = atoi(optarg); if (PK11_IsFIPS()) { if (seedbits < DEFAULT_SEED_BITS) { fprintf(stderr, "%s: FIPS mode does not allow < %d seed bits\n", me, DEFAULT_SEED_BITS); exit(1); } } break; case '?': default: printf("Usage:\t%s\n", usage); exit(2); } if (outputhostname[0] == '\0') { if (gethostname(outputhostname, sizeof(outputhostname)) < 0) { fprintf(stderr, "%s: gethostname failed (%s)\n", me, strerror(errno)); exit(1); } } if (argv[optind] == NULL) { /* default: spread bits between 3072 - 4096 in multiple's of 16 */ srand(time(NULL)); nbits = 3072 + 16 * (rand() % 64); } else { unsigned long u; err_t ugh = ttoulb(argv[optind], 0, 10, INT_MAX, &u); if (ugh != NULL) { fprintf(stderr, "%s: keysize specification is malformed: %s\n", me, ugh); exit(1); } nbits = u; } if (nbits < MIN_KEYBIT ) { fprintf(stderr, "%s: requested RSA key size of %d is too small - use %d or more\n", me, nbits, MIN_KEYBIT); exit(1); } else if (nbits > MAXBITS) { fprintf(stderr, "%s: overlarge bit count (max %d)\n", me, MAXBITS); exit(1); } else if (nbits % (BITS_PER_BYTE * 2) != 0) { fprintf(stderr, "%s: bit count (%d) not multiple of %d\n", me, nbits, (int)BITS_PER_BYTE * 2); exit(1); } rsasigkey(nbits, seedbits, configdir, password); exit(0); }
int main(int argc, char **argv) { int i, nspis; char *endptr; int said_opt = 0; const char* error_s = NULL; char ipaddr_txt[ADDRTOT_BUF]; int debug = 0; int j; struct said_af said_af_array[4]; int error = 0; struct sadb_ext *extensions[SADB_EXT_MAX + 1]; struct sadb_msg *pfkey_msg; #if 0 ip_address pfkey_address_s_ska; #endif program_name = argv[0]; for(i = 0; i < 4; i++) { memset(&said_af_array[i], 0, sizeof(struct said_af)); } if(argc > 1 && strcmp(argv[1], "--debug") == 0) { debug = 1; if(debug) { fprintf(stdout, "\"--debug\" option requested.\n"); } argv += 1; argc -= 1; pfkey_lib_debug = 1; } if(debug) { fprintf(stdout, "argc=%d (%d incl. --debug option).\n", argc, argc + 1); } if(argc > 1 && strcmp(argv[1], "--label") == 0) { if(argc > 2) { program_name = malloc(strlen(argv[0]) + 10 /* update this when changing the sprintf() */ + strlen(argv[2])); sprintf(program_name, "%s --label %s", argv[0], argv[2]); if(debug) { fprintf(stdout, "using \"%s\" as a label.\n", program_name); } argv += 2; argc -= 2; } else { fprintf(stderr, "%s: --label option requires an argument.\n", program_name); exit(1); } } if(debug) { fprintf(stdout, "...After check for --label option.\n"); } if(argc == 1) { system("cat /proc/net/ipsec_spigrp"); exit(0); } if(debug) { fprintf(stdout, "...After check for no option to print /proc/net/ipsec_spigrp.\n"); } if(strcmp(argv[1], "--help") == 0) { if(debug) { fprintf(stdout, "\"--help\" option requested.\n"); } usage(program_name); exit(1); } if(debug) { fprintf(stdout, "...After check for --help option.\n"); } if(strcmp(argv[1], "--version") == 0) { if(debug) { fprintf(stdout, "\"--version\" option requested.\n"); } fprintf(stdout, "%s %s\n", me, ipsec_version_code()); fprintf(stdout, "See `ipsec --copyright' for copyright information.\n"); exit(1); } if(debug) { fprintf(stdout, "...After check for --version option.\n"); } if(strcmp(argv[1], "--said") == 0) { if(debug) { fprintf(stdout, "processing %d args with --said flag.\n", argc); } said_opt = 1; } if(debug) { fprintf(stdout, "...After check for --said option.\n"); } if(said_opt) { if (argc < 3 /*|| argc > 5*/) { fprintf(stderr, "expecting 3 or more args with --said, got %d.\n", argc); usage(program_name); exit(1); } nspis = argc - 2; } else { if ((argc < 5) || (argc > 17) || ((argc % 4) != 1)) { fprintf(stderr, "expecting 5 or more args without --said, got %d.\n", argc); usage(program_name); exit(1); } nspis = argc / 4; } if(debug) { fprintf(stdout, "processing %d nspis.\n", nspis); } for(i = 0; i < nspis; i++) { if(debug) { fprintf(stdout, "processing spi #%d.\n", i); } if(said_opt) { error_s = ttosa((const char *)argv[i+2], 0, (ip_said*)&(said_af_array[i].said)); if(error_s != NULL) { fprintf(stderr, "%s: Error, %s converting --sa argument:%s\n", program_name, error_s, argv[i+2]); exit (1); } said_af_array[i].af = addrtypeof(&(said_af_array[i].said.dst)); if(debug) { addrtot(&said_af_array[i].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stdout, "said[%d].dst=%s.\n", i, ipaddr_txt); } } else { if(!strcmp(argv[i*4+4], "ah")) { said_af_array[i].said.proto = SA_AH; } if(!strcmp(argv[i*4+4], "esp")) { said_af_array[i].said.proto = SA_ESP; } if(!strcmp(argv[i*4+4], "tun")) { said_af_array[i].said.proto = SA_IPIP; } if(!strcmp(argv[i*4+4], "comp")) { said_af_array[i].said.proto = SA_COMP; } if(said_af_array[i].said.proto == 0) { fprintf(stderr, "%s: Badly formed proto: %s\n", program_name, argv[i*4+4]); exit(1); } said_af_array[i].said.spi = htonl(strtoul(argv[i*4+3], &endptr, 0)); if(!(endptr == argv[i*4+3] + strlen(argv[i*4+3]))) { fprintf(stderr, "%s: Badly formed spi: %s\n", program_name, argv[i*4+3]); exit(1); } if(!strcmp(argv[i*4+1], "inet")) { said_af_array[i].af = AF_INET; } if(!strcmp(argv[i*4+1], "inet6")) { said_af_array[i].af = AF_INET6; } if((said_af_array[i].af != AF_INET) && (said_af_array[i].af != AF_INET6)) { fprintf(stderr, "%s: Address family %s not supported\n", program_name, argv[i*4+1]); exit(1); } error_s = ttoaddr(argv[i*4+2], 0, said_af_array[i].af, &(said_af_array[i].said.dst)); if(error_s != NULL) { fprintf(stderr, "%s: Error, %s converting %dth address argument:%s\n", program_name, error_s, i, argv[i*4+2]); exit (1); } } if(debug) { fprintf(stdout, "SA %d contains: ", i+1); fprintf(stdout, "\n"); fprintf(stdout, "proto = %d\n", said_af_array[i].said.proto); fprintf(stdout, "spi = %08x\n", said_af_array[i].said.spi); addrtot(&said_af_array[i].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stdout, "edst = %s\n", ipaddr_txt); } } if(debug) { fprintf(stdout, "Opening pfkey socket.\n"); } if((pfkey_sock = socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0) { fprintf(stderr, "%s: Trouble opening PF_KEY family socket with error: ", program_name); switch(errno) { case ENOENT: fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n"); break; case EACCES: fprintf(stderr, "access denied. "); if(getuid() == 0) { fprintf(stderr, "Check permissions. Should be 600.\n"); } else { fprintf(stderr, "You must be root to open this file.\n"); } break; case EUNATCH: fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n"); break; case ENODEV: fprintf(stderr, "KLIPS not loaded or enabled.\n"); break; case EBUSY: fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n"); break; case EINVAL: fprintf(stderr, "Invalid argument, KLIPS not loaded or check kernel log messages for specifics.\n"); break; case ENOBUFS: fprintf(stderr, "No kernel memory to allocate SA.\n"); break; case ESOCKTNOSUPPORT: fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n"); break; case EEXIST: fprintf(stderr, "SA already in use. Delete old one first.\n"); break; case ENXIO: fprintf(stderr, "SA does not exist. Cannot delete.\n"); break; case EAFNOSUPPORT: fprintf(stderr, "KLIPS not loaded or enabled.\n"); break; default: fprintf(stderr, "Unknown file open error %d. Please report as much detail as possible to development team.\n", errno); } exit(1); } for(i = 0; i < (((nspis - 1) < 2) ? 1 : (nspis - 1)); i++) { if(debug) { fprintf(stdout, "processing %dth pfkey message.\n", i); } pfkey_extensions_init(extensions); for(j = 0; j < ((nspis == 1) ? 1 : 2); j++) { if(debug) { fprintf(stdout, "processing %dth said of %dth pfkey message.\n", j, i); } /* Build an SADB_X_GRPSA message to send down. */ /* It needs <base, SA, SA2, address(D,D2) > minimum. */ if(!j) { if((error = pfkey_msg_hdr_build(&extensions[0], SADB_X_GRPSA, proto2satype(said_af_array[i].said.proto), 0, ++pfkey_seq, getpid()))) { fprintf(stderr, "%s: Trouble building message header, error=%d.\n", program_name, error); pfkey_extensions_free(extensions); exit(1); } } else { if(debug) { fprintf(stdout, "setting x_satype proto=%d satype=%d\n", said_af_array[i+j].said.proto, proto2satype(said_af_array[i+j].said.proto) ); } if((error = pfkey_x_satype_build(&extensions[SADB_X_EXT_SATYPE2], proto2satype(said_af_array[i+j].said.proto) ))) { fprintf(stderr, "%s: Trouble building message header, error=%d.\n", program_name, error); pfkey_extensions_free(extensions); exit(1); } } if((error = pfkey_sa_build(&extensions[!j ? SADB_EXT_SA : SADB_X_EXT_SA2], !j ? SADB_EXT_SA : SADB_X_EXT_SA2, said_af_array[i+j].said.spi, /* in network order */ 0, 0, 0, 0, 0))) { fprintf(stderr, "%s: Trouble building sa extension, error=%d.\n", program_name, error); pfkey_extensions_free(extensions); exit(1); } #if 0 if(!j) { anyaddr(said_af_array[i].af, &pfkey_address_s_ska); /* Is the address family correct ?? */ if((error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], SADB_EXT_ADDRESS_SRC, 0, 0, sockaddrof(&pfkey_address_s_ska)))) { addrtot(&pfkey_address_s_ska, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stderr, "%s: Trouble building address_s extension (%s), error=%d.\n", program_name, ipaddr_txt, error); pfkey_extensions_free(extensions); exit(1); } } #endif if((error = pfkey_address_build(&extensions[!j ? SADB_EXT_ADDRESS_DST : SADB_X_EXT_ADDRESS_DST2], !j ? SADB_EXT_ADDRESS_DST : SADB_X_EXT_ADDRESS_DST2, 0, 0, sockaddrof(&said_af_array[i+j].said.dst)))) { addrtot(&said_af_array[i+j].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stderr, "%s: Trouble building address_d extension (%s), error=%d.\n", program_name, ipaddr_txt, error); pfkey_extensions_free(extensions); exit(1); } } if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) { fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n", program_name, error); pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); exit(1); } if((error = write(pfkey_sock, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) != pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN) { fprintf(stderr, "%s: pfkey write failed, returning %d with errno=%d.\n", program_name, error, errno); pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); switch(errno) { case EACCES: fprintf(stderr, "access denied. "); if(getuid() == 0) { fprintf(stderr, "Check permissions. Should be 600.\n"); } else { fprintf(stderr, "You must be root to open this file.\n"); } break; case EUNATCH: fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n"); break; case EBUSY: fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n"); break; case EINVAL: fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n"); break; case ENODEV: fprintf(stderr, "KLIPS not loaded or enabled.\n"); fprintf(stderr, "No device?!?\n"); break; case ENOBUFS: fprintf(stderr, "No kernel memory to allocate SA.\n"); break; case ESOCKTNOSUPPORT: fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n"); break; case EEXIST: fprintf(stderr, "SA already in use. Delete old one first.\n"); break; case ENOENT: fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n"); break; case ENXIO: fprintf(stderr, "SA does not exist. Cannot delete.\n"); break; default: fprintf(stderr, "Unknown socket write error %d. Please report as much detail as possible to development team.\n", errno); } exit(1); } if(pfkey_msg) { pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); } } (void) close(pfkey_sock); /* close the socket */ exit(0); }
/* - main - mostly argument parsing */ int main(int argc, char *argv[]) { log_to_stderr = FALSE; tool_init_log("ipsec rsasigkey"); int opt; int nbits = 0; int seedbits = DEFAULT_SEED_BITS; while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF) switch (opt) { case 'n': case 'p': fprintf(stderr, "%s: --noopt and --rounds options have been obsoleted - ignored\n", progname); break; case 'v': /* verbose description */ log_to_stderr = TRUE; break; case 'r': fprintf(stderr, "%s: Warning: --random is obsoleted for --seeddev. It no longer specifies the random device used for obtaining random key material", progname); /* FALLTHROUGH */ case 'S': /* nonstandard random device for seed */ device = optarg; break; case 'H': /* set hostname for output */ { size_t full_len = strlen(optarg); bool oflow = sizeof(outputhostname) - 1 < full_len; size_t copy_len = oflow ? sizeof(outputhostname) - 1 : full_len; memcpy(outputhostname, optarg, copy_len); outputhostname[copy_len] = '\0'; } break; case 'h': /* help */ printf("Usage:\t%s\n", usage); exit(0); break; case 'V': /* version */ printf("%s %s\n", progname, ipsec_version_code()); exit(0); break; case 'c': /* obsoleted by --nssdir|-d */ case 'd': /* -d is used for nssdirdir with nss tools */ lsw_conf_nssdir(optarg); break; case 'P': /* token authentication password */ lsw_conf_nsspassword(optarg); break; case 's': /* seed bits */ seedbits = atoi(optarg); if (PK11_IsFIPS()) { if (seedbits < DEFAULT_SEED_BITS) { fprintf(stderr, "%s: FIPS mode does not allow < %d seed bits\n", progname, DEFAULT_SEED_BITS); exit(1); } } break; case '?': default: printf("Usage:\t%s\n", usage); exit(2); } if (outputhostname[0] == '\0') { if (gethostname(outputhostname, sizeof(outputhostname)) < 0) { fprintf(stderr, "%s: gethostname failed (%s)\n", progname, strerror(errno)); exit(1); } } /* * RSA-PSS requires keysize to be a multiple of 8 bits * (see PCS#1 v2.1). * We require a multiple of 16. (??? why?) */ if (argv[optind] == NULL) { /* default keysize: a multiple of 16 in [3072,4096) */ srand(time(NULL)); nbits = 3072 + 16 * (rand() % (1024 / 16)); } else { unsigned long u; err_t ugh = ttoulb(argv[optind], 0, 10, INT_MAX, &u); if (ugh != NULL) { fprintf(stderr, "%s: keysize specification is malformed: %s\n", progname, ugh); exit(1); } nbits = u; } if (nbits < MIN_KEYBIT ) { fprintf(stderr, "%s: requested RSA key size (%d) is too small - use %d or more\n", progname, nbits, MIN_KEYBIT); exit(1); } else if (nbits > MAXBITS) { fprintf(stderr, "%s: requested RSA key size (%d) is too large - (max %d)\n", progname, nbits, MAXBITS); exit(1); } else if (nbits % (BITS_PER_BYTE * 2) != 0) { fprintf(stderr, "%s: requested RSA key size (%d) is not a multiple of %d\n", progname, nbits, (int)BITS_PER_BYTE * 2); exit(1); } /* * Don't fetch the config options until after they have been * processed, and really are "constant". */ const struct lsw_conf_options *oco = lsw_init_options(); rsasigkey(nbits, seedbits, oco); exit(0); }
int main(int argc, char **argv) { int lockfd; bool restore_vrf_pluto = 0; /*此开关必须放在所有动态内存分配之前*/ leak_detective=0; debug_info_control* dic=alloc_bytes(sizeof(debug_info_control), "malloc debug_info_control in main"); openswan_passert_fail = passert_fail; /*设备类型初始化*/ ipsec_device_type_init(); { u32 pseudo_start_pluto = 0; for (;;) { #define DBG_OFFSET 256 static const struct option long_opts[] = { /* name, has_arg, flag, val */ { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "start", no_argument, NULL, 'B' }, { "quit", no_argument, NULL, 'D' }, { "user", no_argument, NULL, 'u' }, { "krl", no_argument, NULL, 'K' }, { "debug-nat", no_argument, NULL, '5' }, { "debug-none", no_argument, NULL, 'N' }, { "debug-all", no_argument, NULL, 'A' }, { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET }, { "debug-crypto", no_argument, NULL, DBG_CRYPT + DBG_OFFSET }, { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET }, { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET }, { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET }, { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET }, { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET }, { "debug-netkey", no_argument, NULL, DBG_NETKEY + DBG_OFFSET }, { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET }, { "debug-oppoinfo", no_argument, NULL, DBG_OPPOINFO + DBG_OFFSET }, { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET }, { "debug-dpd", no_argument, NULL, DBG_DPD + DBG_OFFSET }, { "debug-xauth", no_argument, NULL, DBG_XAUTH+ DBG_OFFSET }, { "debug-x509", no_argument, NULL, DBG_X509 + DBG_OFFSET }, { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET }, { "debug-pfkey", no_argument, NULL, DBG_PFKEY + DBG_OFFSET }, { "debug-ifchange", no_argument, NULL, DBG_IF_CHANGE + DBG_OFFSET }, { "log-openinfo", no_argument, NULL, 'i' }, { "log-openwar", no_argument, NULL, 'w' }, { "log-openerr", no_argument, NULL, 'r' }, { "log-openuserlog", no_argument, NULL, 'e' }, { "log-openradiuslog", no_argument, NULL, 'c' }, { "log-openpri", no_argument, NULL, 'p' }, { "log-opensyserr", no_argument, NULL, 'q' }, { "log-closeall", no_argument, NULL, 'a' }, { "debug-connection", required_argument, NULL, 'O' }, { "debug-host", required_argument, NULL, 'H' }, { "debug-stop", no_argument, NULL, 'S' }, { "counter", no_argument, NULL, 'b' }, { "isa-counter", no_argument, NULL, 'x' }, { "krc", no_argument, NULL, 'E'}, { "kss", required_argument, NULL, 'F'}, { "kpc", no_argument, NULL, 'G'}, { "kprt", required_argument, NULL, 'L'}, { "kspi", required_argument, NULL, 'M' }, { "kdst", required_argument, NULL, 'P' }, { "kdnet", required_argument, NULL, 'R' }, { "kid", required_argument, NULL, 'Q' }, { "restore-vrf", no_argument, NULL, 'V' }, { 0,0,0,0 } }; int c = getopt_long(argc, argv, "", long_opts, NULL); ip_address dst_tmp; ip_subnet subnet_tmp; switch (c) { case EOF: /* end of flags */ break; case 0: /* long option already handled */ continue; case ':': /* diagnostic already printed by getopt_long */ case '?': /* diagnostic already printed by getopt_long */ usage(""); break; case 'h': usage(NULL); break; case 'v': { const char **sp = ipsec_copyright_notice(); printf("%s%s\n", ipsec_version_string(),compile_time_interop_options); for (; *sp != NULL; sp++) { puts(*sp); } } exit(0); break; case 'i': dic->public_info.log_falg = 1; dic->public_info.log_level_info |= IPSEC_LOGLEVEL_INFO; continue; case 'w': dic->public_info.log_falg = 1; dic->public_info.log_level_info |= IPSEC_LOGLEVEL_WARNING; continue; case 'r': dic->public_info.log_falg = 1; dic->public_info.log_level_info |= IPSEC_LOGLEVEL_ERROR; continue; case 'e': dic->public_info.log_falg = 1; dic->public_info.log_level_info |= IPSEC_LOGLEVEL_USER_LOG; continue; case 'c': dic->public_info.log_falg = 1; dic->public_info.log_level_info |= IPSEC_LOGLEVEL_RADIUS_LOG; continue; case 'p': dic->public_info.log_falg = 1; dic->public_info.log_level_info |= IPSEC_LOGLEVEL_PRIVATE; continue; case 'q': dic->public_info.log_falg = 1; dic->public_info.log_level_info |= IPSEC_LOGLEVEL_SYSERROR; continue; case 'a': dic->public_info.log_falg = 1; dic->public_info.log_level_info=IPSEC_LOGLEVEL_CLOSE; continue; case 'B': dic->com_type=IPSEC_DEBUG_STAR_HANDLE; continue; case 'D': dic->com_type=IPSEC_DEBUG_QUIT_HANDLE; continue; case 'u': dic->com_type=IPSEC_DEBUG_USER_HANDLE; continue; case 'K': dic->com_type=IPSEC_DEBUG_KERNEL_HANDLE; continue; case 'N': /* --debug-none */ dic->public_info.public_info_flag=1; dic->public_info.public_info_value=DBG_NONE; continue; case 'A': /* --debug-all */ dic->public_info.public_info_flag=1; dic->public_info.public_info_value=DBG_ALL; continue; case 'O': if(optarg != NULL) { strcpy(dic->child_info.child_info_optarg,optarg); dic->child_info.child_info_type=IPSEC_CHILD_DEBUG_INFO_CON_NAME; } else { return 0; } break; case 'H': if(optarg != NULL) { strcpy(dic->child_info.child_info_optarg,optarg); dic->child_info.child_info_type=IPSEC_CHILD_DEBUG_INFO_HOST; } else { return 0; } break; case 'S': dic->child_info.child_info_type=IPSEC_CHILD_DEBUG_INFO_STOP; break; case 'b': dic->child_info.child_info_type=IPSEC_CHILD_DEBUG_INFO_PRINT_COUNTER; break; case 'x': dic->child_info.child_info_type=IPSEC_CHILD_DEBUG_INFO_PRINT_ISA_COUNTER; break; case 'E': pseudo_start_pluto = 1; dic->kernel_info.flag= IPSEC_RESET_COUNTER; continue; case 'F': pseudo_start_pluto = 1; dic->kernel_info.flag = IPSEC_SET_DEBUG_SIP; dic->kernel_info.sip =inet_addr(optarg); continue; case 'G': pseudo_start_pluto = 1; dic->kernel_info.flag = IPSEC_DUMP_COUNTER; continue; case 'L': pseudo_start_pluto = 1; dic->kernel_info.flag=IPSEC_PRINT_INTERFACE_TEMP; if_get_index_by_name(optarg, (s32*)(&dic->kernel_info.ifindex)); continue; case 'M': pseudo_start_pluto = 1; dic->kernel_info.flag=IPSEC_PRINT_INTERFACE_TEMP; dic->kernel_info.spi = (u32)chartoint(optarg,strlen(optarg)); if((int)dic->kernel_info.spi < 0) { fprintf(stderr,"%s IS ERROR INPUT(For Example:0x123...)\n",optarg); pfree(dic); return 0; } continue; case 'P': pseudo_start_pluto = 1; dic->kernel_info.flag=IPSEC_PRINT_INTERFACE_TEMP; if(ttoaddr(optarg, 0, AF_INET, &dst_tmp)) { fprintf(stderr,"you must input right IP\n"); pfree(dic); return 0; } else{ dic->kernel_info.dsc.a4 = dst_tmp.u.v4.sin_addr.s_addr; continue; } case 'R': pseudo_start_pluto = 1; dic->kernel_info.flag=IPSEC_PRINT_INTERFACE_TEMP; if(ttosubnet(optarg, 0, AF_INET, &subnet_tmp)) { fprintf(stderr,"you must input right subnet\n"); pfree(dic); return 0; } else{ dic->kernel_info.net.a4 = subnet_tmp.addr.u.v4.sin_addr.s_addr; continue; } case 'Q': pseudo_start_pluto = 1; dic->kernel_info.flag=IPSEC_PRINT_INTERFACE_TEMP; dic->kernel_info.connid = atoi(optarg); continue; case 'V': { restore_vrf_pluto = 1; } continue; default: if (c >= DBG_OFFSET) { dic->public_info.public_info_flag=1; dic->public_info.public_info_value |= c - DBG_OFFSET; } continue; bad_case(c); } break; } /** if(restore_vrf_pluto) { ipsec_restore_vrf_pluto(); } **/ ipsec_restore_vrf_pluto(); { u32 err; conplat_syscall(MODULEID_OSBASIC, OSBASIC_GET_VRF_ID, &g_ipsec_vrf_id, sizeof(g_ipsec_vrf_id), (s32*)(&err)); if(err != 0) { g_ipsec_vrf_id = 0; } sprintf(pluto_lock + strlen(pluto_lock), "_%d", g_ipsec_vrf_id); sprintf(ctl_addr.sun_path+ strlen(ctl_addr.sun_path), "_%d", g_ipsec_vrf_id); sprintf(ws_ctl_addr.sun_path+ strlen(ws_ctl_addr.sun_path), "_%d", g_ipsec_vrf_id); } switch(dic->com_type) { case IPSEC_DEBUG_STAR_HANDLE: if(dic->public_info.public_info_flag) { cur_debugging = dic->public_info.public_info_value; } if(dic->public_info.log_falg) { g_log_level = dic->public_info.log_level_info; } break; case IPSEC_DEBUG_USER_HANDLE: send_connection_debug(dic, IPSEC_DEBUG_USER_HANDLE); pfree(dic); return 0; case IPSEC_DEBUG_KERNEL_HANDLE: if(pseudo_start_pluto == 1) { u32 syscall_result = 0; if((dic->kernel_info.flag==IPSEC_PRINT_INTERFACE_TEMP)&&(0 == dic->kernel_info.ifindex)) { fprintf(stderr,"you must input the if name\n"); pfree(dic); return 0; } conplat_syscall(MODULEID_IPSEC_POLICY, IPSEC_MODULE_DEBUG_PART, (void *)(&dic->kernel_info), sizeof(struct ipsec_user_debug_info), (s32 *)(&syscall_result)); if(g_ipsec_device_is_dpx) { (u32)conplat_syscall(FW_MODULEID_IPSEC | FW_BOARD, IPSEC_MODULE_DEBUG_PART, (void *)(&dic->kernel_info), sizeof(struct ipsec_user_debug_info), (s32 *)(&syscall_result)); } } else { fprintf(stderr,"after --kernel ,you must input the right command\n"); } pfree(dic); return 0; case IPSEC_DEBUG_QUIT_HANDLE: send_connection_debug(dic, IPSEC_DEBUG_QUIT_HANDLE); pfree(dic); return 0; default: fprintf(stderr,"you must input --start --quit --user or --kernel\n"); exit(0); } pfree(dic); } if (optind != argc) { usage("unexpected argument"); } //如果你想再重启设备后默认打开调试开关 #if 0 cur_debugging = DBG_ALL; #endif lockfd = create_lock(); g_log_level |= ws_get_log_level(); //获得显示级别 g_ipsec_multiout = ws_get_multiOut(); //获取多接口转发标志位 if(g_ipsec_multiout) { int res; conplat_syscall(MODULEID_IPSEC_POLICY, IPSEC_MODULE_MULTI_OUT, &(g_ipsec_multiout), sizeof(g_ipsec_multiout), &res); } ipsec_restore_tunnel_ipsec(); ipsec_init_lv2_switch(); ipsec_init_route_mode(); ipsec_init_user_syn(); ipsec_init_compress_enable(); ipsec_init_udp_checksum_switch(); ipsec_init_cookie(); ipsec_esp_alg_init(); init_vendorid(); //daemon之前销毁缓冲池中的数据库句柄,使用make_daemon不用加此函数 sqlite3_clear_buffer_ex(); { { pid_t pid = fork(); if (pid < 0) { int e = errno; fprintf(stderr, "pluto: fork failed (%d %s)\n",errno, strerror(e)); exit_pluto(1); } if (pid != 0) { /* parent: die, after filling PID into lock file. * must not use exit_pluto: lock would be removed! */ exit(fill_lock(lockfd, pid)? 0 : 1); } } if (setsid() < 0) { int e = errno; fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n",errno, strerror(e)); exit_pluto(1); } } /** Close everything but and (if needed) stderr. * There is some danger that a library that we don't know * about is using some fd that we don't know about. * I guess we'll soon find out. */ { int i; for (i = getdtablesize() - 1; i >= 0; i--) /* Bad hack */ { close(i); } /* make sure that stdin, stdout, stderr are reserved */ if (open("/dev/null", O_RDONLY) != 0) { IPSEC_abort(); } if (dup2(0, 1) != 1) { IPSEC_abort(); } } init_constants(); init_pluto_vendorid(); ipsec_version_code(); ipsec_get_slot_bit(); // 需要放在ipsec_template_delete_all 前面 ipsec_template_delete_all(); ipsec_enable_flag(1); ipsec_init_nat_traversal(); init_rnd_pool(); init_states(); init_connections();//添加到elist链中phase2 pending timer init_crypto(); ipsec_drv_rsa_para_init(); //初始化使用硬件模幂运算时的固定参数 load_oswcrypto(); init_demux(); /* loading X.509 CA certificates */ load_authcerts("CA cert", "/config/sys/certificate/cacerts", AUTH_CA); /* loading X.509 CRLs */ load_crls(); fflush(stderr); fflush(stdout); IPSEC_dbg("listening for IKE messages"); init_ws_ctl_socket(); /*初始化dpdns守护进程*/ ipsec_dpdns_init_helper(); /*读取DPVPN相关配置并初始化*/ //ipsec_dpvpn_init_cfg(); /*该操作放在操作数据库之后的主进程处理不能再数据操作*/ sqlite3_clear_buffer_ex(); /*初始化子进程*/ ipsec_child_init_helpers(); ipsec_main_call_server(); return -1; /* Shouldn't ever reach this */ }
int main(int argc, char **argv) { char *foo; const char *errstr; int s; int listen_only; int lport,dport; int afamily; int pfamily; int c; int numSenders, numReceived; int natt; int waitTime; int verbose; ip_address laddr, raddr; char *afam = ""; progname = argv[0]; afamily=AF_INET; pfamily=PF_INET; lport=500; dport=500; waitTime=3*1000; verbose=0; natt=0; listen_only=0; bzero(&laddr, sizeof(laddr)); while((c = getopt_long(argc, argv, "hVvsp:b:46E:w:", long_opts, 0))!=EOF) { switch (c) { case 'h': /* --help */ help(); return 0; /* GNU coding standards say to stop here */ case 'V': /* --version */ fprintf(stderr, "Openswan %s\n", ipsec_version_code()); return 0; /* GNU coding standards say to stop here */ case 'v': /* --label <string> */ verbose++; continue; case 'T': natt++; break; case 'E': exchange_number=strtol(optarg, &foo, 0); if(optarg==foo || exchange_number < 1 || exchange_number>255) { fprintf(stderr, "Invalid exchange number '%s' (should be 1<=x<255)\n", optarg); exit(1); } continue; case 's': listen_only++; continue; case 'p': lport=strtol(optarg, &foo, 0); if(optarg==foo || lport <0 || lport>65535) { fprintf(stderr, "Invalid port number '%s' (should be 0<=x<65536)\n", optarg); exit(1); } fprintf(stderr, "setting source port to %u\n", lport); continue; case 'w': /* convert msec to sec */ waitTime=strtol(optarg, &foo, 0)*500; if(optarg==foo || waitTime < 0) { fprintf(stderr, "Invalid waittime number '%s' (should be 0<=x)\n", optarg); exit(1); } continue; case 'b': errstr = ttoaddr(optarg, strlen(optarg), afamily, &laddr); if(errstr!=NULL) { fprintf(stderr, "Invalid local address '%s': %s\n", optarg, errstr); exit(1); } continue; case '4': afamily=AF_INET; pfamily=PF_INET; afam = "IPv4"; continue; case '6': afamily=AF_INET6; pfamily=PF_INET6; afam = "IPv6"; continue; default: help(); } } s=safe_socket(pfamily, SOCK_DGRAM, IPPROTO_UDP); if(s < 0) { perror("socket"); exit(3); } switch(afamily) { case AF_INET: laddr.u.v4.sin_family= AF_INET; laddr.u.v4.sin_port = htons(lport); if(bind(s, (struct sockaddr *)&laddr.u.v4, sizeof(laddr.u.v4)) < 0) { fprintf(stderr, "warning, unable to bind v4 socket port %u: %s" , lport, strerror(errno)); } break; case AF_INET6: laddr.u.v6.sin6_family= AF_INET6; laddr.u.v6.sin6_port = htons(lport); if(bind(s, (struct sockaddr *)&laddr.u.v6, sizeof(laddr.u.v6)) < 0) { fprintf(stderr, "warning, unable to bind v6 socket to port %u: %s" , lport, strerror(errno)); } break; } if(natt) { int r; /* only support RFC method */ int type = ESPINUDP_WITH_NON_ESP; r = setsockopt(s, SOL_UDP, UDP_ESPINUDP, &type, sizeof(type)); if ((r<0) && (errno == ENOPROTOOPT)) { fprintf(stderr, "NAT-Traversal: ESPINUDP(%d) not supported by kernel for family %s" , type, afam); } } numSenders = 0; if(!listen_only) { while(optind < argc) { char *port; char *host; char namebuf[128]; host = argv[optind]; port = strchr(host, '/'); dport=500; if(port) { *port='\0'; port++; dport= strtol(port, &foo, 0); if(port==foo || dport < 0 || dport > 65535) { fprintf(stderr, "Invalid port number '%s' " "(should be 0<=x<65536)\n", port); exit(1); } } errstr = ttoaddr(host, strlen(host), afamily, &raddr); if(errstr!=NULL) { fprintf(stderr, "Invalid remote address '%s': %s\n", host, errstr); exit(1); } addrtot(&raddr, 0, namebuf, sizeof(namebuf)); printf("Sending packet to %s/%d\n", namebuf, dport); send_ping(afamily, s, &raddr, dport); numSenders++; optind++; } } numReceived=0; /* really should catch ^C and print stats on exit */ while(numSenders > 0 || listen_only) { struct pollfd ready; int n; ready.fd = s; ready.events = POLLIN; n = poll(&ready, 1, waitTime); if(n < 0) { if(errno != EINTR) { perror("poll"); exit(1); } } if(n == 0 && !listen_only) { break; } if(n == 1) { numReceived++; receive_ping(afamily, s, listen_only, natt); } } printf("%d packets sent, %d packets received. %d%% packet loss\n", numSenders, numReceived, numSenders > 0 ? 100-numReceived*100/numSenders : 0); exit(numSenders - numReceived); }
/* void */ int ipsec_klips_init(void) { int error = 0; unsigned char seed[256]; #ifdef CONFIG_KLIPS_ENC_3DES extern int des_check_key; /* turn off checking of keys */ des_check_key=0; #endif /* CONFIG_KLIPS_ENC_3DES */ KLIPS_PRINT(1, "klips_info:ipsec_init: " "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n", ipsec_version_code()); error |= ipsec_proc_init(); #ifdef SPINLOCK ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED; #else /* SPINLOCK */ ipsec_sadb.sadb_lock = 0; #endif /* SPINLOCK */ #ifndef SPINLOCK tdb_lock.lock = 0; eroute_lock.lock = 0; #endif /* !SPINLOCK */ error |= ipsec_sadb_init(); error |= ipsec_radijinit(); error |= pfkey_init(); error |= register_netdevice_notifier(&ipsec_dev_notifier); #ifdef CONFIG_KLIPS_ESP openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP); #endif /* CONFIG_KLIPS_ESP */ #ifdef CONFIG_KLIPS_AH openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH); #endif /* CONFIG_KLIPS_AH */ /* we never actually link IPCOMP to the stack */ #ifdef IPCOMP_USED_ALONE #ifdef CONFIG_KLIPS_IPCOMP openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP); #endif /* CONFIG_KLIPS_IPCOMP */ #endif error |= ipsec_tunnel_init_devices(); #if defined(NET_26) && defined(CONFIG_IPSEC_NAT_TRAVERSAL) /* register our ESP-UDP handler */ if(udp4_register_esp_rcvencap(klips26_rcv_encap , &klips_old_encap)!=0) { printk(KERN_ERR "KLIPS: can not register klips_rcv_encap function\n"); } #endif #ifdef CONFIG_SYSCTL error |= ipsec_sysctl_register(); #endif #ifdef CONFIG_KLIPS_ALG ipsec_alg_init(); #endif #ifdef CONFIG_KLIPS_OCF ipsec_ocf_init(); #endif get_random_bytes((void *)seed, sizeof(seed)); prng_init(&ipsec_prng, seed, sizeof(seed)); atomic_set(&ipsec_irs_cnt, 0); atomic_set(&ipsec_ixs_cnt, 0); ipsec_irs_cache = kmem_cache_create("ipsec_irs", sizeof(struct ipsec_rcv_state), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (!ipsec_irs_cache) { printk("Failed to get IRS cache\n"); error |= 1; } ipsec_ixs_cache = kmem_cache_create("ipsec_ixs", sizeof(struct ipsec_xmit_state), 0, SLAB_HWCACHE_ALIGN, NULL, NULL); if (!ipsec_ixs_cache) { printk("Failed to get IXS cache\n"); error |= 1; } return error; }
int main(int argc, char **argv) { /* int fd; */ unsigned char action = 0; int c; int error = 0; int argcount = argc; int em_db_tn, em_db_nl, em_db_xf, em_db_er, em_db_sp; int em_db_rj, em_db_es, em_db_ah, em_db_rx, em_db_ky; int em_db_gz, em_db_vb; struct sadb_ext *extensions[K_SADB_EXT_MAX + 1]; struct sadb_msg *pfkey_msg; em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=0; em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=0; em_db_gz=em_db_vb=0; program_name = argv[0]; while((c = getopt_long(argc, argv, ""/*"s:c:anhvl:+:d"*/, longopts, 0)) != EOF) { switch(c) { case 'd': pfkey_lib_debug = PF_KEY_DEBUG_PARSE_MAX; argcount--; break; case 's': if(action) { fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n", program_name); exit(1); } action = 's'; em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=0; em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=0; em_db_gz=em_db_vb=0; if(strcmp(optarg, "all") == 0) { em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=-1; em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=-1; em_db_gz=-1; em_db_vb= 0; } else if(strcmp(optarg, "tunnel") == 0) { em_db_tn = -1L; } else if(strcmp(optarg, "tncfg") == 0) { em_db_tn = DB_TN_REVEC; } else if(strcmp(optarg, "xmit") == 0 || strcmp(optarg, "tunnel-xmit") == 0) { em_db_tn = DB_TN_XMIT; } else if(strcmp(optarg, "netlink") == 0) { em_db_nl = -1L; } else if(strcmp(optarg, "xform") == 0) { em_db_xf = -1L; } else if(strcmp(optarg, "eroute") == 0) { em_db_er = -1L; } else if(strcmp(optarg, "spi") == 0) { em_db_sp = -1L; } else if(strcmp(optarg, "radij") == 0) { em_db_rj = -1L; } else if(strcmp(optarg, "esp") == 0) { em_db_es = -1L; } else if(strcmp(optarg, "ah") == 0) { em_db_ah = -1L; } else if(strcmp(optarg, "rcv") == 0) { em_db_rx = -1L; } else if(strcmp(optarg, "pfkey") == 0) { em_db_ky = -1L; } else if(strcmp(optarg, "comp") == 0) { em_db_gz = -1L; } else if(strcmp(optarg, "verbose") == 0) { em_db_vb = -1L; } else { fprintf(stdout, "%s: unknown set argument '%s'\n", program_name, optarg); usage(program_name); } em_db_nl |= 1 << (sizeof(em_db_nl) * 8 -1); break; case 'c': if(action) { fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n", program_name); exit(1); } em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=-1; em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=-1; em_db_gz=em_db_vb=-1; action = 'c'; if(strcmp(optarg, "all") == 0) { em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=0; em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=0; em_db_gz=em_db_vb=0; } else if(strcmp(optarg, "tunnel") == 0) { em_db_tn = 0; } else if(strcmp(optarg, "tunnel-xmit") == 0 || strcmp(optarg, "xmit") == 0) { em_db_tn = ~DB_TN_XMIT; } else if(strcmp(optarg, "netlink") == 0) { em_db_nl = 0; } else if(strcmp(optarg, "xform") == 0) { em_db_xf = 0; } else if(strcmp(optarg, "eroute") == 0) { em_db_er = 0; } else if(strcmp(optarg, "spi") == 0) { em_db_sp = 0; } else if(strcmp(optarg, "radij") == 0) { em_db_rj = 0; } else if(strcmp(optarg, "esp") == 0) { em_db_es = 0; } else if(strcmp(optarg, "ah") == 0) { em_db_ah = 0; } else if(strcmp(optarg, "rcv") == 0) { em_db_rx = 0; } else if(strcmp(optarg, "pfkey") == 0) { em_db_ky = 0; } else if(strcmp(optarg, "comp") == 0) { em_db_gz = 0; } else if(strcmp(optarg, "verbose") == 0) { em_db_vb = 0; } else { fprintf(stdout, "%s: unknown clear argument '%s'\n", program_name, optarg); usage(program_name); } em_db_nl &= ~(1 << (sizeof(em_db_nl) * 8 -1)); break; case 'a': if(action) { fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n", program_name); exit(1); } action = 'a'; em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=-1; em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=-1; em_db_gz=-1; em_db_vb= 0; break; case 'n': if(action) { fprintf(stderr, "%s: Only one of '--set', '--clear', '--all' or '--none' options permitted.\n", program_name); exit(1); } action = 'n'; em_db_tn=em_db_nl=em_db_xf=em_db_er=em_db_sp=0; em_db_rj=em_db_es=em_db_ah=em_db_rx=em_db_ky=0; em_db_gz=em_db_vb=0; break; case 'h': case '?': usage(program_name); exit(1); case 'v': fprintf(stdout, "klipsdebug (Openswan %s) \n", ipsec_version_code()); fputs(copyright, stdout); exit(0); case 'l': program_name = malloc(strlen(argv[0]) + 10 /* update this when changing the sprintf() */ + strlen(optarg)); sprintf(program_name, "%s --label %s", argv[0], optarg); argcount -= 2; break; case '+': /* optionsfrom */ optionsfrom(optarg, &argc, &argv, optind, stderr); /* no return on error */ break; default: fprintf(stdout, "%s: unknown option '%s'\n", program_name, argv[optind]); break; } } if(argcount == 1) { int ret = system("cat /proc/net/ipsec_klipsdebug"); exit(ret != -1 && WIFEXITED(ret) ? WEXITSTATUS(ret) : 1); } if(!action) { usage(program_name); } if((pfkey_sock = safe_socket(PF_KEY, SOCK_RAW, PF_KEY_V2) ) < 0) { fprintf(stderr, "%s: Trouble opening PF_KEY family socket with error: ", program_name); switch(errno) { case ENOENT: fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n"); break; case EACCES: fprintf(stderr, "access denied. "); if(getuid() == 0) { fprintf(stderr, "Check permissions. Should be 600.\n"); } else { fprintf(stderr, "You must be root to open this file.\n"); } break; case EUNATCH: fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n"); break; case ENODEV: fprintf(stderr, "KLIPS not loaded or enabled.\n"); break; case EBUSY: fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n"); break; case EINVAL: fprintf(stderr, "Invalid argument, KLIPS not loaded or check kernel log messages for specifics.\n"); break; case ENOBUFS: fprintf(stderr, "No kernel memory to allocate SA.\n"); break; case ESOCKTNOSUPPORT: fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n"); break; case EEXIST: fprintf(stderr, "SA already in use. Delete old one first.\n"); break; case ENXIO: fprintf(stderr, "SA does not exist. Cannot delete.\n"); break; case EAFNOSUPPORT: fprintf(stderr, "KLIPS not loaded or enabled.\n"); break; default: fprintf(stderr, "Unknown file open error %d. Please report as much detail as possible to development team.\n", errno); } exit(1); } pfkey_extensions_init(extensions); if((error = pfkey_msg_hdr_build(&extensions[0], SADB_X_DEBUG, 0, 0, ++pfkey_seq, getpid()))) { fprintf(stderr, "%s: Trouble building message header, error=%d.\n", program_name, error); pfkey_extensions_free(extensions); exit(1); } if((error = pfkey_x_debug_build(&extensions[SADB_X_EXT_DEBUG], em_db_tn, em_db_nl, em_db_xf, em_db_er, em_db_sp, em_db_rj, em_db_es, em_db_ah, em_db_rx, em_db_ky, em_db_gz, em_db_vb))) { fprintf(stderr, "%s: Trouble building message header, error=%d.\n", program_name, error); pfkey_extensions_free(extensions); exit(1); } if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) { fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n", program_name, error); pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); exit(1); } if((error = write(pfkey_sock, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) != (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) { fprintf(stderr, "%s: pfkey write failed, tried to write %u octets, returning %d with errno=%d.\n", program_name, (unsigned)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN), error, errno); pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); switch(errno) { case EACCES: fprintf(stderr, "access denied. "); if(getuid() == 0) { fprintf(stderr, "Check permissions. Should be 600.\n"); } else { fprintf(stderr, "You must be root to open this file.\n"); } break; case EUNATCH: fprintf(stderr, "Netlink not enabled OR KLIPS not loaded.\n"); break; case EBUSY: fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n"); break; case EINVAL: fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n"); break; case ENODEV: fprintf(stderr, "KLIPS not loaded or enabled.\n"); fprintf(stderr, "No device?!?\n"); break; case ENOBUFS: fprintf(stderr, "No kernel memory to allocate SA.\n"); break; case ESOCKTNOSUPPORT: fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n"); break; case EEXIST: fprintf(stderr, "SA already in use. Delete old one first.\n"); break; case ENOENT: fprintf(stderr, "device does not exist. See FreeS/WAN installation procedure.\n"); break; case ENXIO: fprintf(stderr, "SA does not exist. Cannot delete.\n"); break; case ENOSPC: fprintf(stderr, "no room in kernel SAref table. Cannot process request.\n"); break; case ESPIPE: fprintf(stderr, "kernel SAref table internal error. Cannot process request.\n"); break; default: fprintf(stderr, "Unknown socket write error %d. Please report as much detail as possible to development team.\n", errno); } exit(1); } if(pfkey_msg) { pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); } (void) close(pfkey_sock); /* close the socket */ exit(0); }
int main(int argc, char **argv) { int i, nspis; char *endptr; int said_opt = 0; const char* error_s = NULL; char ipaddr_txt[ADDRTOT_BUF]; int j; struct said_af said_af_array[4]; int error = 0; struct stat sts; struct sadb_ext *extensions[K_SADB_EXT_MAX + 1]; struct sadb_msg *pfkey_msg; #if 0 ip_address pfkey_address_s_ska; #endif progname = argv[0]; for(i = 0; i < 4; i++) { memset(&said_af_array[i], 0, sizeof(struct said_af)); } if(argc > 1 && strcmp(argv[1], "--debug") == 0) { debug = 1; if(debug) { fprintf(stdout, "\"--debug\" option requested.\n"); } argv += 1; argc -= 1; pfkey_lib_debug = PF_KEY_DEBUG_PARSE_MAX; } if(debug) { fprintf(stdout, "argc=%d (%d incl. --debug option).\n", argc, argc + 1); } if(argc > 1 && strcmp(argv[1], "--label") == 0) { if(argc > 2) { progname = malloc(strlen(argv[0]) + 10 /* update this when changing the sprintf() */ + strlen(argv[2])); sprintf(progname, "%s --label %s", argv[0], argv[2]); if(debug) { fprintf(stdout, "using \"%s\" as a label.\n", progname); } argv += 2; argc -= 2; } else { fprintf(stderr, "%s: --label option requires an argument.\n", progname); exit(1); } } if(debug) { fprintf(stdout, "...After check for --label option.\n"); } if ( ((stat ("/proc/net/pfkey", &sts)) == 0) ) { fprintf(stderr, "%s: NETKEY does not use the ipsec spigrp command. Use 'ip xfrm' instead.\n",progname); exit(1); } if(argc == 1) { int ret = 1; if ((stat ("/proc/net/ipsec_spigrp", &sts)) != 0) { fprintf(stderr, "%s: No spigrp - no IPsec support in kernel (are the modules loaded?)\n", progname); } else { ret = system("cat /proc/net/ipsec_spigrp"); ret = ret != -1 && WIFEXITED(ret) ? WEXITSTATUS(ret) : 1; } exit(ret); } if(debug) { fprintf(stdout, "...After check for no option to print /proc/net/ipsec_spigrp.\n"); } if(strcmp(argv[1], "--help") == 0) { if(debug) { fprintf(stdout, "\"--help\" option requested.\n"); } usage(progname); exit(1); } if(debug) { fprintf(stdout, "...After check for --help option.\n"); } if(strcmp(argv[1], "--version") == 0) { if(debug) { fprintf(stdout, "\"--version\" option requested.\n"); } fprintf(stderr, "%s, %s\n", progname, ipsec_version_code()); exit(1); } if(debug) { fprintf(stdout, "...After check for --version option.\n"); } if(strcmp(argv[1], "--said") == 0) { if(debug) { fprintf(stdout, "processing %d args with --said flag.\n", argc); } said_opt = 1; } if(debug) { fprintf(stdout, "...After check for --said option.\n"); } if(said_opt) { if (argc < 3 /*|| argc > 5*/) { fprintf(stderr, "expecting 3 or more args with --said, got %d.\n", argc); usage(progname); exit(1); } nspis = argc - 2; } else { if ((argc < 5) || (argc > 17) || ((argc % 4) != 1)) { fprintf(stderr, "expecting 5 or more args without --said, got %d.\n", argc); usage(progname); exit(1); } nspis = argc / 4; } if(debug) { fprintf(stdout, "processing %d nspis.\n", nspis); } for(i = 0; i < nspis; i++) { if(debug) { fprintf(stdout, "processing spi #%d.\n", i); } if(said_opt) { error_s = ttosa((const char *)argv[i+2], 0, (ip_said*)&(said_af_array[i].said)); if(error_s != NULL) { fprintf(stderr, "%s: Error, %s converting --sa argument:%s\n", progname, error_s, argv[i+2]); exit (1); } said_af_array[i].af = addrtypeof(&(said_af_array[i].said.dst)); if(debug) { addrtot(&said_af_array[i].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stdout, "said[%d].dst=%s.\n", i, ipaddr_txt); } } else { if(!strcmp(argv[i*4+4], "ah")) { said_af_array[i].said.proto = SA_AH; } if(!strcmp(argv[i*4+4], "esp")) { said_af_array[i].said.proto = SA_ESP; } if(!strcmp(argv[i*4+4], "tun")) { said_af_array[i].said.proto = SA_IPIP; } if(!strcmp(argv[i*4+4], "comp")) { said_af_array[i].said.proto = SA_COMP; } if(said_af_array[i].said.proto == 0) { fprintf(stderr, "%s: Badly formed proto: %s\n", progname, argv[i*4+4]); exit(1); } said_af_array[i].said.spi = htonl(strtoul(argv[i*4+3], &endptr, 0)); if(!(endptr == argv[i*4+3] + strlen(argv[i*4+3]))) { fprintf(stderr, "%s: Badly formed spi: %s\n", progname, argv[i*4+3]); exit(1); } if(!strcmp(argv[i*4+1], "inet")) { said_af_array[i].af = AF_INET; } if(!strcmp(argv[i*4+1], "inet6")) { said_af_array[i].af = AF_INET6; } if((said_af_array[i].af != AF_INET) && (said_af_array[i].af != AF_INET6)) { fprintf(stderr, "%s: Address family %s not supported\n", progname, argv[i*4+1]); exit(1); } error_s = ttoaddr(argv[i*4+2], 0, said_af_array[i].af, &(said_af_array[i].said.dst)); if(error_s != NULL) { fprintf(stderr, "%s: Error, %s converting %dth address argument:%s\n", progname, error_s, i, argv[i*4+2]); exit (1); } } if(debug) { fprintf(stdout, "SA %d contains: ", i+1); fprintf(stdout, "\n"); fprintf(stdout, "proto = %d\n", said_af_array[i].said.proto); fprintf(stdout, "spi = %08x\n", said_af_array[i].said.spi); addrtot(&said_af_array[i].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stdout, "edst = %s\n", ipaddr_txt); } } if(debug) { fprintf(stdout, "Opening pfkey socket.\n"); } pfkey_sock = pfkey_open_sock_with_error(); if(pfkey_sock < 0) { exit(1); } for(i = 0; i < (((nspis - 1) < 2) ? 1 : (nspis - 1)); i++) { if(debug) { fprintf(stdout, "processing %dth pfkey message.\n", i); } pfkey_extensions_init(extensions); for(j = 0; j < ((nspis == 1) ? 1 : 2); j++) { if(debug) { fprintf(stdout, "processing %dth said of %dth pfkey message.\n", j, i); } /* Build an SADB_X_GRPSA message to send down. */ /* It needs <base, SA, SA2, address(D,D2) > minimum. */ if(!j) { if((error = pfkey_msg_hdr_build(&extensions[0], K_SADB_X_GRPSA, proto2satype(said_af_array[i].said.proto), 0, ++pfkey_seq, getpid()))) { fprintf(stderr, "%s: Trouble building message header, error=%d.\n", progname, error); pfkey_extensions_free(extensions); exit(1); } } else { if(debug) { fprintf(stdout, "setting x_satype proto=%d satype=%d\n", said_af_array[i+j].said.proto, proto2satype(said_af_array[i+j].said.proto) ); } if((error = pfkey_x_satype_build(&extensions[K_SADB_X_EXT_SATYPE2], proto2satype(said_af_array[i+j].said.proto) ))) { fprintf(stderr, "%s: Trouble building message header, error=%d.\n", progname, error); pfkey_extensions_free(extensions); exit(1); } } if((error = pfkey_sa_build(&extensions[!j ? K_SADB_EXT_SA : K_SADB_X_EXT_SA2], !j ? K_SADB_EXT_SA : K_SADB_X_EXT_SA2, said_af_array[i+j].said.spi, /* in network order */ 0, 0, 0, 0, 0))) { fprintf(stderr, "%s: Trouble building sa extension, error=%d.\n", progname, error); pfkey_extensions_free(extensions); exit(1); } #if 0 if(!j) { anyaddr(said_af_array[i].af, &pfkey_address_s_ska); /* Is the address family correct ?? */ if((error = pfkey_address_build(&extensions[K_SADB_EXT_ADDRESS_SRC], K_SADB_EXT_ADDRESS_SRC, 0, 0, sockaddrof(&pfkey_address_s_ska)))) { addrtot(&pfkey_address_s_ska, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stderr, "%s: Trouble building address_s extension (%s), error=%d.\n", progname, ipaddr_txt, error); pfkey_extensions_free(extensions); exit(1); } } #endif if((error = pfkey_address_build(&extensions[!j ? SADB_EXT_ADDRESS_DST : SADB_X_EXT_ADDRESS_DST2], !j ? SADB_EXT_ADDRESS_DST : SADB_X_EXT_ADDRESS_DST2, 0, 0, sockaddrof(&said_af_array[i+j].said.dst)))) { addrtot(&said_af_array[i+j].said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stderr, "%s: Trouble building address_d extension (%s), error=%d.\n", progname, ipaddr_txt, error); pfkey_extensions_free(extensions); exit(1); } } if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) { fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n", progname, error); pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); exit(1); } if((error = write(pfkey_sock, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) != (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) { fprintf(stderr, "%s: pfkey write failed, returning %d with errno=%d.\n", progname, error, errno); pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); pfkey_write_error(error, errno); } if(pfkey_msg) { pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); } } (void) close(pfkey_sock); /* close the socket */ exit(0); }
int main(int argc, char **argv) { #if 0 NSS_NoDB_Init("."); if (!test_aes_cbc(&algo_aes_cbc)) { printf("aes-cbc failed\n"); } if (!test_camellia_cbc(&algo_camellia_cbc)) { printf("camellia-cbc failed\n"); } if (!test_aes_ctr(&algo_aes_ctr)) { printf("aes-ctr failed\n"); } exit(0); #endif int lockfd; /* * We read the intentions for how to log from command line options * and the config file. Then we prepare to be able to log, but until * then log to stderr (better then nothing). Once we are ready to * actually do loggin according to the methods desired, we set the * variables for those methods */ bool log_to_stderr_desired = FALSE; bool log_to_file_desired = FALSE; { int i; /* MUST BE BEFORE ANY allocs */ for (i = 1; i < argc; ++i) { if (streq(argv[i], "--leak-detective")) leak_detective = TRUE; } } pluto_name = argv[0]; coredir = clone_str("/var/run/pluto", "coredir in main()"); pluto_vendorid = clone_str(ipsec_version_vendorid(), "vendorid in main()"); unsigned int keep_alive = 0; /* Overridden by virtual_private= in ipsec.conf */ char *virtual_private = NULL; libreswan_passert_fail = passert_fail; /* handle arguments */ for (;; ) { /* * Note: we don't like the way short options get parsed * by getopt_long, so we simply pass an empty string as * the list. It could be "hvdenp:l:s:" "NARXPECK". */ int longindex = -1; int c = getopt_long(argc, argv, "", long_opts, &longindex); const char *optname = NULL; err_t ugh = NULL; /* complaint from case */ unsigned long u = 0; /* scratch for case */ if (longindex != -1) { const char *optmeta; optname = long_opts[longindex].name; optmeta = optname + strlen(optname) + 1; /* after '\0' */ switch (optmeta[0]) { case '_': libreswan_log("warning: option \"--%s\" with '_' in its name is obsolete; use '-'", optname); break; case '>': libreswan_log("warning: option \"--%s\" is obsolete; use \"--%s\"", optname, optmeta + 1); break; case '!': libreswan_log("warning: option \"--%s\" is obsolete; ignored", optname); continue; /* ignore it! */ } } /* Note: "breaking" from case terminates loop */ switch (c) { case EOF: /* end of flags */ break; case 0: /* * Long option already handled by getopt_long. * Not currently used since we always set flag to NULL. */ continue; case ':': /* diagnostic already printed by getopt_long */ case '?': /* diagnostic already printed by getopt_long */ invocation_fail(NULL); break; case 'h': /* --help */ usage(); break; /* not actually reached */ case 'X': /* --leak-detective */ /* * This flag was already processed at the start of main() * because leak_detective must be immutable from before * the first alloc(). * If this option is specified, we must have already * set it at the start of main(), so assert it. */ passert(leak_detective); continue; case 'C': /* --coredir */ pfree(coredir); coredir = clone_str(optarg, "coredir via getopt"); continue; case 'V': /* --vendorid */ pfree(pluto_vendorid); coredir = clone_str(optarg, "pluto_vendorid via getopt"); continue; case 'S': /* --statsdir */ pfreeany(pluto_stats_binary); pluto_stats_binary = clone_str(optarg, "statsbin"); continue; case 'v': /* --version */ printf("%s%s\n", ipsec_version_string(), compile_time_interop_options); /* not exit_pluto because we are not initialized yet */ exit(0); break; /* not actually reached */ case 'j': /* --nhelpers */ if (streq(optarg, "-1")) { nhelpers = -1; } else { ugh = ttoulb(optarg, 0, 10, 1000, &u); if (ugh != NULL) break; nhelpers = u; } continue; case 'c': /* --seedbits */ pluto_nss_seedbits = atoi(optarg); if (pluto_nss_seedbits == 0) { printf("pluto: seedbits must be an integer > 0"); /* not exit_pluto because we are not initialized yet */ exit(PLUTO_EXIT_NSS_FAIL); } continue; #ifdef HAVE_LABELED_IPSEC case 'w': /* --secctx-attr-type */ ugh = ttoulb(optarg, 0, 0, 0xFFFF, &u); if (ugh != NULL) break; if (u != SECCTX && u != ECN_TUNNEL_or_old_SECCTX) { ugh = "must be a positive 32001 (default) or 10 (for backward compatibility)"; break; } secctx_attr_type = u; continue; #endif case 'd': /* --nofork*/ fork_desired = FALSE; continue; case 'e': /* --stderrlog */ log_to_stderr_desired = TRUE; continue; case 'g': /* --logfile */ pluto_log_file = optarg; log_to_file_desired = TRUE; continue; case 't': /* --log-no-time */ log_with_timestamp = FALSE; continue; case '7': /* --log-no-append */ log_append = FALSE; continue; case '8': /* --drop-oppo-null */ pluto_drop_oppo_null = TRUE; continue; case '9': /* --expire-bare-shunt <interval> */ ugh = ttoulb(optarg, 0, 10, 1000, &u); if (ugh != NULL) break; bare_shunt_interval = u; continue; case 'k': /* --use-klips */ kern_interface = USE_KLIPS; continue; case 'L': /* --listen ip_addr */ { ip_address lip; err_t e = ttoaddr(optarg, 0, AF_UNSPEC, &lip); if (e != NULL) { /* *??? should we continue on failure? * If not, use ugh mechanism. */ libreswan_log( "invalid listen argument ignored: %s\n", e); } else { pluto_listen = clone_str(optarg, "pluto_listen"); libreswan_log( "bind() will be filtered for %s\n", pluto_listen); } } continue; case 'M': /* --use-mast */ kern_interface = USE_MASTKLIPS; continue; case 'F': /* --use-bsdkame */ kern_interface = USE_BSDKAME; continue; case 'K': /* --use-netkey */ kern_interface = USE_NETKEY; continue; case 'n': /* --use-nostack */ kern_interface = NO_KERNEL; continue; case 'D': /* --force-busy */ pluto_ddos_mode = DDOS_FORCE_BUSY; continue; case 'U': /* --force-unlimited */ pluto_ddos_mode = DDOS_FORCE_UNLIMITED; continue; case 'Z': /* --curl-iface */ curl_iface = optarg; continue; case 'I': /* --curl-timeout */ ugh = ttoulb(optarg, 0, 10, 0xFFFF, &u); if (ugh != NULL) break; if (u <= 0) { ugh = "must not be < 1"; break; } curl_timeout = u; continue; case 'r': /* --strictcrlpolicy */ strict_crl_policy = TRUE; continue; case 'o': strict_ocsp_policy = TRUE; continue; case 'O': ocsp_enable = TRUE; continue; case 'Y': ocsp_default_uri = optarg; continue; case 'J': ocsp_trust_name = optarg; continue; case 'T': /* --ocsp_timeout <seconds> */ ugh = ttoulb(optarg, 0, 10, 0xFFFF, &u); if (ugh != NULL) break; if (u == 0) { ugh = "must not be 0"; break; } ocsp_timeout = u; continue; case 'x': /* --crlcheckinterval <seconds> */ ugh = ttoulb(optarg, 0, 10, TIME_T_MAX, &u); if (ugh != NULL) break; crl_check_interval = deltatime(u); continue; case 'u': /* --uniqueids */ uniqueIDs = TRUE; continue; case 'i': /* --interface <ifname|ifaddr> */ if (!use_interface(optarg)) { ugh = "too many --interface specifications"; break; } continue; /* * This option does not really work, as this is the "left" * site only, you also need --to --ikeport again later on * It will result in: yourport -> 500, still not bypassing * filters */ case 'p': /* --ikeport <portnumber> */ ugh = ttoulb(optarg, 0, 10, 0xFFFF, &u); if (ugh != NULL) break; if (u == 0) { ugh = "must not be 0"; break; } pluto_port = u; continue; case 'q': /* --natikeport <portnumber> */ ugh = ttoulb(optarg, 0, 10, 0xFFFF, &u); if (ugh != NULL) break; if (u == 0) { ugh = "must not be 0"; break; } pluto_nat_port = u; continue; case 'b': /* --ctlbase <path> */ /* * ??? work to be done here: * * snprintf returns the required space if there * isn't enough, not -1. * -1 indicates another kind of error. * * This appears to be the only place where the * ctlbase value is used yet it is set elsewhere. * (This isn't clear -- it may be OK.) */ ctlbase = optarg; if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path), "%s%s", ctlbase, CTL_SUFFIX) == -1) { ugh = "<path>" CTL_SUFFIX " too long for sun_path"; break; } if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path), "%s%s", ctlbase, INFO_SUFFIX) == -1) { ugh = "<path>" INFO_SUFFIX " too long for sun_path"; break; } if (snprintf(pluto_lock, sizeof(pluto_lock), "%s%s", ctlbase, LOCK_SUFFIX) == -1) { ugh = "<path>" LOCK_SUFFIX " must fit"; break; } continue; case 's': /* --secretsfile <secrets-file> */ lsw_conf_secretsfile(optarg); continue; case 'f': /* --ipsecdir <ipsec-dir> */ lsw_init_ipsecdir(optarg); continue; case 'N': /* --debug-none */ base_debugging = DBG_NONE; continue; case 'A': /* --debug-all */ base_debugging = DBG_ALL; continue; case 'P': /* --perpeerlogbase */ base_perpeer_logdir = optarg; continue; case 'l': /* --perpeerlog */ log_to_perpeer = TRUE; continue; case '2': /* --keep-alive <delay_secs> */ ugh = ttoulb(optarg, 0, 10, secs_per_day, &u); if (ugh != NULL) break; keep_alive = u; continue; case '5': /* --debug-nat-t */ base_debugging |= DBG_NATT; continue; case '6': /* --virtual-private */ virtual_private = optarg; continue; case 'z': /* --config */ { /* * Config struct to variables mapper. This will * overwrite all previously set options. Keep this * in the same order as long_opts[] is. */ struct starter_config *cfg = read_cfg_file(optarg); /* leak */ set_cfg_string(&pluto_log_file, cfg->setup.strings[KSF_PLUTOSTDERRLOG]); if (pluto_log_file != NULL) log_to_syslog = FALSE; /* plutofork= no longer supported via config file */ log_with_timestamp = cfg->setup.options[KBF_PLUTOSTDERRLOGTIME]; log_append = cfg->setup.options[KBF_PLUTOSTDERRLOGAPPEND]; pluto_drop_oppo_null = cfg->setup.options[KBF_DROP_OPPO_NULL]; pluto_ddos_mode = cfg->setup.options[KBF_DDOS_MODE]; if (cfg->setup.options[KBF_FORCEBUSY]) { /* force-busy is obsoleted, translate to ddos-mode= */ pluto_ddos_mode = cfg->setup.options[KBF_DDOS_MODE] = DDOS_FORCE_BUSY; } /* ddos-ike-threshold and max-halfopen-ike */ pluto_ddos_threshold = cfg->setup.options[KBF_DDOS_IKE_THRESHOLD]; pluto_max_halfopen = cfg->setup.options[KBF_MAX_HALFOPEN_IKE]; strict_crl_policy = cfg->setup.options[KBF_STRICTCRLPOLICY]; pluto_shunt_lifetime = deltatime(cfg->setup.options[KBF_SHUNTLIFETIME]); strict_ocsp_policy = cfg->setup.options[KBF_STRICTOCSPPOLICY]; ocsp_enable = cfg->setup.options[KBF_OCSPENABLE]; set_cfg_string(&ocsp_default_uri, cfg->setup.strings[KSF_OCSPURI]); ocsp_timeout = cfg->setup.options[KBF_OCSPTIMEOUT]; set_cfg_string(&ocsp_trust_name, cfg->setup.strings[KSF_OCSPTRUSTNAME]); crl_check_interval = deltatime( cfg->setup.options[KBF_CRLCHECKINTERVAL]); uniqueIDs = cfg->setup.options[KBF_UNIQUEIDS]; /* * We don't check interfaces= here because that part * has been dealt with in _stackmanager before we * started */ set_cfg_string(&pluto_listen, cfg->setup.strings[KSF_LISTEN]); /* --ikeport */ pluto_port = cfg->setup.options[KBF_IKEPORT]; /* --nflog-all */ /* only causes nflog nmber to show in ipsec status */ pluto_nflog_group = cfg->setup.options[KBF_NFLOG_ALL]; /* only causes nflog nmber to show in ipsec status */ pluto_xfrmlifetime = cfg->setup.options[KBF_XFRMLIFETIME]; /* no config option: ctlbase */ /* --secrets */ if (cfg->setup.strings[KSF_SECRETSFILE] && *cfg->setup.strings[KSF_SECRETSFILE]) { lsw_conf_secretsfile(cfg->setup.strings[KSF_SECRETSFILE]); } if (cfg->setup.strings[KSF_IPSECDIR] != NULL && *cfg->setup.strings[KSF_IPSECDIR] != 0) { /* --ipsecdir */ lsw_init_ipsecdir(cfg->setup.strings[KSF_IPSECDIR]); } /* --perpeerlog */ log_to_perpeer = cfg->setup.options[KBF_PERPEERLOG]; if (log_to_perpeer) { /* --perpeerlogbase */ if (cfg->setup.strings[KSF_PERPEERDIR]) { set_cfg_string(&base_perpeer_logdir, cfg->setup.strings[KSF_PERPEERDIR]); } else { base_perpeer_logdir = clone_str("/var/log/pluto/", "perpeer_logdir"); } } if (cfg->setup.strings[KSF_CURLIFACE]) { pfreeany(curl_iface); /* curl-iface= */ curl_iface = clone_str(cfg->setup.strings[KSF_CURLIFACE], "curl-iface= via --config"); } if (cfg->setup.options[KBF_CURLTIMEOUT]) curl_timeout = cfg->setup.options[KBF_CURLTIMEOUT]; if (cfg->setup.strings[KSF_DUMPDIR]) { pfree(coredir); /* dumpdir= */ coredir = clone_str(cfg->setup.strings[KSF_DUMPDIR], "coredir via --config"); } /* --vendorid */ if (cfg->setup.strings[KSF_MYVENDORID]) { pfree(pluto_vendorid); pluto_vendorid = clone_str(cfg->setup.strings[KSF_MYVENDORID], "pluto_vendorid via --config"); } /* no config option: pluto_adns_option */ if (cfg->setup.strings[KSF_STATSBINARY] != NULL) { if (access(cfg->setup.strings[KSF_STATSBINARY], X_OK) == 0) { pfreeany(pluto_stats_binary); /* statsbin= */ pluto_stats_binary = clone_str(cfg->setup.strings[KSF_STATSBINARY], "statsbin via --config"); libreswan_log("statsbinary set to %s", pluto_stats_binary); } else { libreswan_log("statsbinary= '%s' ignored - file does not exist or is not executable", pluto_stats_binary); } } pluto_nss_seedbits = cfg->setup.options[KBF_SEEDBITS]; pluto_nat_port = cfg->setup.options[KBF_NATIKEPORT]; keep_alive = cfg->setup.options[KBF_KEEPALIVE]; set_cfg_string(&virtual_private, cfg->setup.strings[KSF_VIRTUALPRIVATE]); nhelpers = cfg->setup.options[KBF_NHELPERS]; #ifdef HAVE_LABELED_IPSEC secctx_attr_type = cfg->setup.options[KBF_SECCTX]; #endif base_debugging = cfg->setup.options[KBF_PLUTODEBUG]; char *protostack = cfg->setup.strings[KSF_PROTOSTACK]; if (protostack == NULL || *protostack == '\0') { kern_interface = USE_NETKEY; } else if (streq(protostack, "none")) { kern_interface = NO_KERNEL; } else if (streq(protostack, "auto")) { libreswan_log( "The option protostack=auto is obsoleted, falling back to protostack=netkey\n"); kern_interface = USE_NETKEY; } else if (streq(protostack, "klips")) { kern_interface = USE_KLIPS; } else if (streq(protostack, "mast")) { kern_interface = USE_MASTKLIPS; } else if (streq(protostack, "netkey") || streq(protostack, "native")) { kern_interface = USE_NETKEY; } else if (streq(protostack, "bsd") || streq(protostack, "kame") || streq(protostack, "bsdkame")) { kern_interface = USE_BSDKAME; } else if (streq(protostack, "win2k")) { kern_interface = USE_WIN2K; } confread_free(cfg); continue; } default: if (DBG_OFFSET <= c && c < DBG_OFFSET + IMPAIR_roof_IX) { base_debugging |= LELEM(c - DBG_OFFSET); continue; } bad_case(c); } /* if ugh is set, bail with diagnostic */ if (ugh != NULL) { char mess[200]; if (longindex == -1) { snprintf(mess, sizeof(mess), "unknown option: %s", ugh); } else if (optarg == NULL) { snprintf(mess, sizeof(mess), "--%s option: %s", optname, ugh); } else { snprintf(mess, sizeof(mess), "--%s \"%s\" option: %s", optname, optarg, ugh); } invocation_fail(mess); } break; } if (optind != argc) invocation_fail("unexpected argument"); reset_debugging(); if (chdir(coredir) == -1) { int e = errno; libreswan_log("pluto: warning: chdir(\"%s\") to dumpdir failed (%d: %s)", coredir, e, strerror(e)); } oco = lsw_init_options(); lockfd = create_lock(); /* select between logging methods */ if (log_to_stderr_desired || log_to_file_desired) log_to_syslog = FALSE; if (!log_to_stderr_desired) log_to_stderr = FALSE; #if 0 if (kernel_ops->set_debug != NULL) (*kernel_ops->set_debug)(cur_debugging, DBG_log, DBG_log); #endif /* * create control socket. * We must create it before the parent process returns so that * there will be no race condition in using it. The easiest * place to do this is before the daemon fork. */ { err_t ugh = init_ctl_socket(); if (ugh != NULL) { fprintf(stderr, "pluto: FATAL: %s", ugh); exit_pluto(PLUTO_EXIT_SOCKET_FAIL); } } /* If not suppressed, do daemon fork */ if (fork_desired) { #if USE_DAEMON if (daemon(TRUE, TRUE) < 0) { fprintf(stderr, "pluto: FATAL: daemon failed (%d %s)\n", errno, strerror(errno)); exit_pluto(PLUTO_EXIT_FORK_FAIL); } /* * Parent just exits, so need to fill in our own PID * file. This is racy, since the file won't be * created until after the parent has exited. * * Since "ipsec start" invokes pluto with --nofork, it * is probably safer to leave this feature disabled * then implement it using the daemon call. */ (void) fill_lock(lockfd, getpid()); #elif USE_FORK { pid_t pid = fork(); if (pid < 0) { int e = errno; fprintf(stderr, "pluto: FATAL: fork failed (%d %s)\n", errno, strerror(e)); exit_pluto(PLUTO_EXIT_FORK_FAIL); } if (pid != 0) { /* * parent: die, after filling PID into lock * file. * must not use exit_pluto: lock would be * removed! */ exit(fill_lock(lockfd, pid) ? 0 : 1); } } #else fprintf(stderr, "pluto: FATAL: fork/daemon not supported\n"); exit_pluto(PLUTO_EXIT_FORK_FAIL); #endif if (setsid() < 0) { int e = errno; fprintf(stderr, "FATAL: setsid() failed in main(). Errno %d: %s\n", errno, strerror(e)); exit_pluto(PLUTO_EXIT_FAIL); } } else { /* no daemon fork: we have to fill in lock file */ (void) fill_lock(lockfd, getpid()); if (isatty(fileno(stdout))) { fprintf(stdout, "Pluto initialized\n"); fflush(stdout); } } /* * Close everything but ctl_fd and (if needed) stderr. * There is some danger that a library that we don't know * about is using some fd that we don't know about. * I guess we'll soon find out. */ { int i; for (i = getdtablesize() - 1; i >= 0; i--) /* Bad hack */ if ((!log_to_stderr || i != 2) && i != ctl_fd) close(i); /* make sure that stdin, stdout, stderr are reserved */ if (open("/dev/null", O_RDONLY) != 0) lsw_abort(); if (dup2(0, 1) != 1) lsw_abort(); if (!log_to_stderr && dup2(0, 2) != 2) lsw_abort(); } init_constants(); init_pluto_constants(); pluto_init_log(); if (!pluto_init_nss(oco->nssdb)) { loglog(RC_LOG_SERIOUS, "FATAL: NSS initialization failure"); exit_pluto(PLUTO_EXIT_NSS_FAIL); } libreswan_log("NSS crypto library initialized"); if (ocsp_enable) { if (!init_nss_ocsp(ocsp_default_uri, ocsp_trust_name, ocsp_timeout, strict_ocsp_policy)) { loglog(RC_LOG_SERIOUS, "Initializing NSS OCSP failed"); exit_pluto(PLUTO_EXIT_NSS_FAIL); } else { libreswan_log("NSS OCSP Enabled"); } } #ifdef HAVE_LIBCAP_NG /* * Drop capabilities - this generates a false positive valgrind warning * See: http://marc.info/?l=linux-security-module&m=125895232029657 * * We drop these after creating the pluto socket or else we can't * create a socket if the parent dir is non-root (eg openstack) */ capng_clear(CAPNG_SELECT_BOTH); capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_NET_BIND_SERVICE, CAP_NET_ADMIN, CAP_NET_RAW, CAP_IPC_LOCK, CAP_AUDIT_WRITE, /* for google authenticator pam */ CAP_SETGID, CAP_SETUID, CAP_DAC_READ_SEARCH, -1); /* * We need to retain some capabilities for our children (updown): * CAP_NET_ADMIN to change routes * CAP_NET_RAW for iptables -t mangle * CAP_DAC_READ_SEARCH for pam / google authenticator */ capng_updatev(CAPNG_ADD, CAPNG_BOUNDING_SET, CAP_NET_ADMIN, CAP_NET_RAW, CAP_DAC_READ_SEARCH, -1); capng_apply(CAPNG_SELECT_BOTH); libreswan_log("libcap-ng support [enabled]"); #else libreswan_log("libcap-ng support [disabled]"); #endif #ifdef FIPS_CHECK libreswan_log("FIPS HMAC integrity support [enabled]"); /* * FIPS mode requires two conditions to be true: * - FIPS Kernel mode: fips=1 kernel boot parameter * - FIPS Product mode: See FIPSPRODUCTCHECK in Makefile.inc * (in RHEL/Fedora, dracut-fips installs $FIPSPRODUCTCHECK) * * When FIPS mode, abort on self-check hmac failure. Otherwise, complain */ { if (DBGP(IMPAIR_FORCE_FIPS)) { libreswan_log("Forcing FIPS checks to true to emulate FIPS mode"); lsw_set_fips_mode(LSW_FIPS_ON); } enum lsw_fips_mode pluto_fips_mode = lsw_get_fips_mode(); bool nss_fips_mode = PK11_IsFIPS(); /* * Now verify the consequences. Always run the tests * as combinations such as NSS in fips mode but as out * of it could be bad. */ switch (pluto_fips_mode) { case LSW_FIPS_UNKNOWN: loglog(RC_LOG_SERIOUS, "ABORT: pluto FIPS mode could not be determined"); exit_pluto(PLUTO_EXIT_FIPS_FAIL); break; case LSW_FIPS_ON: libreswan_log("FIPS mode enabled for pluto daemon"); if (nss_fips_mode) { libreswan_log("NSS library is running in FIPS mode"); } else { loglog(RC_LOG_SERIOUS, "ABORT: pluto in FIPS mode but NSS library is not"); exit_pluto(PLUTO_EXIT_FIPS_FAIL); } break; case LSW_FIPS_OFF: libreswan_log("FIPS mode disabled for pluto daemon"); if (nss_fips_mode) { loglog(RC_LOG_SERIOUS, "Warning: NSS library is running in FIPS mode"); } break; case LSW_FIPS_UNSET: default: bad_case(pluto_fips_mode); } /* always run hmac check so we can print diagnostic */ bool fips_files = FIPSCHECK_verify_files(fips_package_files); if (fips_files) { libreswan_log("FIPS HMAC integrity verification self-test passed"); } else { loglog(RC_LOG_SERIOUS, "FIPS HMAC integrity verification self-test FAILED"); } if (pluto_fips_mode == LSW_FIPS_ON && !fips_files) { exit_pluto(PLUTO_EXIT_FIPS_FAIL); } } #else libreswan_log("FIPS HMAC integrity support [disabled]"); #endif #ifdef USE_LINUX_AUDIT linux_audit_init(); #else libreswan_log("Linux audit support [disabled]"); #endif { const char *vc = ipsec_version_code(); libreswan_log("Starting Pluto (Libreswan Version %s%s) pid:%u", vc, compile_time_interop_options, getpid()); } libreswan_log("core dump dir: %s", coredir); if (oco->secretsfile && *oco->secretsfile) libreswan_log("secrets file: %s", oco->secretsfile); libreswan_log(leak_detective ? "leak-detective enabled" : "leak-detective disabled"); /* Check for SAREF support */ #ifdef KLIPS_MAST #include <ipsec_saref.h> { int e, sk, saref; saref = 1; errno = 0; sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_REFINFO, &saref, sizeof(saref)); if (e == -1 ) libreswan_log("SAref support [disabled]: %s", strerror(errno)); else libreswan_log("SAref support [enabled]"); errno = 0; e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_BINDREF, &saref, sizeof(saref)); if (e == -1 ) libreswan_log("SAbind support [disabled]: %s", strerror(errno)); else libreswan_log("SAbind support [enabled]"); close(sk); } #endif libreswan_log("NSS crypto [enabled]"); #ifdef XAUTH_HAVE_PAM libreswan_log("XAUTH PAM support [enabled]"); #else libreswan_log("XAUTH PAM support [disabled]"); #endif /* Log various impair-* functions if they were enabled */ if (DBGP(IMPAIR_BUST_MI2)) libreswan_log("Warning: IMPAIR_BUST_MI2 enabled"); if (DBGP(IMPAIR_BUST_MR2)) libreswan_log("Warning: IMPAIR_BUST_MR2 enabled"); if (DBGP(IMPAIR_SA_CREATION)) libreswan_log("Warning: IMPAIR_SA_CREATION enabled"); if (DBGP(IMPAIR_JACOB_TWO_TWO)) libreswan_log("Warning: IMPAIR_JACOB_TWO_TWO enabled"); if (DBGP(IMPAIR_DIE_ONINFO)) libreswan_log("Warning: IMPAIR_DIE_ONINFO enabled"); if (DBGP(IMPAIR_MAJOR_VERSION_BUMP)) libreswan_log("Warning: IMPAIR_MAJOR_VERSION_BUMP enabled"); if (DBGP(IMPAIR_MINOR_VERSION_BUMP)) libreswan_log("Warning: IMPAIR_MINOR_VERSION_BUMP enabled"); if (DBGP(IMPAIR_RETRANSMITS)) libreswan_log("Warning: IMPAIR_RETRANSMITS enabled"); if (DBGP(IMPAIR_SEND_BOGUS_ISAKMP_FLAG)) libreswan_log("Warning: IMPAIR_SEND_BOGUS_ISAKMP_FLAG enabled"); if (DBGP(IMPAIR_SEND_BOGUS_PAYLOAD_FLAG)) libreswan_log("Warning: IMPAIR_SEND_BOGUS_PAYLOAD_FLAG enabled"); if (DBGP(IMPAIR_SEND_IKEv2_KE)) libreswan_log("Warning: IMPAIR_SEND_IKEv2_KE enabled"); if (DBGP(IMPAIR_SEND_KEY_SIZE_CHECK)) libreswan_log("Warning: IMPAIR_SEND_KEY_SIZE_CHECK enabled"); if (DBGP(IMPAIR_SEND_NO_DELETE)) libreswan_log("Warning: IMPAIR_SEND_NO_DELETE enabled"); if (DBGP(IMPAIR_FORCE_FIPS)) libreswan_log("Warning: IMPAIR_FORCE_FIPS enabled"); if (DBGP(IMPAIR_SEND_NO_IKEV2_AUTH)) libreswan_log("Warning: IMPAIR_SEND_NO_IKEV2_AUTH enabled"); if (DBGP(IMPAIR_SEND_ZERO_GX)) libreswan_log("Warning: IMPAIR_SEND_ZERO_GX enabled"); if (DBGP(IMPAIR_SEND_BOGUS_DCOOKIE)) libreswan_log("Warning: IMPAIR_SEND_BOGUS_DCOOKIE enabled"); /* Initialize all of the various features */ init_nat_traversal(keep_alive); init_virtual_ip(virtual_private); /* obsoleted by nss code init_rnd_pool(); */ init_event_base(); init_secret(); init_states(); init_connections(); init_crypto(); init_crypto_helpers(nhelpers); init_demux(); init_kernel(); init_id(); init_vendorid(); #if defined(LIBCURL) || defined(LDAP_VER) init_fetch(); #endif load_crls(); #ifdef HAVE_LABELED_IPSEC init_avc(); #endif daily_log_event(); #ifdef USE_SYSTEMD_WATCHDOG pluto_sd_init(); #endif call_server(); return -1; /* Shouldn't ever reach this */ }
int main(int argc, char **argv) { int lockfd; int nhelpers = -1; char *coredir; const struct lsw_conf_options *oco; /* * We read the intentions for how to log from command line options * and the config file. Then we prepare to be able to log, but until * then log to stderr (better then nothing). Once we are ready to * actually do loggin according to the methods desired, we set the * variables for those methods */ bool log_to_stderr_desired = FALSE; bool log_to_file_desired = FALSE; coredir = NULL; /* set up initial defaults that need a cast */ pluto_shared_secrets_file = DISCARD_CONST(char *, SHARED_SECRETS_FILE); #ifdef NAT_TRAVERSAL /** Overridden by nat_traversal= in ipsec.conf */ bool nat_traversal = FALSE; bool nat_t_spf = TRUE; /* support port floating */ unsigned int keep_alive = 0; bool force_keepalive = FALSE; #endif /** Overridden by virtual_private= in ipsec.conf */ char *virtual_private = NULL; #ifdef LEAK_DETECTIVE leak_detective=1; #else leak_detective=0; #endif #ifdef HAVE_LIBCAP_NG /* Drop capabilities */ capng_clear(CAPNG_SELECT_BOTH); capng_updatev(CAPNG_ADD, CAPNG_EFFECTIVE|CAPNG_PERMITTED, CAP_NET_BIND_SERVICE, CAP_NET_ADMIN, CAP_NET_RAW, CAP_IPC_LOCK, CAP_AUDIT_WRITE, -1); /* our children must be able to CAP_NET_ADMIN to change routes. */ capng_updatev(CAPNG_ADD, CAPNG_BOUNDING_SET, CAP_NET_ADMIN, -1); capng_apply(CAPNG_SELECT_BOTH); #endif #ifdef DEBUG libreswan_passert_fail = passert_fail; #endif if(getenv("PLUTO_WAIT_FOR_GDB")) { sleep(120); } /* handle arguments */ for (;;) { # define DBG_OFFSET 256 static const struct option long_opts[] = { /* name, has_arg, flag, val */ { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "config", required_argument, NULL, 'z' }, { "nofork", no_argument, NULL, 'd' }, { "stderrlog", no_argument, NULL, 'e' }, { "logfile", required_argument, NULL, 'g' }, { "plutostderrlogtime", no_argument, NULL, 't' }, { "noklips", no_argument, NULL, 'n' }, { "use-nostack", no_argument, NULL, 'n' }, { "use-none", no_argument, NULL, 'n' }, { "force_busy", no_argument, NULL, 'D' }, { "strictcrlpolicy", no_argument, NULL, 'r' }, { "crlcheckinterval", required_argument, NULL, 'x'}, { "uniqueids", no_argument, NULL, 'u' }, { "useklips", no_argument, NULL, 'k' }, { "use-klips", no_argument, NULL, 'k' }, { "use-auto", no_argument, NULL, 'G' }, { "usenetkey", no_argument, NULL, 'K' }, { "use-netkey", no_argument, NULL, 'K' }, { "use-mast", no_argument, NULL, 'M' }, { "use-mastklips", no_argument, NULL, 'M' }, { "use-bsdkame", no_argument, NULL, 'F' }, { "interface", required_argument, NULL, 'i' }, { "listen", required_argument, NULL, 'L' }, { "ikeport", required_argument, NULL, 'p' }, { "natikeport", required_argument, NULL, 'q' }, { "ctlbase", required_argument, NULL, 'b' }, { "secretsfile", required_argument, NULL, 's' }, { "perpeerlogbase", required_argument, NULL, 'P' }, { "perpeerlog", no_argument, NULL, 'l' }, { "noretransmits", no_argument, NULL, 'R' }, { "coredir", required_argument, NULL, 'C' }, { "ipsecdir", required_argument, NULL, 'f' }, { "ipsec_dir", required_argument, NULL, 'f' }, { "foodgroupsdir", required_argument, NULL, 'f' }, { "adns", required_argument, NULL, 'a' }, #ifdef NAT_TRAVERSAL { "nat_traversal", no_argument, NULL, '1' }, { "keep_alive", required_argument, NULL, '2' }, { "force_keepalive", no_argument, NULL, '3' }, { "disable_port_floating", no_argument, NULL, '4' }, { "debug-nat_t", no_argument, NULL, '5' }, { "debug-nattraversal", no_argument, NULL, '5' }, { "debug-nat-t", no_argument, NULL, '5' }, #endif { "virtual_private", required_argument, NULL, '6' }, { "nhelpers", required_argument, NULL, 'j' }, #ifdef HAVE_LABELED_IPSEC { "secctx_attr_value", required_argument, NULL, 'w' }, #endif #ifdef DEBUG { "debug-none", no_argument, NULL, 'N' }, { "debug-all", no_argument, NULL, 'A' }, { "debug-raw", no_argument, NULL, DBG_RAW + DBG_OFFSET }, { "debug-crypt", no_argument, NULL, DBG_CRYPT + DBG_OFFSET }, { "debug-crypto", no_argument, NULL, DBG_CRYPT + DBG_OFFSET }, { "debug-parsing", no_argument, NULL, DBG_PARSING + DBG_OFFSET }, { "debug-emitting", no_argument, NULL, DBG_EMITTING + DBG_OFFSET }, { "debug-control", no_argument, NULL, DBG_CONTROL + DBG_OFFSET }, { "debug-lifecycle", no_argument, NULL, DBG_LIFECYCLE + DBG_OFFSET }, { "debug-klips", no_argument, NULL, DBG_KLIPS + DBG_OFFSET }, { "debug-netkey", no_argument, NULL, DBG_NETKEY + DBG_OFFSET }, { "debug-dns", no_argument, NULL, DBG_DNS + DBG_OFFSET }, { "debug-oppo", no_argument, NULL, DBG_OPPO + DBG_OFFSET }, { "debug-oppoinfo", no_argument, NULL, DBG_OPPOINFO + DBG_OFFSET }, { "debug-controlmore", no_argument, NULL, DBG_CONTROLMORE + DBG_OFFSET }, { "debug-dpd", no_argument, NULL, DBG_DPD + DBG_OFFSET }, { "debug-x509", no_argument, NULL, DBG_X509 + DBG_OFFSET }, { "debug-private", no_argument, NULL, DBG_PRIVATE + DBG_OFFSET }, { "debug-pfkey", no_argument, NULL, DBG_PFKEY + DBG_OFFSET }, { "impair-delay-adns-key-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_KEY_ANSWER + DBG_OFFSET }, { "impair-delay-adns-txt-answer", no_argument, NULL, IMPAIR_DELAY_ADNS_TXT_ANSWER + DBG_OFFSET }, { "impair-bust-mi2", no_argument, NULL, IMPAIR_BUST_MI2 + DBG_OFFSET }, { "impair-bust-mr2", no_argument, NULL, IMPAIR_BUST_MR2 + DBG_OFFSET }, { "impair-sa-creation", no_argument, NULL, IMPAIR_SA_CREATION + DBG_OFFSET }, { "impair-die-oninfo", no_argument, NULL, IMPAIR_DIE_ONINFO + DBG_OFFSET }, { "impair-jacob-two-two", no_argument, NULL, IMPAIR_JACOB_TWO_TWO + DBG_OFFSET }, { "impair-major-version-bump", no_argument, NULL, IMPAIR_MAJOR_VERSION_BUMP + DBG_OFFSET }, { "impair-minor-version-bump", no_argument, NULL, IMPAIR_MINOR_VERSION_BUMP + DBG_OFFSET }, { "impair-retransmits", no_argument, NULL, IMPAIR_RETRANSMITS + DBG_OFFSET }, { "impair-send-bogus-isakmp-flag", no_argument, NULL, IMPAIR_SEND_BOGUS_ISAKMP_FLAG + DBG_OFFSET }, #endif { 0,0,0,0 } }; /* Note: we don't like the way short options get parsed * by getopt_long, so we simply pass an empty string as * the list. It could be "hvdenp:l:s:" "NARXPECK". */ int c = getopt_long(argc, argv, "", long_opts, NULL); /** Note: "breaking" from case terminates loop */ switch (c) { case EOF: /* end of flags */ break; case 0: /* long option already handled */ continue; case ':': /* diagnostic already printed by getopt_long */ case '?': /* diagnostic already printed by getopt_long */ usage(""); break; /* not actually reached */ case 'h': /* --help */ usage(NULL); break; /* not actually reached */ case 'C': coredir = clone_str(optarg, "coredir"); continue; case 'v': /* --version */ { printf("%s%s\n", ipsec_version_string(), compile_time_interop_options); } exit(0); /* not exit_pluto because we are not initialized yet */ break; /* not actually reached */ case 'j': /* --nhelpers */ if (optarg == NULL || !isdigit(optarg[0])) usage("missing number of pluto helpers"); { char *endptr; long count = strtol(optarg, &endptr, 0); if (*endptr != '\0' || endptr == optarg || count < -1) usage("<nhelpers> must be a positive number, 0 or -1"); nhelpers = count; } continue; #ifdef HAVE_LABELED_IPSEC case 'w': /* --secctx_attr_value*/ if (optarg == NULL || !isdigit(optarg[0])) usage("missing (positive integer) value of secctx_attr_value (needed only if using labeled ipsec)"); { char *endptr; long value = strtol(optarg, &endptr, 0); if (*endptr != '\0' || endptr == optarg || (value != SECCTX && value !=10) ) usage("<secctx_attr_value> must be a positive number (32001 by default, 10 for backward compatibility, or any other future number assigned by IANA)"); secctx_attr_value = (u_int16_t)value; } continue; #endif case 'd': /* --nofork*/ fork_desired = FALSE; continue; case 'e': /* --stderrlog */ log_to_stderr_desired = TRUE; continue; case 'g': /* --logfile */ pluto_log_file = optarg; log_to_file_desired = TRUE; continue; case 't': /* --plutostderrlogtime */ log_with_timestamp = TRUE; continue; case 'G': /* --use-auto */ libreswan_log("The option --use-auto is obsoleted, falling back to --use-netkey\n"); kern_interface = USE_NETKEY; continue; case 'k': /* --use-klips */ kern_interface = USE_KLIPS; continue; case 'L': /* --listen ip_addr */ { ip_address lip; err_t e = ttoaddr(optarg,0,0,&lip); if(e) { libreswan_log("invalid listen argument ignored: %s\n",e); } else { pluto_listen = clone_str(optarg, "pluto_listen"); libreswan_log("bind() will be filtered for %s\n",pluto_listen); } } continue; case 'M': /* --use-mast */ kern_interface = USE_MASTKLIPS; continue; case 'F': /* --use-bsdkame */ kern_interface = USE_BSDKAME; continue; case 'K': /* --use-netkey */ kern_interface = USE_NETKEY; continue; case 'n': /* --use-nostack */ kern_interface = NO_KERNEL; continue; case 'D': /* --force_busy */ force_busy = TRUE; continue ; case 'r': /* --strictcrlpolicy */ strict_crl_policy = TRUE; continue ; case 'R': no_retransmits = TRUE; continue; case 'x': /* --crlcheckinterval <time>*/ if (optarg == NULL || !isdigit(optarg[0])) usage("missing interval time"); { char *endptr; long interval = strtol(optarg, &endptr, 0); if (*endptr != '\0' || endptr == optarg || interval <= 0) usage("<interval-time> must be a positive number"); crl_check_interval = interval; } continue ; case 'u': /* --uniqueids */ uniqueIDs = TRUE; continue; case 'i': /* --interface <ifname|ifaddr> */ if (!use_interface(optarg)) usage("too many --interface specifications"); continue; /* * This option does not really work, as this is the "left" * site only, you also need --to --ikeport again later on * It will result in: yourport -> 500, still not bypassing filters */ case 'p': /* --ikeport <portnumber> */ if (optarg == NULL || !isdigit(optarg[0])) usage("missing port number"); { char *endptr; long port = strtol(optarg, &endptr, 0); if (*endptr != '\0' || endptr == optarg || port <= 0 || port > 0x10000) usage("<port-number> must be a number between 1 and 65535"); pluto_port = port; } continue; #ifdef NAT_TRAVERSAL case 'q': /* --natikeport <portnumber> */ if (optarg == NULL || !isdigit(optarg[0])) usage("missing port number"); { char *endptr; long port = strtol(optarg, &endptr, 0); if (*endptr != '\0' || endptr == optarg || port <= 0 || port > 0x10000) usage("<port-number> must be a number between 1 and 65535"); pluto_natt_float_port = port; } continue; #endif case 'b': /* --ctlbase <path> */ ctlbase = optarg; if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path) , "%s%s", ctlbase, CTL_SUFFIX) == -1) usage("<path>" CTL_SUFFIX " too long for sun_path"); if (snprintf(info_addr.sun_path, sizeof(info_addr.sun_path) , "%s%s", ctlbase, INFO_SUFFIX) == -1) usage("<path>" INFO_SUFFIX " too long for sun_path"); if (snprintf(pluto_lock, sizeof(pluto_lock) , "%s%s", ctlbase, LOCK_SUFFIX) == -1) usage("<path>" LOCK_SUFFIX " must fit"); continue; case 's': /* --secretsfile <secrets-file> */ pluto_shared_secrets_file = optarg; continue; case 'f': /* --ipsecdir <ipsec-dir> */ (void)lsw_init_ipsecdir(optarg); continue; case 'a': /* --adns <pathname> */ pluto_adns_option = optarg; continue; #ifdef DEBUG case 'N': /* --debug-none */ base_debugging = DBG_NONE; continue; case 'A': /* --debug-all */ base_debugging = DBG_ALL; continue; #endif case 'P': /* --perpeerlogbase */ base_perpeer_logdir = optarg; continue; case 'l': log_to_perpeer = TRUE; continue; #ifdef NAT_TRAVERSAL case '1': /* --nat_traversal */ nat_traversal = TRUE; continue; case '2': /* --keep_alive */ keep_alive = atoi(optarg); continue; case '3': /* --force_keepalive */ force_keepalive = TRUE; continue; case '4': /* --disable_port_floating */ nat_t_spf = FALSE; continue; #ifdef DEBUG case '5': /* --debug-nat_t */ base_debugging |= DBG_NATT; continue; #endif #endif case '6': /* --virtual_private */ virtual_private = optarg; continue; case 'z': /* --config */ ; /* Config struct to variables mapper. This will overwrite */ /* all previously set options. Keep this in the same order than */ /* long_opts[] is. */ struct starter_config *cfg = read_cfg_file(optarg); set_cfg_string(&pluto_log_file, cfg->setup.strings[KSF_PLUTOSTDERRLOG]); fork_desired = cfg->setup.options[KBF_PLUTOFORK]; /* plutofork= */ log_with_timestamp = cfg->setup.options[KBF_PLUTOSTDERRLOGTIME]; force_busy = cfg->setup.options[KBF_FORCEBUSY]; strict_crl_policy = cfg->setup.options[KBF_STRICTCRLPOLICY]; crl_check_interval = cfg->setup.options[KBF_CRLCHECKINTERVAL]; uniqueIDs = cfg->setup.options[KBF_UNIQUEIDS]; /* * We don't check interfaces= here because that part has been dealt * with in _stackmanager before we started */ set_cfg_string(&pluto_listen, cfg->setup.strings[KSF_LISTEN]); pluto_port = cfg->setup.options[KBF_IKEPORT]; /* --ikeport */ /* no config option: ctlbase */ set_cfg_string(&pluto_shared_secrets_file, cfg->setup.strings[KSF_SECRETSFILE]); /* --secrets */ if(cfg->setup.strings[KSF_IPSECDIR] != NULL && *cfg->setup.strings[KSF_IPSECDIR] != 0) { lsw_init_ipsecdir(cfg->setup.strings[KSF_IPSECDIR]); /* --ipsecdir */ } set_cfg_string(&base_perpeer_logdir, cfg->setup.strings[KSF_PERPEERDIR]); /* --perpeerlogbase */ log_to_perpeer = cfg->setup.options[KBF_PERPEERLOG]; /* --perpeerlog */ no_retransmits = !cfg->setup.options[KBF_RETRANSMITS]; /* --noretransmits */ set_cfg_string(&coredir, cfg->setup.strings[KSF_DUMPDIR]); /* --dumpdir */ /* no config option: pluto_adns_option */ #ifdef NAT_TRAVERSAL pluto_natt_float_port = cfg->setup.options[KBF_NATIKEPORT]; nat_traversal = cfg->setup.options[KBF_NATTRAVERSAL]; keep_alive = cfg->setup.options[KBF_KEEPALIVE]; force_keepalive = cfg->setup.options[KBF_FORCE_KEEPALIVE]; nat_t_spf = !cfg->setup.options[KBF_DISABLEPORTFLOATING]; #endif set_cfg_string(&virtual_private, cfg->setup.strings[KSF_VIRTUALPRIVATE]); nhelpers = cfg->setup.options[KBF_NHELPERS]; #ifdef HAVE_LABELED_IPSEC secctx_attr_value = cfg->setup.options[KBF_SECCTX]; #endif #ifdef DEBUG base_debugging = cfg->setup.options[KBF_PLUTODEBUG]; #endif char *protostack = cfg->setup.strings[KSF_PROTOSTACK]; if (protostack == NULL || *protostack == 0) kern_interface = USE_NETKEY; else if (strcmp(protostack, "none") == 0) kern_interface = NO_KERNEL; else if (strcmp(protostack, "auto") == 0) { libreswan_log("The option protostack=auto is obsoleted, falling back to protostack=netkey\n"); kern_interface = USE_NETKEY; } else if (strcmp(protostack, "klips") == 0) kern_interface = USE_KLIPS; else if (strcmp(protostack, "mast") == 0) kern_interface = USE_MASTKLIPS; else if (strcmp(protostack, "netkey") == 0 || strcmp(protostack, "native") == 0) kern_interface = USE_NETKEY; else if (strcmp(protostack, "bsd") == 0 || strcmp(protostack, "kame") == 0 || strcmp(protostack, "bsdkame") == 0) kern_interface = USE_BSDKAME; else if (strcmp(protostack, "win2k") == 0) kern_interface = USE_WIN2K; confread_free(cfg); continue; default: #ifdef DEBUG if (c >= DBG_OFFSET) { base_debugging |= c - DBG_OFFSET; continue; } # undef DBG_OFFSET #endif bad_case(c); } break; } if (optind != argc) usage("unexpected argument"); reset_debugging(); #ifdef HAVE_NO_FORK fork_desired = FALSE; nhelpers = 0; #endif /* default coredir to location compatible with SElinux */ if(!coredir) { coredir = clone_str("/var/run/pluto", "coredir"); } if(chdir(coredir) == -1) { int e = errno; libreswan_log("pluto: chdir() do dumpdir failed (%d: %s)\n", e, strerror(e)); } oco = lsw_init_options(); lockfd = create_lock(); /* select between logging methods */ if (log_to_stderr_desired || log_to_file_desired) { log_to_syslog = FALSE; } if (!log_to_stderr_desired) log_to_stderr = FALSE; #ifdef DEBUG #if 0 if(kernel_ops->set_debug) { (*kernel_ops->set_debug)(cur_debugging, DBG_log, DBG_log); } #endif #endif /** create control socket. * We must create it before the parent process returns so that * there will be no race condition in using it. The easiest * place to do this is before the daemon fork. */ { err_t ugh = init_ctl_socket(); if (ugh != NULL) { fprintf(stderr, "pluto: %s", ugh); exit_pluto(1); } } /* If not suppressed, do daemon fork */ if (fork_desired) { { pid_t pid = fork(); if (pid < 0) { int e = errno; fprintf(stderr, "pluto: fork failed (%d %s)\n", errno, strerror(e)); exit_pluto(1); } if (pid != 0) { /* parent: die, after filling PID into lock file. * must not use exit_pluto: lock would be removed! */ exit(fill_lock(lockfd, pid)? 0 : 1); } } if (setsid() < 0) { int e = errno; fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n", errno, strerror(e)); exit_pluto(1); } } else { /* no daemon fork: we have to fill in lock file */ (void) fill_lock(lockfd, getpid()); if (isatty(fileno(stdout))) { fprintf(stdout, "Pluto initialized\n"); fflush(stdout); } } /** Close everything but ctl_fd and (if needed) stderr. * There is some danger that a library that we don't know * about is using some fd that we don't know about. * I guess we'll soon find out. */ { int i; for (i = getdtablesize() - 1; i >= 0; i--) /* Bad hack */ if ((!log_to_stderr || i != 2) && i != ctl_fd) close(i); /* make sure that stdin, stdout, stderr are reserved */ if (open("/dev/null", O_RDONLY) != 0) lsw_abort(); if (dup2(0, 1) != 1) lsw_abort(); if (!log_to_stderr && dup2(0, 2) != 2) lsw_abort(); } init_constants(); pluto_init_log(); pluto_init_nss(oco->confddir); #ifdef FIPS_CHECK const char *package_files[]= { IPSECLIBDIR"/setup", IPSECLIBDIR"/addconn", IPSECLIBDIR"/auto", IPSECLIBDIR"/barf", IPSECLIBDIR"/eroute", IPSECLIBDIR"/ikeping", IPSECLIBDIR"/readwriteconf", IPSECLIBDIR"/_keycensor", IPSECLIBDIR"/klipsdebug", IPSECLIBDIR"/look", IPSECLIBDIR"/newhostkey", IPSECLIBDIR"/pf_key", IPSECLIBDIR"/_pluto_adns", IPSECLIBDIR"/_plutorun", IPSECLIBDIR"/ranbits", IPSECLIBDIR"/_realsetup", IPSECLIBDIR"/rsasigkey", IPSECLIBDIR"/pluto", IPSECLIBDIR"/_secretcensor", IPSECLIBDIR"/secrets", IPSECLIBDIR"/showhostkey", IPSECLIBDIR"/spi", IPSECLIBDIR"/spigrp", IPSECLIBDIR"/_stackmanager", IPSECLIBDIR"/tncfg", IPSECLIBDIR"/_updown", IPSECLIBDIR"/_updown.klips", IPSECLIBDIR"/_updown.mast", IPSECLIBDIR"/_updown.netkey", IPSECLIBDIR"/verify", IPSECLIBDIR"/whack", IPSECSBINDIR"/ipsec", NULL }; if (Pluto_IsFIPS() && !FIPSCHECK_verify_files(package_files)) { loglog(RC_LOG_SERIOUS, "FATAL: FIPS integrity verification test failed"); exit_pluto(10); } #else libreswan_log("FIPS integrity support [disabled]"); #endif #ifdef HAVE_LIBCAP_NG libreswan_log("libcap-ng support [enabled]"); #else libreswan_log("libcap-ng support [disabled]"); #endif #ifdef USE_LINUX_AUDIT libreswan_log("Linux audit support [enabled]"); /* test and log if audit is enabled on the system */ int audit_fd, rc; audit_fd = audit_open(); if (audit_fd < 0) { if (errno == EINVAL || errno == EPROTONOSUPPORT || errno == EAFNOSUPPORT) { loglog(RC_LOG_SERIOUS, "Warning: kernel has no audit support"); } else { loglog(RC_LOG_SERIOUS, "FATAL (SOON): audit_open() failed : %s", strerror(errno)); /* temp disabled exit_pluto(10); */ } } rc = audit_log_acct_message(audit_fd, AUDIT_USER_START, NULL, "starting pluto daemon", NULL, -1, NULL, NULL, NULL, 1); close(audit_fd); if (rc < 0) { loglog(RC_LOG_SERIOUS, "FATAL: audit_log_acct_message failed: %s", strerror(errno)); exit_pluto(10); } #else libreswan_log("Linux audit support [disabled]"); #endif /* Note: some scripts may look for this exact message -- don't change * ipsec barf was one, but it no longer does. */ { const char *vc = ipsec_version_code(); #ifdef PLUTO_SENDS_VENDORID const char *v = init_pluto_vendorid(); libreswan_log("Starting Pluto (Libreswan Version %s%s; Vendor ID %s) pid:%u" , vc, compile_time_interop_options, v, getpid()); #else libreswan_log("Starting Pluto (Libreswan Version %s%s) pid:%u" , vc, compile_time_interop_options, getpid()); #endif if(Pluto_IsFIPS()) { libreswan_log("Pluto is running in FIPS mode"); } else { libreswan_log("Pluto is NOT running in FIPS mode"); } if((vc[0]=='c' && vc[1]=='v' && vc[2]=='s') || (vc[2]=='g' && vc[3]=='i' && vc[4]=='t')) { /* * when people build RPMs from CVS or GIT, make sure they * get blamed appropriately, and that we get some way to * identify who did it, and when they did it. Use string concat, * so that strings the binary can or classic SCCS "what", will find * stuff too. */ libreswan_log("@(#) built on "__DATE__":" __TIME__ " by " BUILDER); } #if defined(USE_1DES) libreswan_log("WARNING: 1DES is enabled"); #endif } if(coredir) { libreswan_log("core dump dir: %s", coredir); } if(pluto_shared_secrets_file) { libreswan_log("secrets file: %s", pluto_shared_secrets_file); } #ifdef LEAK_DETECTIVE libreswan_log("LEAK_DETECTIVE support [enabled]"); #else libreswan_log("LEAK_DETECTIVE support [disabled]"); #endif #ifdef HAVE_OCF { struct stat buf; errno=0; if( stat("/dev/crypto",&buf) != -1) libreswan_log("OCF support for IKE via /dev/crypto [enabled]"); else libreswan_log("OCF support for IKE via /dev/crypto [failed:%s]", strerror(errno)); } #else libreswan_log("OCF support for IKE [disabled]"); #endif /* Check for SAREF support */ #ifdef KLIPS_MAST #include <ipsec_saref.h> { int e, sk, saref; saref = 1; errno=0; sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_REFINFO, &saref, sizeof(saref)); if (e == -1 ) { libreswan_log("SAref support [disabled]: %s" , strerror(errno)); } else { libreswan_log("SAref support [enabled]"); } errno=0; e = setsockopt(sk, IPPROTO_IP, IP_IPSEC_BINDREF, &saref, sizeof(saref)); if (e == -1 ) { libreswan_log("SAbind support [disabled]: %s" , strerror(errno)); } else { libreswan_log("SAbind support [enabled]"); } close(sk); } #endif libreswan_log("NSS crypto [enabled]"); #ifdef XAUTH_HAVE_PAM libreswan_log("XAUTH PAM support [enabled]"); #else libreswan_log("XAUTH PAM support [disabled]"); #endif #ifdef HAVE_STATSD libreswan_log("HAVE_STATSD notification via /bin/libreswan-statsd enabled"); #else libreswan_log("HAVE_STATSD notification support [disabled]"); #endif /** Log various impair-* functions if they were enabled */ if(DBGP(IMPAIR_BUST_MI2)) libreswan_log("Warning: IMPAIR_BUST_MI2 enabled"); if(DBGP(IMPAIR_BUST_MR2)) libreswan_log("Warning: IMPAIR_BUST_MR2 enabled"); if(DBGP(IMPAIR_SA_CREATION)) libreswan_log("Warning: IMPAIR_SA_CREATION enabled"); if(DBGP(IMPAIR_JACOB_TWO_TWO)) libreswan_log("Warning: IMPAIR_JACOB_TWO_TWO enabled"); if(DBGP(IMPAIR_DIE_ONINFO)) libreswan_log("Warning: IMPAIR_DIE_ONINFO enabled"); if(DBGP(IMPAIR_MAJOR_VERSION_BUMP)) libreswan_log("Warning: IMPAIR_MAJOR_VERSION_BUMP enabled"); if(DBGP(IMPAIR_MINOR_VERSION_BUMP)) libreswan_log("Warning: IMPAIR_MINOR_VERSION_BUMP enabled"); if(DBGP(IMPAIR_RETRANSMITS)) libreswan_log("Warning: IMPAIR_RETRANSMITS enabled"); if(DBGP(IMPAIR_SEND_BOGUS_ISAKMP_FLAG)) libreswan_log("Warning: IMPAIR_SEND_BOGUS_ISAKMP_FLAG enabled"); if(DBGP(IMPAIR_DELAY_ADNS_KEY_ANSWER)) libreswan_log("Warning: IMPAIR_DELAY_ADNS_KEY_ANSWER enabled"); if(DBGP(IMPAIR_DELAY_ADNS_TXT_ANSWER)) libreswan_log("Warning: IMPAIR_DELAY_ADNS_TXT_ANSWER enabled"); /** Initialize all of the various features */ #ifdef NAT_TRAVERSAL init_nat_traversal(nat_traversal, keep_alive, force_keepalive, nat_t_spf); #endif init_virtual_ip(virtual_private); /* obsoletd by nss code init_rnd_pool(); */ init_timer(); init_secret(); init_states(); init_connections(); init_crypto(); init_crypto_helpers(nhelpers); load_lswcrypto(); init_demux(); init_kernel(); init_adns(); init_id(); #ifdef TPM init_tpm(); #endif #if defined(LIBCURL) || defined(LDAP_VER) init_fetch(); #endif /* loading X.509 CA certificates */ load_authcerts("CA cert", oco->cacerts_dir, AUTH_CA); #if 0 /* unused */ /* loading X.509 AA certificates */ load_authcerts("AA cert", oco->aacerts_dir, AUTH_AA); #endif /* loading X.509 CRLs */ load_crls(); /* loading attribute certificates (experimental) */ load_acerts(); /*Loading CA certs from NSS DB*/ load_authcerts_from_nss("CA cert", AUTH_CA); #ifdef HAVE_LABELED_IPSEC init_avc(); #endif daily_log_event(); call_server(); return -1; /* Shouldn't ever reach this */ }
int main(int argc, char **argv) { bool fork_desired = TRUE; bool log_to_stderr_desired = FALSE; int lockfd; #ifdef NAT_TRAVERSAL bool nat_traversal = FALSE; unsigned int keep_alive = 0; #endif #ifdef VIRTUAL_IP char *virtual_private = NULL; #endif char *ipsec0 = NULL; char *ipsec1 = NULL; char *ipsec2 = NULL; char *ipsec3 = NULL; /* handle arguments */ for (;;) { static const struct option long_opts[] = { /* name, has_arg, flag, val */ { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'v' }, { "optionsfrom", required_argument, NULL, '+' }, { "nofork", no_argument, NULL, 'd' }, { "stderrlog", no_argument, NULL, 'e' }, { "noklips", no_argument, NULL, 'n' }, { "nocrsend", no_argument, NULL, 'c' }, { "uniqueids", no_argument, NULL, 'u' }, { "interface", required_argument, NULL, 'i' }, { "ikeport", required_argument, NULL, 'p' }, { "ctlbase", required_argument, NULL, 'b' }, { "secretsfile", required_argument, NULL, 's' }, { "adns", required_argument, NULL, 'a' }, #ifdef DEBUG { "debug-none", no_argument, NULL, 'N' }, { "debug-all]", no_argument, NULL, 'A' }, { "debug-raw", no_argument, NULL, 'R' }, { "debug-crypt", no_argument, NULL, 'X' }, { "debug-parsing", no_argument, NULL, 'P' }, { "debug-emitting", no_argument, NULL, 'E' }, { "debug-control", no_argument, NULL, 'C' }, { "debug-lifecycle", no_argument, NULL, 'L' }, { "debug-klips", no_argument, NULL, 'K' }, { "debug-dns", no_argument, NULL, 'D' }, { "debug-private", no_argument, NULL, 'Z' }, #endif #ifdef NAT_TRAVERSAL { "nat_traversal", no_argument, NULL, '1' }, { "keep_alive", required_argument, NULL, '2' }, #endif #ifdef VIRTUAL_IP { "virtual_private", required_argument, NULL, '3' }, #endif { "ipsec0", required_argument, NULL, '4' }, { "ipsec1", required_argument, NULL, '5' }, { "ipsec2", required_argument, NULL, '6' }, { "ipsec3", required_argument, NULL, '7' }, { 0,0,0,0 } }; /* Note: we don't like the way short options get parsed * by getopt_long, so we simply pass an empty string as * the list. It could be "hvdenp:l:s:" "NARXPECK". */ int c = getopt_long(argc, argv, "", long_opts, NULL); /* Note: "breaking" from case terminates loop */ switch (c) { case EOF: /* end of flags */ break; case 0: /* long option already handled */ continue; case ':': /* diagnostic already printed by getopt_long */ case '?': /* diagnostic already printed by getopt_long */ usage(""); break; /* not actually reached */ case 'h': /* --help */ usage(NULL); break; /* not actually reached */ case 'v': /* --version */ { const char **sp = ipsec_copyright_notice(); printf("%s\n", ipsec_version_string()); for (; *sp != NULL; sp++) puts(*sp); } exit_pluto(0); break; /* not actually reached */ case '+': /* --optionsfrom <filename> */ optionsfrom(optarg, &argc, &argv, optind, stderr); /* does not return on error */ continue; case 'd': /* --nofork*/ fork_desired = FALSE; continue; case 'e': /* --stderrlog */ log_to_stderr_desired = TRUE; continue; case 'n': /* --noklips */ no_klips = TRUE; continue; case 'c': /* --nocrsend */ no_cr_send = TRUE; continue ; case 'u': /* --uniquids */ uniqueIDs = TRUE; continue; case 'i': /* --interface <ifname> */ if (!use_interface(optarg)) usage("too many --interface specifications"); continue; case 'p': /* --port <portnumber> */ if (optarg == NULL || !isdigit(optarg[0])) usage("missing port number"); { char *endptr; long port = strtol(optarg, &endptr, 0); if (*endptr != '\0' || endptr == optarg || port <= 0 || port > 0x10000) usage("<port-number> must be a number between 1 and 65535"); pluto_port = port; } continue; case 'b': /* --ctlbase <path> */ if (snprintf(ctl_addr.sun_path, sizeof(ctl_addr.sun_path) , "%s%s", optarg, CTL_SUFFIX) == -1) usage("<path>" CTL_SUFFIX " too long for sun_path"); if (snprintf(pluto_lock, sizeof(pluto_lock) , "%s%s", optarg, LOCK_SUFFIX) == -1) usage("<path>" LOCK_SUFFIX " must fit"); continue; case 's': /* --secretsfile <secrets-file> */ shared_secrets_file = optarg; continue; case 'a': /* --adns <pathname> */ pluto_adns_option = optarg; continue; #ifdef DEBUG case 'N': /* --debug-none */ base_debugging = DBG_NONE; continue; case 'A': /* --debug-all */ base_debugging = DBG_ALL; continue; case 'R': /* --debug-raw */ base_debugging |= DBG_RAW; continue; case 'X': /* --debug-crypt */ base_debugging |= DBG_CRYPT; continue; case 'P': /* --debug-parsing */ base_debugging |= DBG_PARSING; continue; case 'E': /* --debug-emitting */ base_debugging |= DBG_EMITTING; continue; case 'C': /* --debug-control */ base_debugging |= DBG_CONTROL; continue; case 'L': /* --debug-lifecycle */ base_debugging |= DBG_LIFECYCLE; continue; case 'K': /* --debug-klips */ base_debugging |= DBG_KLIPS; continue; case 'D': /* --debug-dns */ base_debugging |= DBG_DNS; continue; case 'Z': /* --debug-private */ base_debugging |= DBG_PRIVATE; continue; #endif #ifdef NAT_TRAVERSAL case '1': /* --nat_traversal */ nat_traversal = TRUE; continue; case '2': /* --keep_alive */ keep_alive = atoi(optarg); continue; #endif #ifdef VIRTUAL_IP case '3': /* --virtual_private */ virtual_private = optarg; continue; #endif case '4': /* --ipsec0 */ ipsec0 = optarg; continue; case '5': /* --ipsec1 */ ipsec1 = optarg; continue; case '6': /* --ipsec2 */ ipsec2 = optarg; continue; case '7': /* --ipsec3 */ ipsec3 = optarg; continue; default: impossible(); } break; } if (optind != argc) usage("unexpected argument"); reset_debugging(); lockfd = create_lock(); /* select between logging methods */ if (log_to_stderr_desired) log_to_syslog = FALSE; else log_to_stderr = FALSE; /* create control socket. * We must create it before the parent process returns so that * there will be no race condition in using it. The easiest * place to do this is before the daemon fork. */ { err_t ugh = init_ctl_socket(); if (ugh != NULL) { fprintf(stderr, "pluto: %s", ugh); exit_pluto(1); } } /* If not suppressed, do daemon fork */ #ifndef EMBED if (fork_desired) { { pid_t pid = fork(); if (pid < 0) { int e = errno; fprintf(stderr, "pluto: fork failed (%d %s)\n", errno, strerror(e)); exit_pluto(1); } if (pid != 0) { /* parent: die, after filling PID into lock file. * must not use exit_pluto: lock would be removed! */ exit(fill_lock(lockfd, pid)? 0 : 1); } } if (setsid() < 0) { int e = errno; fprintf(stderr, "setsid() failed in main(). Errno %d: %s\n", errno, strerror(e)); exit_pluto(1); } /* Close everything but ctl_fd and (if needed) stderr. */ { int i; for (i = getdtablesize() - 1; i >= 0; i--) /* Bad hack */ if ((!log_to_stderr || i != 2) && i != ctl_fd) close(i); /* make sure that stdin, stdout, stderr are reserved */ if (open("/dev/null", O_RDONLY) != 0) abort(); if (dup2(0, 1) != 1) abort(); if (!log_to_stderr && dup2(0, 2) != 2) abort(); } } else #endif { /* no daemon fork: we have to fill in lock file */ (void) fill_lock(lockfd, getpid()); fprintf(stdout, "Pluto initialized\n"); fflush(stdout); } init_constants(); init_log(); /* Note: some scripts may look for this exact message -- don't change */ log("Starting Pluto (FreeS/WAN Version %s)", ipsec_version_code()); log(" including X.509 patch (Version %s)", x509patch_version); #ifdef NAT_TRAVERSAL init_nat_traversal(nat_traversal,keep_alive); #endif #ifdef VIRTUAL_IP init_virtual_ip(virtual_private); #endif init_interfaces(ipsec0, ipsec1, ipsec2, ipsec3); init_rnd_pool(); init_secret(); init_states(); init_crypto(); init_demux(); init_kernel(); init_adns(); /* loading CA certificates */ load_cacerts(); /* loading CRLs */ load_crls(); /* loading my X.509 or OpenPGP certificate */ load_mycert(); call_server(); return -1; /* Shouldn't ever reach this */ }
/* - main - mostly argument parsing */ int main(int argc, char *argv[]) { int opt; extern int optind; extern char *optarg; int errflg = 0; int i; int nbits; char *oldkeyfile = NULL; while ((opt = getopt_long(argc, argv, "", opts, NULL)) != EOF) switch (opt) { case 'v': /* verbose description */ verbose = 1; break; case 'r': /* nonstandard /dev/random */ device = optarg; break; case 'p': /* number of prime-check rounds */ nrounds = atoi(optarg); if (nrounds <= 0) { fprintf(stderr, "%s: rounds must be > 0\n", me); exit(2); } break; case 'o': /* reformat old key */ oldkeyfile = optarg; break; case 'H': /* set hostname for output */ strcpy(outputhostname, optarg); break; case 'n': /* don't optimize the private key */ do_lcm = 0; break; case 'h': /* help */ printf("Usage:\t%s\n", usage); printf("\tor\n"); printf("\t%s\n", usage2); exit(0); break; case 'V': /* version */ printf("%s %s\n", me, ipsec_version_code()); exit(0); break; case '?': default: errflg = 1; break; } if (errflg || optind != ((oldkeyfile != NULL) ? argc : argc-1)) { printf("Usage:\t%s\n", usage); printf("\tor\n"); printf("\t%s\n", usage2); exit(2); } if (outputhostname[0] == '\0') { i = gethostname(outputhostname, sizeof(outputhostname)); if (i < 0) { fprintf(stderr, "%s: gethostname failed (%s)\n", me, strerror(errno)); exit(1); } } if (oldkeyfile == NULL) { assert(argv[optind] != NULL); nbits = atoi(argv[optind]); } else nbits = getoldkey(oldkeyfile); if (nbits <= 0) { fprintf(stderr, "%s: invalid bit count (%d)\n", me, nbits); exit(1); } else if (nbits > MAXBITS) { fprintf(stderr, "%s: overlarge bit count (max %d)\n", me, MAXBITS); exit(1); } else if (nbits % (CHAR_BIT*2) != 0) { /* *2 for nbits/2-bit primes */ fprintf(stderr, "%s: bit count (%d) not multiple of %d\n", me, nbits, (int)CHAR_BIT*2); exit(1); } rsasigkey(nbits, (oldkeyfile == NULL) ? 0 : 1); exit(0); }
int main(int argc, char **argv) { /* int fd; */ char *endptr; /* int ret; */ int c; const char* error_s; int error = 0; char ipaddr_txt[ADDRTOT_BUF]; struct sadb_ext *extensions[K_SADB_EXT_MAX + 1]; struct sadb_msg *pfkey_msg; ip_address pfkey_address_s_ska; /*struct sockaddr_in pfkey_address_d_ska;*/ ip_address pfkey_address_sflow_ska; ip_address pfkey_address_dflow_ska; ip_address pfkey_address_smask_ska; ip_address pfkey_address_dmask_ska; int transport_proto = 0; int src_port = 0; int dst_port = 0; ip_said said; ip_subnet s_subnet, d_subnet; int eroute_af = 0; int said_af = 0; int sa_flags=0; int argcount = argc; progname = argv[0]; memset(&pfkey_address_s_ska, 0, sizeof(ip_address)); memset(&pfkey_address_sflow_ska, 0, sizeof(ip_address)); memset(&pfkey_address_dflow_ska, 0, sizeof(ip_address)); memset(&pfkey_address_smask_ska, 0, sizeof(ip_address)); memset(&pfkey_address_dmask_ska, 0, sizeof(ip_address)); memset(&said, 0, sizeof(ip_said)); memset(&s_subnet, 0, sizeof(ip_subnet)); memset(&d_subnet, 0, sizeof(ip_subnet)); eroute_af_opt = said_af_opt = edst_opt = spi_opt = proto_opt = said_opt = dst_opt = src_opt = NULL; while((c = getopt_long(argc, argv, ""/*"acdD:e:i:hprs:S:f:vl:+:g"*/, longopts, 0)) != EOF) { switch(c) { case 'g': debug = 1; pfkey_lib_debug = PF_KEY_DEBUG_PARSE_MAX; argcount--; break; case 'a': if(action_type) { fprintf(stderr, "%s: Only one of '--add', '--addin', '--replace', '--replacein', '--clear', or '--del' options permitted.\n", progname); exit(1); } action_type = EMT_SETEROUTE; break; case 'A': if(action_type) { fprintf(stderr, "%s: Only one of '--add', '--addin', '--replace', '--replacein', '--clear', or '--del' options permitted.\n", progname); exit(1); } action_type = EMT_INEROUTE; break; case 'r': if(action_type) { fprintf(stderr, "%s: Only one of '--add', '--addin', '--replace', '--replacein', '--clear', or '--del' options permitted.\n", progname); exit(1); } action_type = EMT_REPLACEROUTE; break; case 'E': if(action_type) { fprintf(stderr, "%s: Only one of '--add', '--addin', '--replace', '--replacein', '--clear', or '--del' options permitted.\n", progname); exit(1); } action_type = EMT_INREPLACEROUTE; break; case 'c': if(action_type) { fprintf(stderr, "%s: Only one of '--add', '--addin', '--replace', '--clear', or '--del' options permitted.\n", progname); exit(1); } action_type = EMT_CLREROUTE; break; case 'd': if(action_type) { fprintf(stderr, "%s: Only one of '--add', '--addin', '--replace', '--clear', or '--del' options permitted.\n", progname); exit(1); } action_type = EMT_DELEROUTE; break; case 'e': if(said_opt) { fprintf(stderr, "%s: Error, EDST parameter redefined:%s, already defined in SA:%s\n", progname, optarg, said_opt); exit (1); } if(edst_opt) { fprintf(stderr, "%s: Error, EDST parameter redefined:%s, already defined as:%s\n", progname, optarg, edst_opt); exit (1); } error_s = ttoaddr(optarg, 0, said_af, &said.dst); if(error_s != NULL) { fprintf(stderr, "%s: Error, %s converting --edst argument:%s\n", progname, error_s, optarg); exit (1); } edst_opt = optarg; break; case 'h': case '?': usage(progname); exit(1); case 's': if(said_opt) { fprintf(stderr, "%s: Error, SPI parameter redefined:%s, already defined in SA:%s\n", progname, optarg, said_opt); exit (1); } if(spi_opt) { fprintf(stderr, "%s: Error, SPI parameter redefined:%s, already defined as:%s\n", progname, optarg, spi_opt); exit (1); } said.spi = htonl(strtoul(optarg, &endptr, 0)); if(!(endptr == optarg + strlen(optarg))) { fprintf(stderr, "%s: Invalid character in SPI parameter: %s\n", progname, optarg); exit (1); } if(ntohl(said.spi) < 0x100) { fprintf(stderr, "%s: Illegal reserved spi: %s => 0x%x Must be larger than 0x100.\n", progname, optarg, ntohl(said.spi)); exit(1); } spi_opt = optarg; break; case 'p': if(said_opt) { fprintf(stderr, "%s: Error, PROTO parameter redefined:%s, already defined in SA:%s\n", progname, optarg, said_opt); exit (1); } if(proto_opt) { fprintf(stderr, "%s: Error, PROTO parameter redefined:%s, already defined as:%s\n", progname, optarg, proto_opt); exit (1); } #if 0 if(said.proto) { fprintf(stderr, "%s: Warning, PROTO parameter redefined:%s\n", progname, optarg); exit (1); } #endif if(!strcmp(optarg, "ah")) said.proto = SA_AH; if(!strcmp(optarg, "esp")) said.proto = SA_ESP; if(!strcmp(optarg, "tun")) said.proto = SA_IPIP; if(!strcmp(optarg, "comp")) said.proto = SA_COMP; if(said.proto == 0) { fprintf(stderr, "%s: Invalid PROTO parameter: %s\n", progname, optarg); exit (1); } proto_opt = optarg; break; case 'I': if(said_opt) { fprintf(stderr, "%s: Error, SAID parameter redefined:%s, already defined in SA:%s\n", progname, optarg, said_opt); exit (1); } if(proto_opt) { fprintf(stderr, "%s: Error, PROTO parameter redefined in SA:%s, already defined as:%s\n", progname, optarg, proto_opt); exit (1); } if(edst_opt) { fprintf(stderr, "%s: Error, EDST parameter redefined in SA:%s, already defined as:%s\n", progname, optarg, edst_opt); exit (1); } if(spi_opt) { fprintf(stderr, "%s: Error, SPI parameter redefined in SA:%s, already defined as:%s\n", progname, optarg, spi_opt); exit (1); } if(said_af_opt) { fprintf(stderr, "%s: Error, address family parameter redefined in SA:%s, already defined as:%s\n", progname, optarg, said_af_opt); exit (1); } error_s = ttosa(optarg, 0, &said); if(error_s != NULL) { fprintf(stderr, "%s: Error, %s converting --sa argument:%s\n", progname, error_s, optarg); exit (1); } else if(ntohl(said.spi) < 0x100){ fprintf(stderr, "%s: Illegal reserved spi: %s => 0x%x Must be larger than or equal to 0x100.\n", progname, optarg, said.spi); exit(1); } said_af = addrtypeof(&said.dst); said_opt = optarg; break; case 'v': fprintf(stdout, "%s %s\n", me, ipsec_version_code()); fprintf(stdout, "See `ipsec --copyright' for copyright information.\n"); exit(1); case 'D': if(dst_opt) { fprintf(stderr, "%s: Error, --dst parameter redefined:%s, already defined as:%s\n", progname, optarg, dst_opt); exit (1); } error_s = ttosubnet(optarg, 0, eroute_af, &d_subnet); if (error_s != NULL) { fprintf(stderr, "%s: Error, %s converting --dst argument: %s\n", progname, error_s, optarg); exit (1); } dst_opt = optarg; break; case 'S': if(src_opt) { fprintf(stderr, "%s: Error, --src parameter redefined:%s, already defined as:%s\n", progname, optarg, src_opt); exit (1); } error_s = ttosubnet(optarg, 0, eroute_af, &s_subnet); if (error_s != NULL) { fprintf(stderr, "%s: Error, %s converting --src argument: %s\n", progname, error_s, optarg); exit (1); } src_opt = optarg; break; case 'P': if (transport_proto_opt) { fprintf(stderr, "%s: Error, --transport-proto" " parameter redefined:%s, " "already defined as:%s\n", progname, optarg, transport_proto_opt); exit(1); } transport_proto_opt = optarg; break; case 'Q': if (src_port_opt) { fprintf(stderr, "%s: Error, --src-port" " parameter redefined:%s, " "already defined as:%s\n", progname, optarg, src_port_opt); exit(1); } src_port_opt = optarg; break; case 'R': if (dst_port_opt) { fprintf(stderr, "%s: Error, --dst-port" " parameter redefined:%s, " "already defined as:%s\n", progname, optarg, dst_port_opt); exit(1); } dst_port_opt = optarg; break; case 'l': progname = malloc(strlen(argv[0]) + 10 /* update this when changing the sprintf() */ + strlen(optarg)); sprintf(progname, "%s --label %s", argv[0], optarg); argcount -= 2; break; case 'i': /* specifies the address family of the SAID, stored in said_af */ if(said_af_opt) { fprintf(stderr, "%s: Error, address family of SAID redefined:%s, already defined as:%s\n", progname, optarg, said_af_opt); exit (1); } if(!strcmp(optarg, "inet")) said_af = AF_INET; if(!strcmp(optarg, "inet6")) said_af = AF_INET6; if(said_af == 0) { fprintf(stderr, "%s: Invalid address family parameter for SAID: %s\n", progname, optarg); exit (1); } said_af_opt = optarg; break; case 'f': /* specifies the address family of the eroute, stored in eroute_af */ if(eroute_af_opt) { fprintf(stderr, "%s: Error, address family of eroute redefined:%s, already defined as:%s\n", progname, optarg, eroute_af_opt); exit (1); } if(!strcmp(optarg, "inet")) eroute_af = AF_INET; if(!strcmp(optarg, "inet6")) eroute_af = AF_INET6; if(eroute_af == 0) { fprintf(stderr, "%s: Invalid address family parameter for eroute: %s\n", progname, optarg); exit (1); } eroute_af_opt = optarg; break; case '+': /* optionsfrom */ optionsfrom(optarg, &argc, &argv, optind, stderr); /* no return on error */ break; default: break; } } if(debug) { fprintf(stdout, "%s: DEBUG: argc=%d\n", progname, argc); } if(argcount == 1) { struct stat sts; if ( ((stat ("/proc/net/pfkey", &sts)) == 0) ) { fprintf(stderr, "%s: NETKEY does not support eroute table.\n",progname); exit(1); } else { int ret = 1; if ((stat ("/proc/net/ipsec_eroute", &sts)) != 0) { fprintf(stderr, "%s: No eroute table - no IPsec support in kernel (are the modules loaded?)\n", progname); } else { ret = system("cat /proc/net/ipsec_eroute"); ret = ret != -1 && WIFEXITED(ret) ? WEXITSTATUS(ret) : 1; } exit(ret); } } /* Sanity checks */ if(debug) { fprintf(stdout, "%s: DEBUG: action_type=%d\n", progname, action_type); } if (transport_proto_opt != 0) { struct protoent * proto = getprotobyname(transport_proto_opt); if (proto != 0) { transport_proto = proto->p_proto; } else { transport_proto = strtoul(transport_proto_opt, &endptr, 0); if ((*endptr != '\0') || (transport_proto == 0 && endptr == transport_proto_opt)) { fprintf(stderr, "%s: Invalid character in --transport-proto parameter: %s\n", progname, transport_proto_opt); exit (1); } if (transport_proto > 255) { fprintf(stderr, "%s: --transport-proto parameter: %s must be in the range 0 to 255 inclusive\n", progname, transport_proto_opt); exit (1); } } } if (src_port_opt != 0 || dst_port_opt != 0) { switch (transport_proto) { case IPPROTO_UDP: case IPPROTO_TCP: break; default: fprintf(stderr, "%s: --transport-proto with either UDP or TCP must be specified if --src-port or --dst-port is used\n", progname); exit(1); } } if (src_port_opt) { struct servent * ent = getservbyname(src_port_opt, 0); if (ent != 0) { src_port = ent->s_port; } else { src_port = strtoul(src_port_opt, &endptr, 0); if ((*endptr != '\0') || (src_port == 0 && endptr == src_port_opt)) { fprintf(stderr, "%s: Invalid character in --src-port parameter: %s\n", progname, src_port_opt); exit (1); } if (src_port > 65535) { fprintf(stderr, "%s: --src-port parameter: %s must be in the range 0 to 65535 inclusive\n", progname, src_port_opt); } src_port = htons(src_port); } } if (dst_port_opt) { struct servent * ent = getservbyname(dst_port_opt, 0); if (ent != 0) { dst_port = ent->s_port; } else { dst_port = strtoul(dst_port_opt, &endptr, 0); if ((*endptr != '\0') || (dst_port == 0 && endptr == dst_port_opt)) { fprintf(stderr, "%s: Invalid character in --dst-port parameter: %s\n", progname, dst_port_opt); exit (1); } if (dst_port > 65535) { fprintf(stderr, "%s: --dst-port parameter: %s must be in the range 0 to 65535 inclusive\n", progname, dst_port_opt); } dst_port = htons(dst_port); } } switch(action_type) { case EMT_SETEROUTE: case EMT_REPLACEROUTE: case EMT_INEROUTE: case EMT_INREPLACEROUTE: if(!(said_af_opt && edst_opt && spi_opt && proto_opt) && !(said_opt)) { fprintf(stderr, "%s: add and addin options must have SA specified.\n", progname); exit(1); } case EMT_DELEROUTE: if(!src_opt) { fprintf(stderr, "%s: Error -- %s option '--src' is required.\n", progname, (action_type == EMT_SETEROUTE) ? "add" : "del"); exit(1); } if(!dst_opt) { fprintf(stderr, "%s: Error -- %s option '--dst' is required.\n", progname, (action_type == EMT_SETEROUTE) ? "add" : "del"); exit(1); } case EMT_CLREROUTE: break; default: fprintf(stderr, "%s: exactly one of '--add', '--addin', '--replace', '--del' or '--clear' options must be specified.\n" "Try %s --help' for usage information.\n", progname, progname); exit(1); } pfkey_sock = pfkey_open_sock_with_error(); if(pfkey_sock == -1) { exit(1); } if(debug) { fprintf(stdout, "%s: DEBUG: PFKEYv2 socket successfully openned=%d.\n", progname, pfkey_sock); } /* Build an SADB_X_ADDFLOW or SADB_X_DELFLOW message to send down. */ /* It needs <base, SA, address(SD), flow(SD), mask(SD)> minimum. */ pfkey_extensions_init(extensions); if((error = pfkey_msg_hdr_build(&extensions[0], (action_type == EMT_SETEROUTE || action_type == EMT_REPLACEROUTE || action_type == EMT_INREPLACEROUTE || action_type == EMT_INEROUTE) ? SADB_X_ADDFLOW : SADB_X_DELFLOW, proto2satype(said.proto), 0, ++pfkey_seq, getpid()))) { fprintf(stderr, "%s: Trouble building message header, error=%d.\n", progname, error); pfkey_extensions_free(extensions); exit(1); } if(debug) { fprintf(stdout, "%s: DEBUG: pfkey_msg_hdr_build successfull.\n", progname); } switch(action_type) { case EMT_CLREROUTE: sa_flags = SADB_X_SAFLAGS_CLEARFLOW; goto sa_build; case EMT_REPLACEROUTE: sa_flags = SADB_X_SAFLAGS_REPLACEFLOW; goto sa_build; case EMT_INREPLACEROUTE: sa_flags = SADB_X_SAFLAGS_REPLACEFLOW | SADB_X_SAFLAGS_INFLOW; goto sa_build; case EMT_INEROUTE: sa_flags = SADB_X_SAFLAGS_INFLOW; goto sa_build; case EMT_SETEROUTE: sa_build: if((error = pfkey_sa_build(&extensions[SADB_EXT_SA], SADB_EXT_SA, said.spi, /* in network order */ 0, 0, 0, 0, sa_flags))) { fprintf(stderr, "%s: Trouble building sa extension, error=%d.\n", progname, error); pfkey_extensions_free(extensions); exit(1); } if(debug) { fprintf(stdout, "%s: DEBUG: pfkey_sa_build successful.\n", progname); } default: break; } switch(action_type) { case EMT_SETEROUTE: case EMT_REPLACEROUTE: case EMT_INEROUTE: case EMT_INREPLACEROUTE: anyaddr(said_af, &pfkey_address_s_ska); if((error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_SRC], SADB_EXT_ADDRESS_SRC, 0, 0, sockaddrof(&pfkey_address_s_ska)))) { addrtot(&pfkey_address_s_ska, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stderr, "%s: Trouble building address_s extension (%s), error=%d.\n", progname, ipaddr_txt, error); pfkey_extensions_free(extensions); exit(1); } if(debug) { fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for src.\n", progname); } if((error = pfkey_address_build(&extensions[SADB_EXT_ADDRESS_DST], SADB_EXT_ADDRESS_DST, 0, 0, sockaddrof(&said.dst)))) { addrtot(&said.dst, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stderr, "%s: Trouble building address_d extension (%s), error=%d.\n", progname, ipaddr_txt, error); pfkey_extensions_free(extensions); exit(1); } if(debug) { fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for dst.\n", progname); } default: break; } switch(action_type) { case EMT_SETEROUTE: case EMT_REPLACEROUTE: case EMT_INEROUTE: case EMT_INREPLACEROUTE: case EMT_DELEROUTE: networkof(&s_subnet, &pfkey_address_sflow_ska); /* src flow */ add_port(eroute_af, &pfkey_address_sflow_ska, src_port); if((error = pfkey_address_build(&extensions[SADB_X_EXT_ADDRESS_SRC_FLOW], SADB_X_EXT_ADDRESS_SRC_FLOW, 0, 0, sockaddrof(&pfkey_address_sflow_ska)))) { addrtot(&pfkey_address_sflow_ska, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stderr, "%s: Trouble building address_sflow extension (%s), error=%d.\n", progname, ipaddr_txt, error); pfkey_extensions_free(extensions); exit(1); } if(debug) { fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for src flow.\n", progname); } networkof(&d_subnet, &pfkey_address_dflow_ska); /* dst flow */ add_port(eroute_af, &pfkey_address_dflow_ska, dst_port); if((error = pfkey_address_build(&extensions[SADB_X_EXT_ADDRESS_DST_FLOW], SADB_X_EXT_ADDRESS_DST_FLOW, 0, 0, sockaddrof(&pfkey_address_dflow_ska)))) { addrtot(&pfkey_address_dflow_ska, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stderr, "%s: Trouble building address_dflow extension (%s), error=%d.\n", progname, ipaddr_txt, error); pfkey_extensions_free(extensions); exit(1); } if(debug) { fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for dst flow.\n", progname); } maskof(&s_subnet, &pfkey_address_smask_ska); /* src mask */ add_port(eroute_af, &pfkey_address_smask_ska, src_port ? ~0:0); if((error = pfkey_address_build(&extensions[SADB_X_EXT_ADDRESS_SRC_MASK], SADB_X_EXT_ADDRESS_SRC_MASK, 0, 0, sockaddrof(&pfkey_address_smask_ska)))) { addrtot(&pfkey_address_smask_ska, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stderr, "%s: Trouble building address_smask extension (%s), error=%d.\n", progname, ipaddr_txt, error); pfkey_extensions_free(extensions); exit(1); } if(debug) { fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for src mask.\n", progname); } maskof(&d_subnet, &pfkey_address_dmask_ska); /* dst mask */ add_port(eroute_af, &pfkey_address_dmask_ska, dst_port ? ~0:0); if((error = pfkey_address_build(&extensions[SADB_X_EXT_ADDRESS_DST_MASK], SADB_X_EXT_ADDRESS_DST_MASK, 0, 0, sockaddrof(&pfkey_address_dmask_ska)))) { addrtot(&pfkey_address_dmask_ska, 0, ipaddr_txt, sizeof(ipaddr_txt)); fprintf(stderr, "%s: Trouble building address_dmask extension (%s), error=%d.\n", progname, ipaddr_txt, error); pfkey_extensions_free(extensions); exit(1); } if(debug) { fprintf(stdout, "%s: DEBUG: pfkey_address_build successful for dst mask.\n", progname); } } if (transport_proto != 0) { if ((error = pfkey_x_protocol_build(&extensions[SADB_X_EXT_PROTOCOL], transport_proto))) { fprintf(stderr, "%s: Trouble building transport" " protocol extension, error=%d.\n", progname, error); exit(1); } } if((error = pfkey_msg_build(&pfkey_msg, extensions, EXT_BITS_IN))) { fprintf(stderr, "%s: Trouble building pfkey message, error=%d.\n", progname, error); pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); exit(1); } if(debug) { fprintf(stdout, "%s: DEBUG: pfkey_msg_build successful.\n", progname); } if((error = write(pfkey_sock, pfkey_msg, pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) != (ssize_t)(pfkey_msg->sadb_msg_len * IPSEC_PFKEYv2_ALIGN)) { fprintf(stderr, "%s: pfkey write failed, returning %d with errno=%d.\n", progname, error, errno); pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); switch(errno) { case EINVAL: fprintf(stderr, "Invalid argument, check kernel log messages for specifics.\n"); break; case ENXIO: if((action_type == EMT_SETEROUTE) || (action_type == EMT_REPLACEROUTE)) { fprintf(stderr, "Invalid mask.\n"); break; } if(action_type == EMT_DELEROUTE) { fprintf(stderr, "Mask not found.\n"); break; } case EFAULT: if((action_type == EMT_SETEROUTE) || (action_type == EMT_REPLACEROUTE)) { fprintf(stderr, "Invalid address.\n"); break; } if(action_type == EMT_DELEROUTE) { fprintf(stderr, "Address not found.\n"); break; } case EACCES: fprintf(stderr, "access denied. "); if(getuid() == 0) { fprintf(stderr, "Check permissions. Should be 600.\n"); } else { fprintf(stderr, "You must be root to open this file.\n"); } break; case EUNATCH: fprintf(stderr, "KLIPS not loaded.\n"); break; case EBUSY: fprintf(stderr, "KLIPS is busy. Most likely a serious internal error occured in a previous command. Please report as much detail as possible to development team.\n"); break; case ENODEV: fprintf(stderr, "KLIPS not loaded or enabled.\n"); fprintf(stderr, "No device?!?\n"); break; case ENOBUFS: fprintf(stderr, "No kernel memory to allocate SA.\n"); break; case ESOCKTNOSUPPORT: fprintf(stderr, "Algorithm support not available in the kernel. Please compile in support.\n"); break; case EEXIST: fprintf(stderr, "eroute already in use. Delete old one first.\n"); break; case ENOENT: if(action_type == EMT_INEROUTE || action_type == EMT_INREPLACEROUTE) { fprintf(stderr, "non-existant IPIP SA.\n"); break; } fprintf(stderr, "eroute doesn't exist. Can't delete.\n"); break; case ENOSPC: fprintf(stderr, "no room in kernel SAref table. Cannot process request.\n"); break; case ESPIPE: fprintf(stderr, "kernel SAref table internal error. Cannot process request.\n"); break; default: fprintf(stderr, "Unknown socket write error %d. Please report as much detail as possible to development team.\n", errno); } /* fprintf(stderr, "%s: socket write returned errno %d\n", progname, errno);*/ exit(1); } if(debug) { fprintf(stdout, "%s: DEBUG: pfkey write successful.\n", progname); } if(pfkey_msg) { pfkey_extensions_free(extensions); pfkey_msg_free(&pfkey_msg); } (void) close(pfkey_sock); /* close the socket */ if(debug) { fprintf(stdout, "%s: DEBUG: write ok\n", progname); } exit(0); }
/* void */ int ipsec_init(void) { int error = 0; unsigned char seed[256]; #ifdef CONFIG_IPSEC_ENC_3DES extern int des_check_key; /* turn off checking of keys */ des_check_key=0; #endif /* CONFIG_IPSEC_ENC_3DES */ KLIPS_PRINT(1, "klips_info:ipsec_init: " "KLIPS startup, Openswan KLIPS IPsec stack version: %s\n", ipsec_version_code()); error |= ipsec_proc_init(); #ifdef SPINLOCK ipsec_sadb.sadb_lock = SPIN_LOCK_UNLOCKED; #else /* SPINLOCK */ ipsec_sadb.sadb_lock = 0; #endif /* SPINLOCK */ #ifndef SPINLOCK tdb_lock.lock = 0; eroute_lock.lock = 0; #endif /* !SPINLOCK */ error |= ipsec_sadb_init(); error |= ipsec_radijinit(); error |= pfkey_init(); error |= register_netdevice_notifier(&ipsec_dev_notifier); #ifdef CONFIG_IPSEC_ESP openswan_inet_add_protocol(&esp_protocol, IPPROTO_ESP); #endif /* CONFIG_IPSEC_ESP */ #ifdef CONFIG_IPSEC_AH openswan_inet_add_protocol(&ah_protocol, IPPROTO_AH); #endif /* CONFIG_IPSEC_AH */ /* we never actually link IPCOMP to the stack */ #ifdef IPCOMP_USED_ALONE #ifdef CONFIG_IPSEC_IPCOMP openswan_inet_add_protocol(&comp_protocol, IPPROTO_COMP); #endif /* CONFIG_IPSEC_IPCOMP */ #endif error |= ipsec_tunnel_init_devices(); #ifdef CONFIG_SYSCTL error |= ipsec_sysctl_register(); #endif #ifdef CONFIG_IPSEC_ALG ipsec_alg_init(); #endif get_random_bytes((void *)seed, sizeof(seed)); prng_init(&ipsec_prng, seed, sizeof(seed)); return error; }