main(int argc, char *argv[]) { int len; err_t err = NULL; char *infile; char *conn_name; int lineno=0; struct starter_config *cfg = NULL; struct starter_conn *conn = NULL; //EF_PROTECT_FREE=1; progname = argv[0]; leak_detective = 1; if(argc < 4) { fprintf(stderr, "Usage: %s <cfgrootdir> <cfgfile> <conn-name>.. \n", progname); exit(10); } /* argv[1] == "-r" */ tool_init_log(); //init_fake_vendorid(); rootdir[0]='\0'; strlcat(rootdir, argv[1], sizeof(rootdir)); starter_use_log(1, 1, 1); cfg = confread_load(argv[2], &err, FALSE, NULL,FALSE); argv+=3; argc-=3; /* load all conns marked as auto=add or better */ for(conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { for(; argc>0; argc--, argv++) { conn_name = *argv; printf("processing conn: %s\n", conn_name); if(strcasecmp(conn->name, conn_name)==0) { struct whack_message msg1; if(starter_whack_build_basic_conn(cfg, &msg1, conn)==0) { add_connection(&msg1); } } } } confread_free(cfg); report_leaks(); tool_close_log(); exit(0); }
/* Read config file. exit() on error. */ static struct starter_config *read_cfg_file(char *configfile) { struct starter_config *cfg = NULL; err_t err = NULL; cfg = confread_load(configfile, &err, FALSE, NULL, TRUE); if (cfg == NULL) invocation_fail(err); return cfg; }
int main(int argc, char *argv[]) { int opt = 0; int autoall = 0; int configsetup = 0; int checkconfig = 0; char *export = "export"; /* display export before the foo=bar or not */ int listroute = 0, liststart = 0, listignore = 0, listadd = 0, listall = 0, dolist = 0, liststack = 0; struct starter_config *cfg = NULL; err_t err = NULL; char *confdir = NULL; char *configfile = NULL; char *varprefix = ""; int exit_status = 0; struct starter_conn *conn = NULL; char *ctlbase = NULL; bool resolvip = TRUE; /* default to looking up names */ #if 0 /* efence settings */ extern int EF_PROTECT_BELOW; extern int EF_PROTECT_FREE; EF_PROTECT_BELOW = 1; EF_PROTECT_FREE = 1; #endif progname = argv[0]; rootdir[0] = '\0'; tool_init_log(); while ((opt = getopt_long(argc, argv, "", longopts, 0)) != EOF) { switch (opt) { case 'h': /* usage: */ usage(); break; case 'a': autoall = 1; break; case 'D': verbose++; lex_verbosity++; break; case 'T': configsetup++; break; case 'K': checkconfig++; break; case 'N': export = ""; break; case 'C': configfile = clone_str(optarg, "config file name"); break; case 'c': ctlbase = clone_str(optarg, "control base"); break; case 'L': listadd = 1; dolist = 1; break; case 'r': listroute = 1; dolist = 1; break; case 's': liststart = 1; dolist = 1; break; case 'S': liststack = 1; dolist = 1; break; case 'i': listignore = 1; dolist = 1; break; case 'A': listall = 1; dolist = 1; break; case 'P': varprefix = optarg; break; case 'R': printf("setting rootdir=%s\n", optarg); jam_str(rootdir, sizeof(rootdir), optarg); break; case 'd': case 'n': printf("Warning: options --defaultroute and --defaultroutenexthop are obsolete and were ignored\n"); break; default: usage(); } } /* if nothing to add, then complain */ if (optind == argc && !autoall && !dolist && !configsetup && !checkconfig) usage(); if (verbose > 3) { yydebug = 1; } /* find config file */ if (confdir == NULL) confdir = IPSEC_CONFDIR; if (configfile == NULL) { /* ??? see code clone in programs/readwriteconf/readwriteconf.c */ configfile = alloc_bytes(strlen(confdir) + sizeof("/ipsec.conf"), "conf file"); /* calculate default value for configfile */ strcpy(configfile, confdir); /* safe: see allocation above */ if (configfile[0] != '\0' && configfile[strlen(configfile) - 1] != '/') strcat(configfile, "/"); /* safe: see allocation above */ strcat(configfile, "ipsec.conf"); /* safe: see allocation above */ } if (verbose) printf("opening file: %s\n", configfile); starter_use_log(verbose != 0, TRUE, verbose == 0); err = NULL; /* reset to no error */ if (configsetup || checkconfig || dolist) { /* skip if we have no use for them... causes delays */ resolvip = FALSE; } cfg = confread_load(configfile, &err, resolvip, ctlbase, configsetup); if (cfg == NULL) { fprintf(stderr, "cannot load config '%s': %s\n", configfile, err); exit(3); } else if (checkconfig) { confread_free(cfg); exit(0); } if (autoall) { if (verbose) printf("loading all conns according to their auto= settings\n"); /* * Load all conns marked as auto=add or better. * First, do the auto=route and auto=add conns to quickly * get routes in place, then do auto=start as these can be * slower. * This mimics behaviour of the old _plutoload */ if (verbose) printf(" Pass #1: Loading auto=add, auto=route and auto=start connections\n"); for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (conn->desired_state == STARTUP_ADD || conn->desired_state == STARTUP_ONDEMAND || conn->desired_state == STARTUP_START) { if (verbose) printf(" %s", conn->name); starter_whack_add_conn(cfg, conn); } } /* * We loaded all connections. Now tell pluto to listen, * then route the conns and resolve default route. */ starter_whack_listen(cfg); if (verbose) printf(" Pass #2: Routing auto=route and auto=start connections\n"); for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (conn->desired_state == STARTUP_ADD || conn->desired_state == STARTUP_ONDEMAND || conn->desired_state == STARTUP_START) { if (verbose) printf(" %s", conn->name); resolve_defaultroute(conn); if (conn->desired_state == STARTUP_ONDEMAND || conn->desired_state == STARTUP_START) { starter_whack_route_conn(cfg, conn); } } } if (verbose) printf(" Pass #3: Initiating auto=start connections\n"); for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (conn->desired_state == STARTUP_START) { if (verbose) printf(" %s", conn->name); starter_whack_initiate_conn(cfg, conn); } } if (verbose) printf("\n"); } else { /* load named conns, regardless of their state */ int connum; if (verbose) printf("loading named conns:"); for (connum = optind; connum < argc; connum++) { char *connname = argv[connum]; if (verbose) printf(" %s", connname); for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (streq(conn->name, connname)) { if (conn->state == STATE_ADDED) { printf("\nconn %s already added\n", conn->name); } else if (conn->state == STATE_FAILED) { printf("\nconn %s did not load properly\n", conn->name); } else { resolve_defaultroute(conn); exit_status = starter_whack_add_conn( cfg, conn); conn->state = STATE_ADDED; } break; } } if (conn == NULL) { /* * only if we don't find it, do we now look * for aliases */ for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (conn->strings_set[KSF_CONNALIAS] && lsw_alias_cmp(connname, conn-> strings[KSF_CONNALIAS] )) { if (conn->state == STATE_ADDED) { printf("\nalias: %s conn %s already added\n", connname, conn->name); } else if (conn->state == STATE_FAILED) { printf("\nalias: %s conn %s did not load properly\n", connname, conn->name); } else { resolve_defaultroute( conn); exit_status = starter_whack_add_conn( cfg, conn); conn->state = STATE_ADDED; } break; } } } if (conn == NULL) { exit_status++; if (!verbose) { printf("conn '%s': not found (tried aliases)\n", connname); } else { printf(" (notfound)\n"); } } } } if (listall) { if (verbose) printf("listing all conns\n"); for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) printf("%s ", conn->name); printf("\n"); } else { if (listadd) { if (verbose) printf("listing all conns marked as auto=add\n"); /* list all conns marked as auto=add */ for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (conn->desired_state == STARTUP_ADD) printf("%s ", conn->name); } } if (listroute) { if (verbose) printf("listing all conns marked as auto=route and auto=start\n"); /* * list all conns marked as auto=route or start or * better */ for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (conn->desired_state == STARTUP_START || conn->desired_state == STARTUP_ONDEMAND) printf("%s ", conn->name); } } if (liststart && !listroute) { if (verbose) printf("listing all conns marked as auto=start\n"); /* list all conns marked as auto=start */ for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (conn->desired_state == STARTUP_START) printf("%s ", conn->name); } } if (listignore) { if (verbose) printf("listing all conns marked as auto=ignore\n"); /* list all conns marked as auto=start */ for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (conn->desired_state == STARTUP_IGNORE) printf("%s ", conn->name); } printf("\n"); } } if (liststack) { const struct keyword_def *kd; for (kd = ipsec_conf_keywords_v2; kd->keyname != NULL; kd++) { if (strstr(kd->keyname, "protostack")) { if (cfg->setup.strings[kd->field]) printf("%s\n", cfg->setup.strings[kd->field]); else /* implicit default */ printf("netkey\n"); } } confread_free(cfg); exit(0); } if (configsetup) { const struct keyword_def *kd; printf("%s %sconfreadstatus=''\n", export, varprefix); for (kd = ipsec_conf_keywords_v2; kd->keyname != NULL; kd++) { if ((kd->validity & kv_config) == 0) continue; switch (kd->type) { case kt_string: case kt_filename: case kt_dirname: case kt_loose_enum: if (cfg->setup.strings[kd->field]) { printf("%s %s%s='%s'\n", export, varprefix, kd->keyname, cfg->setup.strings[kd->field]); } break; case kt_bool: printf("%s %s%s='%s'\n", export, varprefix, kd->keyname, cfg->setup.options[kd->field] ? "yes" : "no"); break; case kt_list: printf("%s %s%s='", export, varprefix, kd->keyname); confwrite_list(stdout, "", cfg->setup.options[kd->field], kd); printf("'\n"); break; case kt_obsolete: printf("# obsolete option '%s%s' ignored\n", varprefix, kd->keyname); break; default: if (cfg->setup.options[kd->field] || cfg->setup.options_set[kd->field]) { printf("%s %s%s='%d'\n", export, varprefix, kd->keyname, cfg->setup.options[kd->field]); } break; } }
int main(int argc, char *argv[]) { int opt = 0; struct starter_config *cfg = NULL; err_t err = NULL; char *confdir = NULL; char *configfile = NULL; struct starter_conn *conn = NULL; progname = argv[0]; rootdir[0] = '\0'; rootdir2[0] = '\0'; tool_init_log(); while ((opt = getopt_long(argc, argv, "", longopts, 0)) != EOF) { switch (opt) { case 'h': /* usage: */ usage(); break; case 'D': verbose++; lex_verbosity++; break; case 'C': configfile = clone_str(optarg, "config file name"); break; case 'R': printf("#setting rootdir=%s\n", optarg); jam_str(rootdir, sizeof(rootdir), optarg); break; case 'S': printf("#setting rootdir2=%s\n", optarg); jam_str(rootdir2, sizeof(rootdir2), optarg); break; case '?': exit(5); default: fprintf(stderr, "%s: getopt returned %d\n", progname, opt); exit(6); } } if (optind != argc) { fprintf(stderr,"%s: unexpected arguments\n", progname); exit(4); } /* find config file */ if (confdir == NULL) confdir = IPSEC_CONFDIR; if (configfile == NULL) { /* ??? see code clone in programs/addconn/addconn.c */ configfile = alloc_bytes(strlen(confdir) + sizeof("/ipsec.conf"), "conf file"); /* calculate default value for configfile */ strcpy(configfile, confdir); /* safe: see allocation above */ if (configfile[0] != '\0' && configfile[strlen(configfile) - 1] != '/') strcat(configfile, "/"); /* safe: see allocation above */ strcat(configfile, "ipsec.conf"); /* safe: see allocation above */ } if (verbose > 3) { yydebug = 1; } if (verbose) printf("opening file: %s\n", configfile); starter_use_log(verbose != 0, TRUE, verbose == 0); cfg = confread_load(configfile, &err, FALSE, NULL, FALSE); if (cfg == NULL) { fprintf(stderr, "%s: config file \"%s\" cannot be loaded: %s\n", progname, configfile, err); exit(3); } /* load all conns marked as auto=add or better */ for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) printf("#conn %s loaded\n", conn->name); confwrite(cfg, stdout); confread_free(cfg); exit(0); }
int main(int argc, char *argv[]) { int opt = 0; int textout = 1; int whackout = 0; /* if true, write whack messages */ char *whackfile = NULL; struct starter_config *cfg = NULL; err_t err = NULL; char *confdir = NULL; char *configfile = NULL; struct starter_conn *conn = NULL; progname = argv[0]; rootdir[0]='\0'; tool_init_log(); while((opt = getopt_long(argc, argv, "", longopts, 0)) != EOF) { switch(opt) { case 'h': /* usage: */ usage(); break; case 'T': textout = 1; break; case 'w': whackfile = clone_str(optarg, "output file name"); whackout = 1; textout = 0; break; case 'D': verbose++; break; case 'W': warningsarefatal++; break; case 'C': configfile = clone_str(optarg, "config file name"); break; case 'R': if(verbose) printf("#setting rootdir=%s\n", optarg); strlcat(rootdir, optarg, sizeof(rootdir)); break; case 'S': if(verbose) printf("#setting rootdir2=%s\n", optarg); rootdir2[0]='\0'; strlcat(rootdir2, optarg, sizeof(rootdir2)); break; } } /* find config file */ confdir = getenv(IPSEC_CONFDIR_VAR); if(confdir == NULL) { confdir = IPSEC_CONFDIR; } if(!configfile) { configfile = alloc_bytes(strlen(confdir)+sizeof("/ipsec.conf")+2,"conf file"); /* calculate default value for configfile */ configfile[0]='\0'; strcpy(configfile, confdir); if(configfile[strlen(configfile)-1]!='/') { strcat(configfile, "/"); } strcat(configfile, "ipsec.conf"); } if(verbose > 3) { extern int yydebug; yydebug=1; } if(verbose) { printf("opening file: %s\n", configfile); } starter_use_log (verbose, 1, verbose ? 0 : 1); cfg = confread_load(configfile, &err, FALSE, NULL,FALSE); if(!cfg) { printf("config file: %s can not be loaded: %s\n", configfile, err); exit(3); } if(textout) { /* load all conns marked as auto=add or better */ for(conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { printf("#conn %s loaded\n", conn->name); } confwrite(cfg, stdout); } if(whackout && whackfile!=NULL) { if(!openwhackrecordfile(whackfile)) { perror(whackfile); exit(5); } /* use file writer above */ cfg->send_whack_msg = send_whack_msg_to_file; /* load all conns marked as auto=add or better, and save them. */ argv+=optind; argc-=optind; for(; argc>0; argc--, argv++) { char *conn_name = *argv; for(conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if(verbose) { printf("processing conn: %s vs %s\n", conn_name, conn->name); } if(strcasecmp(conn->name, conn_name)==0) { if(starter_whack_add_conn(cfg, conn) != 0) { fprintf(stderr, "failed to load conn: %s\n", conn_name); } } } } } confread_free(cfg); exit(0); }
int main(int argc, char *argv[]) { int opt = 0; struct starter_config *cfg = NULL; err_t err = NULL; char *confdir = NULL; char *configfile = NULL; struct starter_conn *conn = NULL; progname = argv[0]; rootdir[0] = '\0'; tool_init_log(); while ((opt = getopt_long(argc, argv, "", longopts, 0)) != EOF) { switch (opt) { case 'h': //usage: usage(); break; case 'D': verbose++; break; case 'W': warningsarefatal++; break; case 'C': configfile = clone_str(optarg, "config file name"); break; case 'R': printf("#setting rootdir=%s\n", optarg); strncat(rootdir, optarg, sizeof(rootdir)); break; case 'S': printf("#setting rootdir2=%s\n", optarg); strncat(rootdir2, optarg, sizeof(rootdir2)); break; } } /* find config file */ if (confdir == NULL) confdir = IPSEC_CONFDIR; if (!configfile) { configfile = alloc_bytes(strlen( confdir) + sizeof("/ipsec.conf") + 2, "conf file"); /* calculate default value for configfile */ configfile[0] = '\0'; strcpy(configfile, confdir); if (configfile[strlen(configfile) - 1] != '/') strcat(configfile, "/"); strcat(configfile, "ipsec.conf"); } if (verbose) printf("opening file: %s\n", configfile); starter_use_log(verbose, 1, verbose ? 0 : 1); cfg = confread_load(configfile, &err, NULL); if (!cfg) { printf("config file: %s can not be loaded: %s\n", configfile, err); exit(3); } /* load all conns marked as auto=add or better */ for (conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { /* basic case, nothing special to synthize! */ if (!conn->left.strings_set[KSCF_SUBNETS] && !conn->right.strings_set[KSCF_SUBNETS]) continue; starter_permutate_conns(starter_print_connname, cfg, conn); } exit(0); }
int main(int argc, char *argv[]) { int opt = 0; int all = 0; int search = 0; int typeexport = 0; int checkconfig = 0; int listroute=0, liststart=0; struct starter_config *cfg = NULL; err_t err = NULL; char *confdir = NULL; char *configfile = NULL; char *varprefix = ""; int exit_status = 0; struct starter_conn *conn = NULL; char *defaultroute = NULL; char *defaultnexthop = NULL; char *ctlbase = NULL; bool resolvip = FALSE; #if 0 /* efence settings */ extern int EF_PROTECT_BELOW; extern int EF_PROTECT_FREE; EF_PROTECT_BELOW=1; EF_PROTECT_FREE=1; #endif progname = argv[0]; rootdir[0]='\0'; tool_init_log(); while((opt = getopt_long(argc, argv, "", longopts, 0)) != EOF) { switch(opt) { case 'h': /* usage: */ usage(); break; case 'a': all=1; break; case 'D': verbose++; break; case 'W': warningsarefatal++; break; case 'S': search++; break; case 'T': typeexport++; break; case 'K': checkconfig++; break; case 'C': configfile = clone_str(optarg, "config file name"); break; case 'c': ctlbase = clone_str(optarg, "control base"); break; case 'A': all=1; break; case 'r': listroute=1; break; case 's': liststart=1; break; case 'P': varprefix=optarg; break; case 'R': printf("setting rootdir=%s\n", optarg); strncat(rootdir, optarg, sizeof(rootdir)-1); break; case 'd': defaultroute=optarg; break; case 'n': defaultnexthop=optarg; break; default: usage(); } } /* if nothing to add, then complain */ if(optind == argc && !all && !listroute && !liststart && !search && !typeexport && !checkconfig) { usage(); } if(verbose > 3) { extern int yydebug; yydebug=1; } /* find config file */ confdir = getenv(IPSEC_CONFDIR_VAR); if(confdir == NULL) { confdir = IPSEC_CONFDIR; } if(!configfile) { configfile = alloc_bytes(strlen(confdir)+sizeof("/ipsec.conf")+2,"conf file"); /* calculate default value for configfile */ configfile[0]='\0'; strcpy(configfile, confdir); if(configfile[strlen(configfile)-1]!='/') { strcat(configfile, "/"); } strcat(configfile, "ipsec.conf"); } if(verbose) { printf("opening file: %s\n", configfile); } starter_use_log (verbose, 1, verbose ? 0 : 1); err = NULL; /* reset to no error */ resolvip=TRUE; /* default to looking up names */ if(typeexport || checkconfig || listroute || liststart || search) { /* but not if we have no use for them... might cause delays too! */ resolvip=FALSE; } cfg = confread_load(configfile, &err, resolvip, ctlbase,typeexport); if(cfg == NULL) { fprintf(stderr, "can not load config '%s': %s\n", configfile, err); exit(3); } else if(checkconfig) { confread_free(cfg); exit(0); } if(defaultroute) { err_t e; char b[ADDRTOT_BUF]; e = ttoaddr(defaultroute, strlen(defaultroute), AF_INET, &cfg->dr); if(e) { printf("ignoring invalid defaultroute: %s\n", e); defaultroute = NULL; /* exit(4); */ } else if(verbose) { addrtot(&cfg->dr, 0, b, sizeof(b)); printf("default route is: %s\n", b); } } if(defaultnexthop) { err_t e; char b[ADDRTOT_BUF]; e = ttoaddr(defaultnexthop, strlen(defaultnexthop), AF_INET, &cfg->dnh); if(e) { printf("ignoring invalid defaultnexthop: %s\n", e); defaultnexthop = NULL; /* exit(4); */ } else if(verbose) { addrtot(&cfg->dnh, 0, b, sizeof(b)); printf("default nexthop is: %s\n", b); } } if(all) { if(verbose) { printf("loading all conns:"); } /* load all conns marked as auto=add or better */ for(conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (conn->desired_state == STARTUP_ADD || conn->desired_state == STARTUP_START || conn->desired_state == STARTUP_ROUTE) { if(verbose) printf(" %s", conn->name); starter_whack_add_conn(cfg, conn); } } if(verbose) printf("\n"); } else if(listroute) { if(verbose) { printf("listing all conns marked as auto=start\n"); } /* list all conns marked as auto=route or start or better */ for(conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (conn->desired_state == STARTUP_START || conn->desired_state == STARTUP_ROUTE) { printf("%s ", conn->name); } } printf("\n"); } else if(liststart) { /* list all conns marked as auto=start */ for(conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if (conn->desired_state == STARTUP_START) { printf("%s ", conn->name); } } printf("\n"); } else if(search) { char *sep=""; if((argc-optind) < 2 ) { printf("%s_confreadstatus=failed\n", varprefix); confread_free(cfg); exit(3); } printf("%s_confreadstatus=\n", varprefix); printf("%s_confreadnames=\"",varprefix); /* find conn names that have value set */ for(conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { /* we recognize a limited set of values */ if(strcasecmp(argv[optind],"auto")==0 && strcasecmp(argv[optind+1],"manual")==0) { if(conn->manualkey) { printf("%s%s", sep, conn->name); sep=" "; } } } printf("\"\n"); confread_free(cfg); exit(0); } else if(typeexport) { struct keyword_def *kd; printf("export %sconfreadstatus=''\n", varprefix); for(kd=ipsec_conf_keywords_v2; kd->keyname != NULL; kd++) { if((kd->validity & kv_config)==0) continue; switch(kd->type) { case kt_string: case kt_filename: case kt_dirname: case kt_loose_enum: if(cfg->setup.strings[kd->field]) { printf("export %s%s='%s'\n", varprefix, kd->keyname, cfg->setup.strings[kd->field]); } break; case kt_bool: printf("export %s%s='%s'\n", varprefix, kd->keyname, cfg->setup.options[kd->field] ? "yes" : "no"); break; case kt_list: printf("export %s%s='", varprefix, kd->keyname); confwrite_list(stdout, "", cfg->setup.options[kd->field], kd); printf("'\n"); break; case kt_obsolete: printf("# obsolete option '%s%s' ignored\n", varprefix, kd->keyname); break; default: if(cfg->setup.options[kd->field] || cfg->setup.options_set[kd->field]) { printf("export %s%s='%d'\n", varprefix, kd->keyname, cfg->setup.options[kd->field]); } break; } } confread_free(cfg); exit(0); } else { /* load named conns, regardless of their state */ int connum; if(verbose) { printf("loading named conns:"); } for(connum = optind; connum<argc; connum++) { char *connname = argv[connum]; if(verbose) { printf(" %s", connname); } for(conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { /* yes, let's make it case-insensitive */ if(strcasecmp(conn->name, connname)==0) { if(conn->state == STATE_ADDED) { printf("\nconn %s already added\n", conn->name); } else if(conn->state == STATE_FAILED) { printf("\nconn %s did not load properly\n", conn->name); } else { exit_status = starter_whack_add_conn(cfg, conn); conn->state = STATE_ADDED; } break; } } if(conn == NULL) { /* only if we don't find it, do we now look for aliases */ for(conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { if(conn->strings_set[KSF_CONNALIAS] && osw_alias_cmp(connname , conn->strings[KSF_CONNALIAS])) { if(conn->state == STATE_ADDED) { printf("\nalias: %s conn %s already added\n", connname, conn->name); } else if(conn->state == STATE_FAILED) { printf("\nalias: %s conn %s did not load properly\n", connname, conn->name); } else { exit_status = starter_whack_add_conn(cfg, conn); conn->state = STATE_ADDED; } break; } } } if(conn == NULL) { exit_status++; if(!verbose) { printf("conn '%s': not found (tried aliases)\n", connname); } else { printf("(notfound)"); } } } if(verbose) printf("\n"); } confread_free(cfg); exit(exit_status); }
int main(int argc, char *argv[]) { int opt = 0; struct starter_config *cfg = NULL; err_t err = NULL; char *confdir = NULL; char *configfile = NULL; struct starter_conn *conn = NULL; progname = argv[0]; rootdir[0]='\0'; tool_init_log(); while((opt = getopt_long(argc, argv, "", longopts, 0)) != EOF) { switch(opt) { case 'h': /* usage: */ usage(); break; case 'D': verbose++; break; case 'W': warningsarefatal++; break; case 'C': configfile = clone_str(optarg, "config file name"); break; case 'R': printf("#setting rootdir=%s\n", optarg); strlcat(rootdir, optarg, sizeof(rootdir)); break; case 'S': printf("#setting rootdir2=%s\n", optarg); rootdir2[0]='\0'; strlcat(rootdir2, optarg, sizeof(rootdir2)); break; } } /* find config file */ confdir = getenv(IPSEC_CONFDIR_VAR); if(confdir == NULL) { confdir = IPSEC_CONFDIR; } if(!configfile) { configfile = alloc_bytes(strlen(confdir)+sizeof("/ipsec.conf")+2,"conf file"); /* calculate default value for configfile */ configfile[0]='\0'; strcpy(configfile, confdir); if(configfile[strlen(configfile)-1]!='/') { strcat(configfile, "/"); } strcat(configfile, "ipsec.conf"); } if(verbose > 3) { extern int yydebug; yydebug=1; } if(verbose) { printf("opening file: %s\n", configfile); } starter_use_log (verbose, 1, verbose ? 0 : 1); cfg = confread_load(configfile, &err, FALSE, NULL,FALSE); if(!cfg) { printf("config file: %s can not be loaded: %s\n", configfile, err); exit(3); } /* load all conns marked as auto=add or better */ for(conn = cfg->conns.tqh_first; conn != NULL; conn = conn->link.tqe_next) { printf("#conn %s loaded\n", conn->name); } confwrite(cfg, stdout); confread_free(cfg); exit(0); }
int main (int argc, char **argv) { starter_config_t *cfg = NULL; starter_config_t *new_cfg; starter_conn_t *conn, *conn2; starter_ca_t *ca, *ca2; struct sigaction action; struct stat stb; int i; int id = 1; struct timespec ts; unsigned long auto_update = 0; time_t last_reload; bool no_fork = FALSE; bool attach_gdb = FALSE; bool load_warning = FALSE; library_init(NULL); atexit(library_deinit); libhydra_init("starter"); atexit(libhydra_deinit); /* parse command line */ for (i = 1; i < argc; i++) { if (streq(argv[i], "--debug")) { current_loglevel = 2; } else if (streq(argv[i], "--debug-more")) { current_loglevel = 3; } else if (streq(argv[i], "--debug-all")) { current_loglevel = 4; } else if (streq(argv[i], "--nolog")) { current_loglevel = 0; } else if (streq(argv[i], "--nofork")) { no_fork = TRUE; } else if (streq(argv[i], "--attach-gdb")) { no_fork = TRUE; attach_gdb = TRUE; } else if (streq(argv[i], "--auto-update") && i+1 < argc) { auto_update = atoi(argv[++i]); if (!auto_update) usage(argv[0]); } else if (streq(argv[i], "--daemon") && i+1 < argc) { daemon_name = argv[++i]; } else { usage(argv[0]); } } if (!set_daemon_name()) { DBG1(DBG_APP, "unable to set daemon name"); exit(LSB_RC_FAILURE); } init_log("ipsec_starter"); DBG1(DBG_APP, "Starting %sSwan "VERSION" IPsec [starter]...", lib->settings->get_bool(lib->settings, "charon.i_dont_care_about_security_and_use_aggressive_mode_psk", FALSE) ? "weak" : "strong"); #ifdef LOAD_WARNING load_warning = TRUE; #endif if (lib->settings->get_bool(lib->settings, "starter.load_warning", load_warning)) { if (lib->settings->get_str(lib->settings, "charon.load", NULL)) { DBG1(DBG_APP, "!! Your strongswan.conf contains manual plugin load options for charon."); DBG1(DBG_APP, "!! This is recommended for experts only, see"); DBG1(DBG_APP, "!! http://wiki.strongswan.org/projects/strongswan/wiki/PluginLoad"); } } /* verify that we can start */ if (getuid() != 0) { DBG1(DBG_APP, "permission denied (must be superuser)"); cleanup(); exit(LSB_RC_NOT_ALLOWED); } if (check_pid(pid_file)) { DBG1(DBG_APP, "%s is already running (%s exists) -- skipping daemon start", daemon_name, pid_file); } else { _action_ |= FLAG_ACTION_START_CHARON; } if (stat(DEV_RANDOM, &stb) != 0) { DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_RANDOM); cleanup(); exit(LSB_RC_FAILURE); } if (stat(DEV_URANDOM, &stb)!= 0) { DBG1(DBG_APP, "unable to start strongSwan IPsec -- no %s!", DEV_URANDOM); cleanup(); exit(LSB_RC_FAILURE); } cfg = confread_load(CONFIG_FILE); if (cfg == NULL || cfg->err > 0) { DBG1(DBG_APP, "unable to start strongSwan -- fatal errors in config"); if (cfg) { confread_free(cfg); } cleanup(); exit(LSB_RC_INVALID_ARGUMENT); } /* determine if we have a native netkey IPsec stack */ if (!starter_netkey_init()) { DBG1(DBG_APP, "no netkey IPsec stack detected"); if (!starter_klips_init()) { DBG1(DBG_APP, "no KLIPS IPsec stack detected"); DBG1(DBG_APP, "no known IPsec stack detected, ignoring!"); } } last_reload = time_monotonic(NULL); if (check_pid(starter_pid_file)) { DBG1(DBG_APP, "starter is already running (%s exists) -- no fork done", starter_pid_file); confread_free(cfg); cleanup(); exit(LSB_RC_SUCCESS); } #ifdef GENERATE_SELFCERT generate_selfcert(); #endif /* fork if we're not debugging stuff */ if (!no_fork) { log_to_stderr = FALSE; switch (fork()) { case 0: { int fnull; close_log(); closefrom(3); fnull = open("/dev/null", O_RDWR); if (fnull >= 0) { dup2(fnull, STDIN_FILENO); dup2(fnull, STDOUT_FILENO); dup2(fnull, STDERR_FILENO); close(fnull); } setsid(); init_log("ipsec_starter"); } break; case -1: DBG1(DBG_APP, "can't fork: %s", strerror(errno)); break; default: confread_free(cfg); cleanup(); exit(LSB_RC_SUCCESS); } } /* save pid file in /var/run/starter[.daemon_name].pid */ { FILE *fd = fopen(starter_pid_file, "w"); if (fd) { fprintf(fd, "%u\n", getpid()); fclose(fd); } } /* we handle these signals only in pselect() */ memset(&action, 0, sizeof(action)); sigemptyset(&action.sa_mask); sigaddset(&action.sa_mask, SIGHUP); sigaddset(&action.sa_mask, SIGINT); sigaddset(&action.sa_mask, SIGTERM); sigaddset(&action.sa_mask, SIGQUIT); sigaddset(&action.sa_mask, SIGALRM); sigaddset(&action.sa_mask, SIGUSR1); pthread_sigmask(SIG_SETMASK, &action.sa_mask, NULL); /* install a handler for fatal signals */ action.sa_handler = fatal_signal_handler; sigaction(SIGSEGV, &action, NULL); sigaction(SIGILL, &action, NULL); sigaction(SIGBUS, &action, NULL); action.sa_handler = SIG_IGN; sigaction(SIGPIPE, &action, NULL); /* install main signal handler */ action.sa_handler = signal_handler; sigaction(SIGHUP, &action, NULL); sigaction(SIGINT, &action, NULL); sigaction(SIGTERM, &action, NULL); sigaction(SIGQUIT, &action, NULL); sigaction(SIGALRM, &action, NULL); sigaction(SIGUSR1, &action, NULL); /* this is not blocked above as we want to receive it asynchronously */ sigaction(SIGCHLD, &action, NULL); /* empty mask for pselect() call below */ sigemptyset(&action.sa_mask); for (;;) { /* * Stop charon (if started) and exit */ if (_action_ & FLAG_ACTION_QUIT) { if (starter_charon_pid()) { starter_stop_charon(); } starter_netkey_cleanup(); confread_free(cfg); unlink(starter_pid_file); cleanup(); DBG1(DBG_APP, "ipsec starter stopped"); close_log(); exit(LSB_RC_SUCCESS); } /* * Delete all connections. Will be added below */ if (_action_ & FLAG_ACTION_RELOAD) { if (starter_charon_pid()) { for (conn = cfg->conn_first; conn; conn = conn->next) { if (conn->state == STATE_ADDED) { if (starter_charon_pid()) { if (conn->startup == STARTUP_ROUTE) { starter_stroke_unroute_conn(conn); } starter_stroke_del_conn(conn); } conn->state = STATE_TO_ADD; } } for (ca = cfg->ca_first; ca; ca = ca->next) { if (ca->state == STATE_ADDED) { if (starter_charon_pid()) { starter_stroke_del_ca(ca); } ca->state = STATE_TO_ADD; } } } _action_ &= ~FLAG_ACTION_RELOAD; } /* * Update configuration */ if (_action_ & FLAG_ACTION_UPDATE) { DBG2(DBG_APP, "Reloading config..."); new_cfg = confread_load(CONFIG_FILE); if (new_cfg && (new_cfg->err == 0)) { /* Switch to new config. New conn will be loaded below */ /* Look for new connections that are already loaded */ for (conn = cfg->conn_first; conn; conn = conn->next) { if (conn->state == STATE_ADDED) { for (conn2 = new_cfg->conn_first; conn2; conn2 = conn2->next) { if (conn2->state == STATE_TO_ADD && starter_cmp_conn(conn, conn2)) { conn->state = STATE_REPLACED; conn2->state = STATE_ADDED; conn2->id = conn->id; break; } } } } /* Remove conn sections that have become unused */ for (conn = cfg->conn_first; conn; conn = conn->next) { if (conn->state == STATE_ADDED) { if (starter_charon_pid()) { if (conn->startup == STARTUP_ROUTE) { starter_stroke_unroute_conn(conn); } starter_stroke_del_conn(conn); } } } /* Look for new ca sections that are already loaded */ for (ca = cfg->ca_first; ca; ca = ca->next) { if (ca->state == STATE_ADDED) { for (ca2 = new_cfg->ca_first; ca2; ca2 = ca2->next) { if (ca2->state == STATE_TO_ADD && starter_cmp_ca(ca, ca2)) { ca->state = STATE_REPLACED; ca2->state = STATE_ADDED; break; } } } } /* Remove ca sections that have become unused */ for (ca = cfg->ca_first; ca; ca = ca->next) { if (ca->state == STATE_ADDED) { if (starter_charon_pid()) { starter_stroke_del_ca(ca); } } } confread_free(cfg); cfg = new_cfg; } else { DBG1(DBG_APP, "can't reload config file due to errors -- keeping old one"); if (new_cfg) { confread_free(new_cfg); } } _action_ &= ~FLAG_ACTION_UPDATE; last_reload = time_monotonic(NULL); } /* * Start daemon */ if (_action_ & FLAG_ACTION_START_CHARON) { if (cfg->setup.charonstart && !starter_charon_pid()) { DBG2(DBG_APP, "Attempting to start %s...", daemon_name); if (starter_start_charon(cfg, no_fork, attach_gdb)) { /* schedule next try */ alarm(CHARON_RESTART_DELAY); } starter_stroke_configure(cfg); } _action_ &= ~FLAG_ACTION_START_CHARON; for (ca = cfg->ca_first; ca; ca = ca->next) { if (ca->state == STATE_ADDED) { ca->state = STATE_TO_ADD; } } for (conn = cfg->conn_first; conn; conn = conn->next) { if (conn->state == STATE_ADDED) { conn->state = STATE_TO_ADD; } } } /* * Add stale conn and ca sections */ if (starter_charon_pid()) { for (ca = cfg->ca_first; ca; ca = ca->next) { if (ca->state == STATE_TO_ADD) { if (starter_charon_pid()) { starter_stroke_add_ca(ca); } ca->state = STATE_ADDED; } } for (conn = cfg->conn_first; conn; conn = conn->next) { if (conn->state == STATE_TO_ADD) { if (conn->id == 0) { /* affect new unique id */ conn->id = id++; } if (starter_charon_pid()) { starter_stroke_add_conn(cfg, conn); } conn->state = STATE_ADDED; if (conn->startup == STARTUP_START) { if (starter_charon_pid()) { starter_stroke_initiate_conn(conn); } } else if (conn->startup == STARTUP_ROUTE) { if (starter_charon_pid()) { starter_stroke_route_conn(conn); } } } } } /* * If auto_update activated, when to stop select */ if (auto_update) { time_t now = time_monotonic(NULL); ts.tv_sec = (now < last_reload + auto_update) ? (last_reload + auto_update - now) : 0; ts.tv_nsec = 0; } /* * Wait for something to happen */ if (!_action_ && pselect(0, NULL, NULL, NULL, auto_update ? &ts : NULL, &action.sa_mask) == 0) { /* timeout -> auto_update */ _action_ |= FLAG_ACTION_UPDATE; } } exit(LSB_RC_SUCCESS); }