예제 #1
0
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);
}
예제 #2
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;
}
예제 #3
0
파일: addconn.c 프로젝트: saaros/libreswan
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;
			}
		}
예제 #4
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';
	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);
}
예제 #5
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);
}
예제 #6
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);
}
예제 #7
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);
}
예제 #8
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);
	    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);
}
예제 #9
0
파일: starter.c 프로젝트: agimsn/strongswan
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);
}