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);
}
Beispiel #2
0
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;
			}
		}
Beispiel #3
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);
}