void exclude_file_name(char path[]) { if(path_exists(path, DEREF) && !is_valid_dir(path)) { remove_last_path_component(path); } }
int show_history_menu(FileView *view) { int i; static menu_info m; init_menu_info(&m, DIRHISTORY, strdup("History disabled or empty")); m.title = strdup(" Directory History "); for(i = 0; i < view->history_num && i < cfg.history_len; i++) { int j; if(view->history[i].dir[0] == '\0') break; for(j = i + 1; j < view->history_num && j < cfg.history_len; j++) if(stroscmp(view->history[i].dir, view->history[j].dir) == 0) break; if(j < view->history_num && j < cfg.history_len) continue; if(!is_valid_dir(view->history[i].dir)) continue; /* Change the current dir to reflect the current file. */ if(stroscmp(view->history[i].dir, view->curr_dir) == 0) { (void)replace_string(&view->history[i].file, view->dir_entry[view->list_pos].name); m.pos = m.len; } m.len = add_to_string_array(&m.items, m.len, 1, view->history[i].dir); } /* Reverse order in which items appear. */ for(i = 0; i < m.len/2; i++) { char *t = m.items[i]; m.items[i] = m.items[m.len - 1 - i]; m.items[m.len - 1 - i] = t; } m.pos = m.len - 1 - m.pos; return display_menu(&m, view); }
/* Read and parse the access file, popluating the access data as we go. */ void parse_access_file(fko_srv_options_t *opts) { FILE *file_ptr; char *ndx; int got_source = 0; unsigned int num_lines = 0; char access_line_buf[MAX_LINE_LEN] = {0}; char var[MAX_LINE_LEN] = {0}; char val[MAX_LINE_LEN] = {0}; struct passwd *pw; struct stat st; acc_stanza_t *curr_acc = NULL; /* First see if the access file exists. If it doesn't, complain * and bail. */ if(stat(opts->config[CONF_ACCESS_FILE], &st) != 0) { fprintf(stderr, "[*] Access file: '%s' was not found.\n", opts->config[CONF_ACCESS_FILE]); exit(EXIT_FAILURE); } if ((file_ptr = fopen(opts->config[CONF_ACCESS_FILE], "r")) == NULL) { fprintf(stderr, "[*] Could not open access file: %s\n", opts->config[CONF_ACCESS_FILE]); perror(NULL); exit(EXIT_FAILURE); } /* Initialize the access list. */ acc_stanza_init(opts); /* Now walk through access file pulling the access entries into the * current stanza. */ while ((fgets(access_line_buf, MAX_LINE_LEN, file_ptr)) != NULL) { num_lines++; access_line_buf[MAX_LINE_LEN-1] = '\0'; /* Get past comments and empty lines (note: we only look at the * first character. */ if(IS_EMPTY_LINE(access_line_buf[0])) continue; if(sscanf(access_line_buf, "%s %[^;\n\r]", var, val) != 2) { fprintf(stderr, "*Invalid access file entry in %s at line %i.\n - '%s'", opts->config[CONF_ACCESS_FILE], num_lines, access_line_buf ); continue; } /* Remove any colon that may be on the end of the var */ if((ndx = strrchr(var, ':')) != NULL) *ndx = '\0'; /* */ if(opts->verbose > 3) fprintf(stderr, "ACCESS FILE: %s, LINE: %s\tVar: %s, Val: '%s'\n", opts->config[CONF_ACCESS_FILE], access_line_buf, var, val ); /* Process the entry. * * NOTE: If a new access.conf parameter is created. It also needs * to be accounted for in the following if/if else construct. */ if(CONF_VAR_IS(var, "SOURCE")) { /* If this is not the first stanza, sanity check the previous * stanza for the minimum required data. */ if(curr_acc != NULL) { if(!acc_data_is_valid(curr_acc)) { fprintf(stderr, "[*] Data error in access file: '%s'\n", opts->config[CONF_ACCESS_FILE]); exit(EXIT_FAILURE); } } /* Start new stanza. */ curr_acc = acc_stanza_add(opts); add_acc_string(&(curr_acc->source), val); got_source++; } else if (curr_acc == NULL) { /* The stanza must start with the "SOURCE" variable */ continue; } else if(CONF_VAR_IS(var, "OPEN_PORTS")) { add_acc_string(&(curr_acc->open_ports), val); } else if(CONF_VAR_IS(var, "RESTRICT_PORTS")) { add_acc_string(&(curr_acc->restrict_ports), val); } else if(CONF_VAR_IS(var, "KEY")) { if(strcasecmp(val, "__CHANGEME__") == 0) { fprintf(stderr, "[*] KEY value is not properly set in stanza source '%s' in access file: '%s'\n", curr_acc->source, opts->config[CONF_ACCESS_FILE]); exit(EXIT_FAILURE); } add_acc_string(&(curr_acc->key), val); } else if(CONF_VAR_IS(var, "FW_ACCESS_TIMEOUT")) { add_acc_int(&(curr_acc->fw_access_timeout), val); } else if(CONF_VAR_IS(var, "ENABLE_CMD_EXEC")) { add_acc_bool(&(curr_acc->enable_cmd_exec), val); } else if(CONF_VAR_IS(var, "CMD_EXEC_USER")) { add_acc_string(&(curr_acc->cmd_exec_user), val); errno = 0; pw = getpwnam(val); if(pw == NULL) { fprintf(stderr, "Unable to determine UID for CMD_EXEC_USER: %s.\n", errno ? strerror(errno) : "Not a user on this system"); exit(EXIT_FAILURE); } curr_acc->cmd_exec_uid = pw->pw_uid; } else if(CONF_VAR_IS(var, "REQUIRE_USERNAME")) { add_acc_string(&(curr_acc->require_username), val); } else if(CONF_VAR_IS(var, "REQUIRE_SOURCE_ADDRESS")) { add_acc_bool(&(curr_acc->require_source_address), val); } else if(CONF_VAR_IS(var, "GPG_HOME_DIR")) { if (is_valid_dir(val)) { add_acc_string(&(curr_acc->gpg_home_dir), val); } else { fprintf(stderr, "[*] GPG_HOME_DIR directory '%s' stat()/existence problem in stanza source '%s' in access file: '%s'\n", val, curr_acc->source, opts->config[CONF_ACCESS_FILE]); exit(EXIT_FAILURE); } } else if(CONF_VAR_IS(var, "GPG_DECRYPT_ID")) { add_acc_string(&(curr_acc->gpg_decrypt_id), val); } else if(CONF_VAR_IS(var, "GPG_DECRYPT_PW")) { if(strcasecmp(val, "__CHANGEME__") == 0) { fprintf(stderr, "[*] GPG_DECRYPT_PW value is not properly set in stanza source '%s' in access file: '%s'\n", curr_acc->source, opts->config[CONF_ACCESS_FILE]); exit(EXIT_FAILURE); } add_acc_string(&(curr_acc->gpg_decrypt_pw), val); } else if(CONF_VAR_IS(var, "GPG_REQUIRE_SIG")) { add_acc_bool(&(curr_acc->gpg_require_sig), val); } else if(CONF_VAR_IS(var, "GPG_IGNORE_SIG_VERIFY_ERROR")) { add_acc_bool(&(curr_acc->gpg_ignore_sig_error), val); } else if(CONF_VAR_IS(var, "GPG_REMOTE_ID")) { add_acc_string(&(curr_acc->gpg_remote_id), val); } else { fprintf(stderr, "*Ignoring unknown access parameter: '%s' in %s\n", var, opts->config[CONF_ACCESS_FILE] ); } } fclose(file_ptr); /* Basic check to ensure that we got at least one SOURCE stanza with * a valid KEY defined (valid meaning it has a value that is not * "__CHANGEME__". */ if (got_source == 0) { fprintf(stderr, "[*] Could not find valid SOURCE stanza in access file: '%s'\n", opts->config[CONF_ACCESS_FILE]); exit(EXIT_FAILURE); } /* Sanity check the last stanza */ if(!acc_data_is_valid(curr_acc)) { fprintf(stderr, "[*] Data error in access file: '%s'\n", opts->config[CONF_ACCESS_FILE]); exit(EXIT_FAILURE); } /* Expand our the expandable fields into their respective data buckets. */ expand_acc_ent_lists(opts); /* Make sure default values are set where needed. * a default value. */ set_acc_defaults(opts); return; }
/* Checks if a bookmark is valid (exists and points to an existing directory). * For convenience bmark can be NULL. Returns non-zero if so, otherwise zero is * returned. */ static int is_bmark_valid(const bookmark_t *bmark) { return !is_bmark_empty(bmark) && is_valid_dir(bmark->directory); }
/* Initialize program configuration via config file and/or command-line * switches. */ void config_init(fko_srv_options_t *opts, int argc, char **argv) { int cmd_arg, index, is_err; unsigned char got_conf_file = 0, got_override_config = 0; char override_file[MAX_LINE_LEN] = {0}; char *ndx, *cmrk; /* Zero out options and opts_track. */ memset(opts, 0x00, sizeof(fko_srv_options_t)); /* Set some preconfiguration options (i.e. build-time defaults) */ set_preconfig_entries(opts); /* In case this is a re-config. */ optind = 0; /* First, scan the command-line args for -h/--help or an alternate * configuration file. If we find an alternate config file, use it, * otherwise use the default. We also grab any override config files * as well. */ while ((cmd_arg = getopt_long(argc, argv, GETOPTS_OPTION_STRING, cmd_opts, &index)) != -1) { /* If help is wanted, give it and exit. */ switch(cmd_arg) { case 'h': usage(); clean_exit(opts, NO_FW_CLEANUP, EXIT_SUCCESS); break; /* Look for configuration file arg. */ case 'c': set_config_entry(opts, CONF_CONFIG_FILE, optarg); got_conf_file++; /* If we already have the config_override option, we are done. */ if(got_override_config > 0) break; /* Look for override configuration file arg. */ case 'O': set_config_entry(opts, CONF_OVERRIDE_CONFIG, optarg); got_override_config++; /* If we already have the conf_file option, we are done. */ if(got_conf_file > 0) break; } } /* If no alternate configuration file was specified, we use the * default. */ if(opts->config[CONF_CONFIG_FILE] == NULL) set_config_entry(opts, CONF_CONFIG_FILE, DEF_CONFIG_FILE); /* Parse configuration file to populate any params not already specified * via command-line options. */ parse_config_file(opts, opts->config[CONF_CONFIG_FILE]); /* If there are override configuration entries, process them * here. */ if(opts->config[CONF_OVERRIDE_CONFIG] != NULL) { /* Make a copy of the override_config string so we can munge it. */ strlcpy(override_file, opts->config[CONF_OVERRIDE_CONFIG], sizeof(override_file)); ndx = override_file; cmrk = strchr(ndx, ','); if(cmrk == NULL) { /* Only one to process... */ parse_config_file(opts, ndx); } else { /* Walk the string pulling the next config override * at the comma delimiters. */ while(cmrk != NULL) { *cmrk = '\0'; parse_config_file(opts, ndx); ndx = cmrk + 1; cmrk = strchr(ndx, ','); } /* Process the last entry */ parse_config_file(opts, ndx); } } /* Set up the verbosity level according to the value found in the * config files */ if (opts->config[CONF_VERBOSE] != NULL) { opts->verbose = strtol_wrapper(opts->config[CONF_VERBOSE], 0, -1, NO_EXIT_UPON_ERR, &is_err); if(is_err != FKO_SUCCESS) { log_msg(LOG_ERR, "[*] VERBOSE value '%s' not in the range (>0)", opts->config[CONF_VERBOSE]); clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE); } } /* Reset the options index so we can run through them again. */ optind = 0; /* Last, but not least, we process command-line options (some of which * may override configuration file options. */ while ((cmd_arg = getopt_long(argc, argv, GETOPTS_OPTION_STRING, cmd_opts, &index)) != -1) { switch(cmd_arg) { case 'a': set_config_entry(opts, CONF_ACCESS_FILE, optarg); break; case 'c': /* This was handled earlier */ break; case 'C': opts->packet_ctr_limit = strtol_wrapper(optarg, 0, (2 << 30), NO_EXIT_UPON_ERR, &is_err); if(is_err != FKO_SUCCESS) { log_msg(LOG_ERR, "[*] invalid -C packet count limit '%s'", optarg); clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE); } break; case 'd': #if USE_FILE_CACHE set_config_entry(opts, CONF_DIGEST_FILE, optarg); #else set_config_entry(opts, CONF_DIGEST_DB_FILE, optarg); #endif break; case 'D': opts->dump_config = 1; break; case 'f': opts->foreground = 1; break; case FW_LIST: opts->fw_list = 1; break; case FW_LIST_ALL: opts->fw_list = 1; opts->fw_list_all = 1; break; case FW_FLUSH: opts->fw_flush = 1; break; case GPG_HOME_DIR: if (is_valid_dir(optarg)) { set_config_entry(opts, CONF_GPG_HOME_DIR, optarg); } else { log_msg(LOG_ERR, "[*] Directory '%s' could not stat()/does not exist?", optarg); clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE); } break; case 'i': set_config_entry(opts, CONF_PCAP_INTF, optarg); break; case 'K': opts->kill = 1; break; case 'l': set_config_entry(opts, CONF_LOCALE, optarg); break; case 'O': /* This was handled earlier */ break; case 'p': set_config_entry(opts, CONF_FWKNOP_PID_FILE, optarg); break; case 'P': set_config_entry(opts, CONF_PCAP_FILTER, optarg); break; case PCAP_FILE: set_config_entry(opts, CONF_PCAP_FILE, optarg); break; case ENABLE_PCAP_ANY_DIRECTION: opts->pcap_any_direction = 1; break; case ROTATE_DIGEST_CACHE: opts->rotate_digest_cache = 1; break; case 'R': opts->restart = 1; break; case 'S': opts->status = 1; break; /* Verbosity level */ case 'v': opts->verbose++; break; case SYSLOG_ENABLE: opts->syslog_enable = 1; break; case 'V': fprintf(stdout, "fwknopd server %s\n", MY_VERSION); clean_exit(opts, NO_FW_CLEANUP, EXIT_SUCCESS); break; default: usage(); clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE); } } /* Now that we have all of our options set, and we are actually going to * start fwknopd, we can validate them. */ validate_options(opts); return; }
/* Checks if a mark is valid (exists and points to an existing directory). For * convenience mark can be NULL. Returns non-zero if so, otherwise zero is * returned. */ static int is_mark_valid(const mark_t *mark) { return !is_empty(mark) && is_valid_dir(mark->directory); }
void exclude_file_name(char *path) { if(path_exists(path) && !is_valid_dir(path)) remove_last_path_component(path); }