/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_n_netopeer_n_tls_n_trusted_ca_certs_n_trusted_ca_cert(void** UNUSED(data), XMLDIFF_OP op, xmlNodePtr old_node, xmlNodePtr new_node, struct nc_err** error) { char* content = NULL; if (op & (XMLDIFF_REM | XMLDIFF_MOD)) { content = get_node_content(old_node); if (content == NULL) { *error = nc_err_new(NC_ERR_OP_FAILED); nc_verb_error("%s: node content missing", __func__); return EXIT_FAILURE; } /* TLS_CTX LOCK */ pthread_mutex_lock(&netopeer_options.tls_opts->tls_ctx_lock); if (del_trusted_cert(&netopeer_options.tls_opts->trusted_certs, content, 0) != 0) { nc_verb_error("%s: inconsistent state (%s:%d)", __func__, __FILE__, __LINE__); } else { netopeer_options.tls_opts->tls_ctx_change_flag = 1; } /* TLS_CTX UNLOCK */ pthread_mutex_unlock(&netopeer_options.tls_opts->tls_ctx_lock); } if (op & (XMLDIFF_MOD | XMLDIFF_ADD)) { content = get_node_content(new_node); if (content == NULL) { *error = nc_err_new(NC_ERR_OP_FAILED); nc_verb_error("%s: node content missing", __func__); return EXIT_FAILURE; } /* TLS_CTX LOCK */ pthread_mutex_lock(&netopeer_options.tls_opts->tls_ctx_lock); add_trusted_cert(&netopeer_options.tls_opts->trusted_certs, content, 0); netopeer_options.tls_opts->tls_ctx_change_flag = 1; /* TLS_CTX UNLOCK */ pthread_mutex_unlock(&netopeer_options.tls_opts->tls_ctx_lock); } return EXIT_SUCCESS; }
int main(int argc, char **argv) { int ret = EXIT_FAILURE; struct vpn_config cfg; char *config_file = "/etc/openfortivpn/config"; char *host, *username = NULL, *password = NULL; char *port_str; long int port; init_logging(); // Set defaults init_vpn_config(&cfg); cfg.set_routes = 1; cfg.set_dns = 1; cfg.verify_cert = 1; cfg.insecure_ssl = 0; cfg.pppd_use_peerdns = 1; struct option long_options[] = { {"help", no_argument, 0, 'h'}, {"version", no_argument, 0, 0}, {"config", required_argument, 0, 'c'}, {"realm", required_argument, 0, 0}, {"username", required_argument, 0, 'u'}, {"password", required_argument, 0, 'p'}, {"no-routes", no_argument, &cfg.set_routes, 0}, {"no-dns", no_argument, &cfg.set_dns, 0}, {"pppd-no-peerdns", no_argument, &cfg.pppd_use_peerdns, 0}, {"ca-file", required_argument, 0, 0}, {"user-cert", required_argument, 0, 0}, {"user-key", required_argument, 0, 0}, {"trusted-cert", required_argument, 0, 0}, {"insecure-ssl", no_argument, &cfg.insecure_ssl, 1}, {"cipher-list", required_argument, 0, 0}, {"pppd-log", required_argument, 0, 0}, {"pppd-plugin", required_argument, 0, 0}, {"plugin", required_argument, 0, 0}, // deprecated {0, 0, 0, 0} }; while (1) { /* getopt_long stores the option index here. */ int c, option_index = 0; c = getopt_long(argc, argv, "hvqc:u:p:", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; switch (c) { case 0: /* If this option set a flag, do nothing else now. */ if (long_options[option_index].flag != 0) break; if (strcmp(long_options[option_index].name, "version") == 0) { printf(VERSION "\n"); ret = EXIT_SUCCESS; goto exit; } if (strcmp(long_options[option_index].name, "pppd-log") == 0) { cfg.pppd_log = optarg; break; } if (strcmp(long_options[option_index].name, "pppd-plugin") == 0) { cfg.pppd_plugin = optarg; break; } // --plugin is deprecated, --pppd-plugin should be used if (cfg.pppd_plugin == NULL && strcmp(long_options[option_index].name, "plugin") == 0) { cfg.pppd_plugin = optarg; break; } if (strcmp(long_options[option_index].name, "ca-file") == 0) { cfg.ca_file = strdup(optarg); break; } if (strcmp(long_options[option_index].name, "user-cert") == 0) { cfg.user_cert = strdup(optarg); break; } if (strcmp(long_options[option_index].name, "user-key") == 0) { cfg.user_key = strdup(optarg); break; } if (strcmp(long_options[option_index].name, "realm") == 0) { strncpy(cfg.realm, optarg, FIELD_SIZE); cfg.realm[FIELD_SIZE] = '\0'; break; } if (strcmp(long_options[option_index].name, "trusted-cert") == 0) { if (add_trusted_cert(&cfg, optarg)) log_warn("Could not add certificate " "digest to whitelist.\n"); break; } if (strcmp(long_options[option_index].name, "cipher-list") == 0) { cfg.cipher_list = strdup(optarg); break; } goto user_error; case 'h': printf(HELP); ret = EXIT_SUCCESS; goto exit; case 'v': increase_verbosity(); break; case 'q': decrease_verbosity(); break; case 'c': config_file = optarg; break; case 'u': username = optarg; break; case 'p': password = optarg; break; default: goto user_error; } } if (optind < argc - 1 || optind > argc) goto user_error; if (password != NULL) log_warn("You should not pass the password on the command " "line. Type it interactively or use a config file " "instead.\n"); // Load config file if (config_file[0] != '\0') { ret = load_config(&cfg, config_file); if (ret == 0) log_debug("Loaded config file \"%s\".\n", config_file); else log_warn("Could not load config file \"%s\" (%s).\n", config_file, err_cfg_str(ret)); } // Read host and port from the command line if (optind == argc - 1) { host = argv[optind++]; port_str = strchr(host, ':'); if (port_str == NULL) { log_error("Specify a valid host:port couple.\n"); goto user_error; } port_str[0] = '\0'; strncpy(cfg.gateway_host, host, FIELD_SIZE); cfg.gateway_host[FIELD_SIZE] = '\0'; port_str++; port = strtol(port_str, NULL, 0); if (port <= 0 || port > 65535) { log_error("Specify a valid port.\n"); goto user_error; } cfg.gateway_port = port; } // Read username and password from the command line if (username != NULL) { strncpy(cfg.username, username, FIELD_SIZE); cfg.username[FIELD_SIZE] = '\0'; } if (password != NULL) { strncpy(cfg.password, password, FIELD_SIZE); cfg.password[FIELD_SIZE] = '\0'; } // Check host and port if (cfg.gateway_host[0] == '\0' || cfg.gateway_port == 0) { log_error("Specify a valid host:port couple.\n"); goto user_error; } // Check username if (cfg.username[0] == '\0') { log_error("Specify an username.\n"); goto user_error; } // If no password given, interactively ask user if (cfg.password[0] == '\0') read_password("VPN account password: "******"Specify a password.\n"); goto user_error; } log_debug("Config host = \"%s\"\n", cfg.gateway_host); log_debug("Config realm = \"%s\"\n", cfg.realm); log_debug("Config port = \"%d\"\n", cfg.gateway_port); log_debug("Config username = \"%s\"\n", cfg.username); log_debug("Config password = \"%s\"\n", "********"); if (geteuid() != 0) log_warn("This process was not spawned with root " "privileges, this will probably not work.\n"); if (run_tunnel(&cfg) == 0) ret = EXIT_SUCCESS; goto exit; user_error: fprintf(stderr, USAGE); exit: destroy_vpn_config(&cfg); exit(ret); }