Added more server command-line and config file processing code. Updated autoconf config for new checks and files.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@138 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart
2009-09-05 02:54:42 +00:00
parent 791eb4055b
commit 998fe8da0a
6 changed files with 319 additions and 146 deletions
+5
View File
@@ -1,3 +1,5 @@
fwknopddir = @sysconfdir@/fwknop
sbin_PROGRAMS = fwknopd
fwknopd_SOURCES = fwknopd.c fwknopd.h config_init.c config_init.h \
@@ -10,3 +12,6 @@ if HAVE_LIBPCAP
endif
fwknopd_CPPFLAGS = -I $(top_srcdir)/lib -I $(top_srcdir)/common
dist_fwknopd_DATA = fwknopd.conf
+96 -69
View File
@@ -29,86 +29,77 @@
#include "utils.h"
#include "ctype.h"
/* Routine to extract the configuration value from a line in the config
* file.
/* Take an index and a string value. malloc the space for the value
* and assign it to the array at the specified index.
*/
int
get_char_val(const char *var_name, char *dest, char *lptr)
void
set_config_entry(fko_srv_options_t *opts, int var_ndx, char *value)
{
int i, var_char_ctr = 0;
char *tmp_ptr;
int slen;
tmp_ptr = lptr;
/* var_name is guaranteed to be NULL-terminated.
/* Sanity check the index value.
*/
for (i=0; i < (int)strlen(var_name); i++)
if (tmp_ptr[i] != var_name[i])
return 0;
if(var_ndx < 0 || var_ndx >= NUMBER_OF_CONFIG_ENTRIES)
{
fprintf(stderr, "Index value of %i is not valid\n", var_ndx);
exit(EXIT_FAILURE);
}
tmp_ptr += i;
/* First char after varName better be a space or tab or '='.
/* Make sure we have a valid value.
*/
if (*tmp_ptr != ' ' && *tmp_ptr != '\t' && *tmp_ptr != '=')
return 0;
if(value == NULL)
{
fprintf(stderr, "Config value for index %i was NULL\n", var_ndx);
exit(EXIT_FAILURE);
}
/* Walk past the delimiter.
*/
while (*tmp_ptr == ' ' || *tmp_ptr == '\t' || *tmp_ptr == '=')
tmp_ptr++;
slen = strlen(value) + 1;
while (var_char_ctr < MAX_LINE_LEN && tmp_ptr[var_char_ctr] != '\n'
&& tmp_ptr[var_char_ctr] != '\0')
var_char_ctr++;
opts->config_ent[var_ndx] = malloc(slen);
if (tmp_ptr[var_char_ctr] != '\n' || var_char_ctr >= MAX_LINE_LEN)
return 0;
if(opts->config_ent[var_ndx] == NULL)
{
fprintf(stderr, "*Fatal memory allocation error!\n");
exit(EXIT_FAILURE);
}
strncpy(dest, tmp_ptr, var_char_ctr);
dest[var_char_ctr] = '\0';
return 1;
strlcpy(opts->config_ent[var_ndx], value, slen);
return;
}
/* Parse the config file...
*/
static void
parse_config_file(fko_svr_options_t *options, opts_track_t *ot)
parse_config_file(fko_srv_options_t *options, opts_track_t *ot)
{
FILE *cfile_ptr;
unsigned int numLines = 0;
unsigned int i, good_ent;
char conf_line_buf[MAX_LINE_LEN] = {0};
char tmp_char_buf[MAX_LINE_LEN] = {0};
char *lptr;
char var[MAX_LINE_LEN] = {0};
char val[MAX_LINE_LEN] = {0};
struct stat st;
* First see if the config file exists. If it doesn't, and was
* specified via command-line, then error out. Otherwise, complain
/* First see if the config file exists. If it doesn't, complain
* and go on with program defaults.
*
if(stat(options->config_file, &st) != 0)
*/
if(stat(options->config_ent[CONF_CONFIG_FILE], &st) != 0)
{
if(ot->got_config_file)
{
fprintf(stderr, "[*] Could not open config file: %s\n",
options->config_file);
exit(EXIT_FAILURE);
}
fprintf(stderr,
"** Config file was not found. Attempting to continue with defaults...\n"
"** Config file: '%s' was not found. Attempting to continue with defaults...\n",
options->config_ent[CONF_CONFIG_FILE]
);
return;
}
if ((cfile_ptr = fopen(options->config_file, "r")) == NULL)
if ((cfile_ptr = fopen(options->config_ent[CONF_CONFIG_FILE], "r")) == NULL)
{
fprintf(stderr, "[*] Could not open config file: %s\n",
options->config_file);
options->config_ent[CONF_CONFIG_FILE]);
exit(EXIT_FAILURE);
}
@@ -116,24 +107,45 @@ parse_config_file(fko_svr_options_t *options, opts_track_t *ot)
{
numLines++;
conf_line_buf[MAX_LINE_LEN-1] = '\0';
lptr = conf_line_buf;
memset(tmp_char_buf, 0x0, MAX_LINE_LEN);
while (*lptr == ' ' || *lptr == '\t' || *lptr == '=')
lptr++;
* Get past comments and empty lines.
*
if (*lptr == '#' || *lptr == '\n' || *lptr == '\r' || *lptr == '\0' || *lptr == ';')
/* Get past comments and empty lines (note: we only look at the
* first character.
*/
if(IS_EMPTY_LINE(conf_line_buf[0]))
continue;
if(sscanf(conf_line_buf, "%s %[^;\n\r]", var, val) != 2)
{
fprintf(stderr,
"*Invalid config file entry at line %i.\n - '%s'",
numLines, conf_line_buf
);
continue;
}
/*
fprintf(stderr, "LINE: %s\tVar: %s, Val: '%s'\n", conf_line_buf, var, val);
*/
good_ent = 0;
for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
{
if(CONF_VAR_IS(config_ent_map[i], var))
{
set_config_entry(options, i, val);
good_ent++;
break;
}
}
if(good_ent == 0)
fprintf(stderr, "*Ignoring unknown configuration parameter: '%s'\n");
}
fclose(cfile_ptr);
return;
}
*/
/* Sanity and bounds checks for the various options.
*/
@@ -168,13 +180,10 @@ config_init(fko_srv_options_t *options, int argc, char **argv)
switch(cmd_arg) {
case 'c':
strlcpy(options->config_file, optarg, MAX_PATH_LEN);
set_config_entry(options, CONF_CONFIG_FILE, optarg);
break;
case 'D':
fprintf(stderr, "*NOT IMPLEMENTED YET*\n");
// TODO: Add this...
//dump_config();
exit(EXIT_SUCCESS);
options->dump_config = 1;
break;
case FIREWALL_LIST:
fprintf(stderr, "*NOT IMPLEMENTED YET*\n");
@@ -189,20 +198,20 @@ config_init(fko_srv_options_t *options, int argc, char **argv)
exit(EXIT_SUCCESS);
break;
case FIREWALL_LOG:
strlcpy(options->firewall_log, optarg, MAX_PATH_LEN);
set_config_entry(options, FIREWALL_LOG, optarg);
break;
case GPG_HOME_DIR:
strlcpy(options->gpg_home_dir, optarg, MAX_PATH_LEN);
set_config_entry(options, GPG_HOME_DIR, optarg);
break;
case GPG_KEY:
strlcpy(options->gpg_key, optarg, MAX_GPG_KEY_ID);
set_config_entry(options, GPG_KEY, optarg);
break;
case 'h':
usage();
exit(EXIT_SUCCESS);
break;
case 'i':
strlcpy(options->net_interface, optarg, MAX_PATH_LEN);
set_config_entry(options, CONF_PCAP_INTF, optarg);
break;
case 'K':
fprintf(stderr, "*NOT IMPLEMENTED YET*\n");
@@ -211,7 +220,7 @@ config_init(fko_srv_options_t *options, int argc, char **argv)
exit(EXIT_SUCCESS);
break;
case 'O':
strlcpy(options->override_config, optarg, MAX_PATH_LEN);
set_config_entry(options, CONF_OVERRIDE_CONFIG, optarg);
break;
case 'R':
fprintf(stderr, "*NOT IMPLEMENTED YET*\n");
@@ -241,7 +250,7 @@ config_init(fko_srv_options_t *options, int argc, char **argv)
/* Parse configuration file to populate any params not already specified
* via command-line options
*/
//parse_config_file(options, &ot);
parse_config_file(options, &ot);
/* Now that we have all of our options set, we can validate them.
*/
@@ -250,6 +259,24 @@ config_init(fko_srv_options_t *options, int argc, char **argv)
return;
}
/* Dump the configuration
*/
void
dump_config(fko_srv_options_t *opts)
{
int i;
char *var, *val;
fprintf(stderr, "Current fwknopd config settings:\n");
for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
fprintf(stderr, "%3i. %-28s = '%s'\n",
i,
config_ent_map[i],
(opts->config_ent[i] == NULL) ? "<not set>" : opts->config_ent[i]
);
}
/* Print usage message...
*/
void
+23
View File
@@ -29,6 +29,27 @@
#include <getopt.h>
#include <sys/stat.h>
/* Some convenience macros */
/* Characters allowed between a config parameter and its value.
*/
#define IS_CONFIG_PARAM_DELIMITER(x) (x == ' ' || x == '\t' || x == '=');
/* End of line characters.
*/
#define IS_LINE_END(x) (x == '\n' || x == '\r' || x == ';');
/* Characters in the first position of a line that make it considered
* empty or otherwise non-interesting (like a comment).
*/
#define IS_EMPTY_LINE(x) ( \
x == '#' || x == '\n' || x == '\r' || x == ';' || x == '\0' \
)
/* String compare of macro
*/
#define CONF_VAR_IS(n, v) (strcmp(n, v) == 0)
/* Long options values (for those that may not have a short option).
*/
enum {
@@ -40,6 +61,7 @@ enum {
NOOP /* Just to be a marker for the end */
};
/* Our program command-line options...
*/
static struct option cmd_opts[] =
@@ -72,6 +94,7 @@ typedef struct opts_track {
/* Function Prototypes
*/
void config_init(fko_srv_options_t *options, int argc, char **argv);
void dump_config(fko_srv_options_t *options);
void usage(void);
#endif /* CONFIG_INIT_H */
+8
View File
@@ -46,6 +46,14 @@ main(int argc, char **argv)
*/
config_init(&options, argc, argv);
/* Show config and exit dump config was wanted.
*/
if(options.dump_config == 1)
{
dump_config(&options);
exit(EXIT_SUCCESS);
}
/* TODO: add fwknop server code below :)
*/
printf("\nThis is fwknopd. It would do something if it was coded"
+9 -67
View File
@@ -207,11 +207,6 @@ PCAP_PKT_FILE /var/log/sniff.pcap;
#
BLACKLIST NONE;
# Defines interval fwknop will use to check for more iptables
# messages (this is only used in the legacy port knocking mode).
#
SLEEP_INTERVAL 2; ### seconds
# TTL values are decremented depending on the number of hops the packet
# has taken before it hits the firewall. We will assume packets will not
# jump through more than 20 hops on average.
@@ -255,12 +250,6 @@ SYSLOG_IDENTITY fwknopd;
SYSLOG_FACILITY LOG_LOCAL7;
SYSLOG_PRIORITY LOG_INFO;
# syslog config for knoptm
#
KNOPTM_SYSLOG_IDENTITY fwknop(knoptm);
KNOPTM_SYSLOG_FACILITY LOG_LOCAL7;
KNOPTM_SYSLOG_PRIORITY LOG_INFO;
# Allow reporting methods to be enabled/restricted. This keyword can
# accept values of "nosyslog" (don't write any messages to syslog),
# "noemail" (don't send any email messages), or "ALL" (to generate both
@@ -270,24 +259,6 @@ KNOPTM_SYSLOG_PRIORITY LOG_INFO;
#
ALERTING_METHODS ALL;
# (Legacy port knocking mode)
# The following variable can be modified to look for logging messages
# that are specific to your firewall configuration (specified by the
# "--log-prefix" for iptables firewalls). For example, if your firewall
# uses the string "Audit" for packets that have been blocked, then you
# could set FW_MSG_SEARCH = "Audit";
#
FW_MSG_SEARCH DROP;
# (Legacy port knocking mode)
# This variable controls whether fwknopd parses the /var/log/messages
# file for port knock sequences, or if it assumes that the local syslog
# daemon has been configured to write iptables log messages to the
# fwknopfifo named pipe
#
ENABLE_SYSLOG_FILE Y;
IPT_SYSLOG_FILE /var/log/messages;
# This variable defines the number of seconds that the IPTables::ChainMgr
# module should wait for running iptables commands. Normally iptables
# runs extremely fast from the command line (at least for the commands
@@ -354,22 +325,6 @@ EXTERNAL_CMD_ALARM 30;
ENABLE_EXT_CMD_PREFIX N;
EXT_CMD_PREFIX FWKNOP_;
# For knopwatchd
#
KNOPWATCHD_CHECK_INTERVAL 5; ### seconds
KNOPWATCHD_MAX_RETRIES 10;
# Default minimum for any SPA packet (including both the data link,
# network, and transport layer headers)
#
MIN_SPA_PKT_LEN 150;
# Default minimum message size SPA messages encrypted with GnuPG. The
# fwknopd daemon will not attempt to decrypt any packet with gpg that is not
# at least as large as this value.
#
MIN_GNUPG_MSG_SIZE 400;
# fwknop uses the IPTables::ChainMgr module to add allow rules to a
# custom iptables chain "FWKNOP_INPUT". This chain is called from
# the INPUT chain, and by default no other iptables chains are used.
@@ -416,25 +371,17 @@ IPT_MASQUERADE_ACCESS MASQUERADE, src, nat, POSTROUTING, 1, FWKNOP_POSTROU
#
FWKNOP_DIR /var/log/fwknop;
FWKNOP_RUN_DIR /var/run/fwknop;
FWKNOP_LIB_DIR /var/lib/fwknop; # for legacy port knocking mode
FWKNOP_MOD_DIR /usr/lib/fwknop;
FWKNOP_CONF_DIR /etc/fwknop;
FWKNOP_ERR_DIR $FWKNOP_DIR/errs;
# Files
#
FW_DATA_FILE $FWKNOP_DIR/fwdata; # legacy port knocking mode
ACCESS_CONF $FWKNOP_CONF_DIR/access.conf;
P0F_FILE $FWKNOP_CONF_DIR/pf.os; ### p0f-based fingerprints
DIGEST_FILE $FWKNOP_DIR/digest.cache;
FWKNOP_PID_FILE $FWKNOP_RUN_DIR/fwknopd.pid;
FWKNOP_CMDLINE_FILE $FWKNOP_RUN_DIR/fwknopd.cmd;
TCPSERV_PID_FILE $FWKNOP_RUN_DIR/fwknop_serv.pid;
KNOPWATCHD_PID_FILE $FWKNOP_RUN_DIR/knopwatchd.pid;
KNOPMD_PID_FILE $FWKNOP_RUN_DIR/knopmd.pid;
KNOPTM_PID_FILE $FWKNOP_RUN_DIR/knoptm.pid;
KNOPTM_IP_TIMEOUT_SOCK $FWKNOP_RUN_DIR/knoptm_ip_timeout.sock;
KNOPMD_FIFO $FWKNOP_LIB_DIR/fwknopfifo;
PROC_IP_FORWARD_FILE /proc/sys/net/ipv4/ip_forward;
# iptables command output and error collection files; these are
@@ -442,22 +389,17 @@ PROC_IP_FORWARD_FILE /proc/sys/net/ipv4/ip_forward;
#
IPT_OUTPUT_FILE $FWKNOP_DIR/fwknopd.iptout;
IPT_ERROR_FILE $FWKNOP_DIR/fwknopd.ipterr;
KNOPTM_IPT_OUTPUT_FILE $FWKNOP_DIR/knoptm.iptout;
KNOPTM_IPT_ERROR_FILE $FWKNOP_DIR/knoptm.ipterr;
# system binaries
#
gpgCmd /usr/bin/gpg;
mailCmd /bin/mail;
sendmailCmd /usr/sbin/sendmail;
shCmd /bin/sh;
mknodCmd /bin/mknod;
iptablesCmd /sbin/iptables;
ipfwCmd /sbin/ipfw; ### BSD and Mac OS X only
fwknopdCmd /usr/sbin/fwknopd;
fwknop_servCmd /usr/sbin/fwknop_serv;
knopmdCmd /usr/sbin/knopmd;
knoptmCmd /usr/sbin/knoptm;
knopwatchdCmd /usr/sbin/knopwatchd;
#gpgCmd /usr/bin/gpg;
#mailCmd /bin/mail;
#sendmailCmd /usr/sbin/sendmail;
#shCmd /bin/sh;
#mknodCmd /bin/mknod;
#iptablesCmd /sbin/iptables;
#ipfwCmd /sbin/ipfw; ### BSD and Mac OS X only
#fwknopdCmd /usr/sbin/fwknopd;
#fwknop_servCmd /usr/sbin/fwknop_serv;
###EOF###
+178 -10
View File
@@ -54,27 +54,195 @@
#define MAX_PCAP_FILTER_LEN 1024
#define MAX_IFNAME_LEN 128
/* Data collection modes
*/
enum {
SPA_CAP_MODE_PCAP,
SPA_CAP_MODE_UDP,
SPA_CAP_MODE_TCP
};
/* Configuration file parameter tags.
* This will correspond to entries in the configuration parameters
* array.
*/
enum {
CONF_CONFIG_FILE = 0,
CONF_FIREWALL_LOG,
CONF_GPG_KEY,
CONF_OVERRIDE_CONFIG,
CONF_EMAIL_ADDRESSES,
CONF_HOSTNAME,
CONF_FIREWALL_TYPE,
CONF_AUTH_MODE,
CONF_PCAP_INTF,
CONF_ENABLE_PCAP_PROMISC,
CONF_PCAP_FILTER,
CONF_ENABLE_SPA_PACKET_AGING,
CONF_MAX_SPA_PACKET_AGE,
CONF_ENABLE_DIGEST_PERSISTENCE,
CONF_DIGEST_TYPE,
CONF_ENABLE_DIGEST_INCLUDE_SRC,
CONF_ENABLE_IPT_FORWARDING,
CONF_ENABLE_IPT_LOCAL_NAT,
CONF_ENABLE_IPT_SNAT,
CONF_SNAT_TRANSLATE_IP,
CONF_ENABLE_PROC_IP_FORWARD,
CONF_ENABLE_IPT_OUTPUT,
CONF_REQUIRE_SOURCE_ADDRESS,
CONF_ENABLE_COOKED_INTF,
CONF_ENABLE_VOLUNTARY_EXITS,
CONF_EXIT_INTERVAL,
CONF_MAX_SNIFF_BYTES,
CONF_FLUSH_IPT_AT_INIT,
CONF_IPFW_RULE_NUM,
CONF_IPFW_SET_NUM,
CONF_IPFW_DYNAMIC_INTERVAL,
CONF_PCAP_CMD_TIMEOUT,
CONF_GPG_DEFAULT_HOME_DIR,
CONF_PCAP_PKT_FILE,
CONF_BLACKLIST,
CONF_MAX_HOPS,
CONF_ENABLE_SPA_OVER_HTTP,
CONF_ENABLE_TCP_SERVER,
CONF_TCPSERV_PORT,
CONF_LOCALE,
CONF_SYSLOG_DAEMON,
CONF_SYSLOG_IDENTITY,
CONF_SYSLOG_FACILITY,
CONF_SYSLOG_PRIORITY,
CONF_ALERTING_METHODS,
CONF_IPT_CMD_ALARM,
CONF_IPT_EXEC_STYLE,
CONF_IPT_EXEC_SLEEP,
CONF_IPT_EXEC_TRIES,
CONF_ENABLE_EXTERNAL_CMDS,
CONF_EXTERNAL_CMD_OPEN,
CONF_EXTERNAL_CMD_CLOSE,
CONF_EXTERNAL_CMD_ALARM,
CONF_ENABLE_EXT_CMD_PREFIX,
CONF_EXT_CMD_PREFIX,
CONF_IPT_INPUT_ACCESS,
CONF_IPT_OUTPUT_ACCESS,
CONF_IPT_FORWARD_ACCESS,
CONF_IPT_DNAT_ACCESS,
CONF_IPT_SNAT_ACCESS,
CONF_IPT_MASQUERADE_ACCESS,
CONF_FWKNOP_DIR,
CONF_FWKNOP_RUN_DIR,
CONF_FWKNOP_MOD_DIR,
CONF_FWKNOP_CONF_DIR,
CONF_FWKNOP_ERR_DIR,
CONF_ACCESS_CONF,
CONF_DIGEST_FILE,
CONF_FWKNOP_PID_FILE,
CONF_FWKNOP_CMDLINE_FILE,
CONF_TCPSERV_PID_FILE,
CONF_PROC_IP_FORWARD_FILE,
CONF_IPT_OUTPUT_FILE,
CONF_IPT_ERROR_FILE,
NUMBER_OF_CONFIG_ENTRIES /* Marks the end and number of entries */
};
/* Now that we have the config entry indexes defined, we will create a
* config entry name map as well (too lazy to make a hash table).
*
* Note: It is very important this list matches the one above (with the
* exception of the last entry above).
*/
static char *config_ent_map[NUMBER_OF_CONFIG_ENTRIES] = {
"CONFIG_FILE",
"FIREWALL_LOG",
"GPG_KEY",
"OVERRIDE_CONFIG",
"EMAIL_ADDRESSES",
"HOSTNAME",
"FIREWALL_TYPE",
"AUTH_MODE",
"PCAP_INTF",
"ENABLE_PCAP_PROMISC",
"PCAP_FILTER",
"ENABLE_SPA_PACKET_AGING",
"MAX_SPA_PACKET_AGE",
"ENABLE_DIGEST_PERSISTENCE",
"DIGEST_TYPE",
"ENABLE_DIGEST_INCLUDE_SRC",
"ENABLE_IPT_FORWARDING",
"ENABLE_IPT_LOCAL_NAT",
"ENABLE_IPT_SNAT",
"SNAT_TRANSLATE_IP",
"ENABLE_PROC_IP_FORWARD",
"ENABLE_IPT_OUTPUT",
"REQUIRE_SOURCE_ADDRESS",
"ENABLE_COOKED_INTF",
"ENABLE_VOLUNTARY_EXITS",
"EXIT_INTERVAL",
"MAX_SNIFF_BYTES",
"FLUSH_IPT_AT_INIT",
"IPFW_RULE_NUM",
"IPFW_SET_NUM",
"IPFW_DYNAMIC_INTERVAL",
"PCAP_CMD_TIMEOUT",
"GPG_DEFAULT_HOME_DIR",
"PCAP_PKT_FILE",
"BLACKLIST",
"MAX_HOPS",
"ENABLE_SPA_OVER_HTTP",
"ENABLE_TCP_SERVER",
"TCPSERV_PORT",
"LOCALE",
"SYSLOG_DAEMON",
"SYSLOG_IDENTITY",
"SYSLOG_FACILITY",
"SYSLOG_PRIORITY",
"ALERTING_METHODS",
"IPT_CMD_ALARM",
"IPT_EXEC_STYLE",
"IPT_EXEC_SLEEP",
"IPT_EXEC_TRIES",
"ENABLE_EXTERNAL_CMDS",
"EXTERNAL_CMD_OPEN",
"EXTERNAL_CMD_CLOSE",
"EXTERNAL_CMD_ALARM",
"ENABLE_EXT_CMD_PREFIX",
"EXT_CMD_PREFIX",
"IPT_INPUT_ACCESS",
"IPT_OUTPUT_ACCESS",
"IPT_FORWARD_ACCESS",
"IPT_DNAT_ACCESS",
"IPT_SNAT_ACCESS",
"IPT_MASQUERADE_ACCESS",
"FWKNOP_DIR",
"FWKNOP_RUN_DIR",
"FWKNOP_MOD_DIR",
"FWKNOP_CONF_DIR",
"FWKNOP_ERR_DIR",
"ACCESS_CONF",
"DIGEST_FILE",
"FWKNOP_PID_FILE",
"FWKNOP_CMDLINE_FILE",
"TCPSERV_PID_FILE",
"PROC_IP_FORWARD_FILE",
"IPT_OUTPUT_FILE",
"IPT_ERROR_FILE"
};
/* fwknopd server configuration parameters and values
*/
typedef struct fko_srv_options
{
/* Various command-line options and flags
/* The command-line options or flags that invoke an immediate response
* then exit.
*/
char config_file[MAX_PATH_LEN]; /* The main fwknopd config file */
char firewall_log[MAX_PATH_LEN]; /* The firewall log file */
char gpg_home_dir[MAX_PATH_LEN]; /* GPG Home directory */
char gpg_key[MAX_GPG_KEY_ID]; /* The gpg key id for decrypting */
char net_interface[MAX_IFNAME_LEN]; /* Network interface to sniff */
char override_config[MAX_PATH_LEN]; /* One of more overried config files */
unsigned char dump_config; /* Dump current configuration flag */
unsigned char restart; /* Restart fwknopd flag*/
unsigned char verbose; /* Verbose mode flag */
unsigned char test; /* Test mode flag */
/* Options from the config file only.
/* This array holds all of the config file entry values as strings
* indexed by their tag name.
*/
char *config_ent[NUMBER_OF_CONFIG_ENTRIES];
} fko_srv_options_t;