Added stubs and some handling for signals. SIGHUP induces the re-reading the configs and restarting the capture loop. SIGTERM and SIGINT simply trigger a graceful exit. Trimmed some more of the configuration options.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@152 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart
2009-10-11 17:42:45 +00:00
parent e399f39c39
commit 8b4b55fa44
13 changed files with 517 additions and 301 deletions
+2 -1
View File
@@ -3,7 +3,8 @@ sbin_PROGRAMS = fwknopd
fwknopd_SOURCES = fwknopd.c fwknopd.h config_init.c config_init.h \
fwknopd_common.h incoming_spa.c incoming_spa.h \
pcap_capture.c pcap_capture.h process_packet.c \
process_packet.h log_msg.c log_msg.h utils.c utils.h
process_packet.h log_msg.c log_msg.h utils.c utils.h \
sig_handler.c sig_handler.h
fwknopd_LDADD = $(top_builddir)/lib/libfko.la
+16 -4
View File
@@ -88,6 +88,18 @@ config_entry_index(fko_srv_options_t *opts, char *var)
return(-1);
}
/* Free the config memory
*/
void
free_configs(fko_srv_options_t *opts)
{
int i;
for(i=0; i<NUMBER_OF_CONFIG_ENTRIES; i++)
if(opts->config[i] != NULL)
free(opts->config[i]);
}
/* Parse the config file...
*/
static void
@@ -244,13 +256,16 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
memset(opts, 0x00, sizeof(fko_srv_options_t));
/* First, set any default or otherwise static settings here. Some may
* end up being overwritten vail config file or command-line.
* end up being overwritten via config file or command-line.
*/
/* Default Hostname (or unknown if gethostname cannot tell us).
*/
if(gethostname(opts->hostname, MAX_HOSTNAME_LEN-1) < 0)
strcpy(opts->hostname, "UNKNOWN");
/* In case this is a re-config.
*/
optind = 0;
/* First, scan the command-line args for an alternate configuration
* file. If we find it, use it, otherwise use the default.
@@ -364,9 +379,6 @@ config_init(fko_srv_options_t *opts, int argc, char **argv)
//flush_firewall_rules();
exit(EXIT_SUCCESS);
break;
case FIREWALL_LOG:
set_config_entry(opts, CONF_FIREWALL_LOG, optarg);
break;
case GPG_HOME_DIR:
set_config_entry(opts, CONF_GPG_HOME_DIR, optarg);
break;
+3 -2
View File
@@ -90,8 +90,9 @@ static struct option cmd_opts[] =
/* Function Prototypes
*/
void config_init(fko_srv_options_t *options, int argc, char **argv);
void dump_config(fko_srv_options_t *options);
void config_init(fko_srv_options_t *opts, int argc, char **argv);
void dump_config(fko_srv_options_t *opts);
void clear_configs(fko_srv_options_t *opts);
void usage(void);
#endif /* CONFIG_INIT_H */
+151 -82
View File
@@ -32,6 +32,7 @@
#include "pcap_capture.h"
#include "log_msg.h"
#include "utils.h"
#include "sig_handler.h"
/* Prototypes
*/
@@ -43,119 +44,187 @@ int
main(int argc, char **argv)
{
fko_ctx_t ctx;
int res;
int res, last_sig;
char *spa_data, *version;
char access_buf[MAX_LINE_LEN];
pid_t old_pid;
fko_srv_options_t opts;
/* Handle command line
*/
config_init(&opts, argc, argv);
/* Process any options that do their thing and exit. */
/* Show config and exit dump config was wanted.
*/
if(opts.dump_config == 1)
while(1)
{
dump_config(&opts);
exit(EXIT_SUCCESS);
}
/* Handle command line
*/
config_init(&opts, argc, argv);
/* Kill the currently running fwknopd?
*/
if(opts.kill == 1)
{
old_pid = get_running_pid(&opts);
/* Process any options that do their thing and exit. */
if(old_pid > 0)
/* Show config and exit dump config was wanted.
*/
if(opts.dump_config == 1)
{
res = kill(old_pid, SIGTERM);
if(res == 0)
dump_config(&opts);
exit(EXIT_SUCCESS);
}
/* Kill the currently running fwknopd?
*/
if(opts.kill == 1)
{
old_pid = get_running_pid(&opts);
if(old_pid > 0)
{
fprintf(stderr, "Killed fwknopd (pid=%i)\n", old_pid);
exit(EXIT_SUCCESS);
res = kill(old_pid, SIGTERM);
if(res == 0)
{
fprintf(stderr, "Killed fwknopd (pid=%i)\n", old_pid);
exit(EXIT_SUCCESS);
}
else
{
perror("Unable to kill fwknop: ");
exit(EXIT_FAILURE);
}
}
else
{
perror("Unable to kill fwknop: ");
fprintf(stderr, "No running fwknopd detected.\n", old_pid);
exit(EXIT_FAILURE);
}
}
/* Restart the currently running fwknopd?
*/
if(opts.restart == 1)
{
old_pid = get_running_pid(&opts);
if(old_pid > 0)
{
res = kill(old_pid, SIGHUP);
if(res == 0)
{
fprintf(stderr, "Sent restart signal to fwknopd (pid=%i)\n", old_pid);
exit(EXIT_SUCCESS);
}
else
{
perror("Unable to send signal to fwknop: ");
exit(EXIT_FAILURE);
}
}
else
{
fprintf(stderr, "No running fwknopd detected.\n", old_pid);
exit(EXIT_FAILURE);
}
}
/* Status of the currently running fwknopd?
*/
if(opts.status == 1)
{
fprintf(stderr, "Status option not implemented yet.\n");
exit(EXIT_SUCCESS);
}
/* Initialize logging.
*/
init_logging(&opts);
if(get_running_pid(&opts) != getpid())
{
/* If foreground mode is not set, the fork off and become a daemon.
* Otherwise, attempt to get the pid fiel lock and go on.
*/
if(opts.foreground == 0)
{
daemonize_process(&opts);
}
else
{
old_pid = write_pid_file(&opts);
if(old_pid > 0)
{
fprintf(stderr,
"* An instance of fwknopd is already running: (PID=%i).\n", old_pid
);
exit(EXIT_FAILURE);
}
else if(old_pid < 0)
{
fprintf(stderr, "* PID file error. The lock may not be effective.\n");
}
}
log_msg(LOG_INFO, "Starting %s", MY_NAME);
}
else
{
fprintf(stderr, "No running fwknopd detected.\n", old_pid);
exit(EXIT_FAILURE);
log_msg(LOG_INFO, "Re-starting %s", MY_NAME);
}
}
/* Restart the currently running fwknopd?
*/
if(opts.restart == 1)
{
//sendsig_fwknopd(&opts, SIGHUP);
fprintf(stderr, "Restart option not implemented yet.\n");
exit(EXIT_SUCCESS);
}
dump_config(&opts);
/* Status of the currently running fwknopd?
*/
if(opts.status == 1)
{
//fwknopd_status(&opts, SIGHUP);
fprintf(stderr, "Status option not implemented yet.\n");
exit(EXIT_SUCCESS);
}
/* If foreground mode is not set, the fork off and become a daemon.
* Otherwise, attempt to get the pid fiel lock and go on.
*/
if(opts.foreground == 0)
{
daemonize_process(&opts);
}
else
{
old_pid = write_pid_file(&opts);
if(old_pid > 0)
if((strncasecmp(opts.config[CONF_AUTH_MODE], "pcap", 4)) != 0)
{
fprintf(stderr,
"* An instance of fwknopd is already running: (PID=%i).\n", old_pid
log_msg(LOG_ERR|LOG_STDERR,
"Capture/auth mode other than 'PCAP' is not supported."
);
exit(EXIT_FAILURE);
}
else if(old_pid < 0)
{
fprintf(stderr, "* PID file error. The lock may not be effective.\n");
}
}
/* Initialize logging.
*/
init_logging(&opts);
log_msg(LOG_INFO, "Starting %s", MY_NAME);
if((strncasecmp(opts.config[CONF_AUTH_MODE], "pcap", 4)) != 0)
{
log_msg(LOG_ERR|LOG_STDERR,
"Capture/auth mode other than 'PCAP' is not supported."
);
exit(EXIT_FAILURE);
}
#ifndef HAVE_LIBPCAP
log_msg(LOG_ERR|LOG_STDERR,
"libpcap is not avaiable, I'm hosed (for now).");
exit(EXIT_FAILURE);
log_msg(LOG_ERR|LOG_STDERR,
"libpcap is not avaiable, I'm hosed (for now).");
exit(EXIT_FAILURE);
#endif
/* Intiate pcap capture mode...
/* Intiate pcap capture mode...
*/
pcap_capture(&opts);
if(last_sig = got_signal) {
got_signal = 0;
if(got_sighup)
{
log_msg(LOG_WARNING|LOG_STDERR, "Got SIGHUP. Re-reading configs.");
free_configs(&opts);
got_sighup = 0;
}
else if(got_sigint)
{
log_msg(LOG_WARNING|LOG_STDERR, "Got SIGINT. Exiting...");
got_sigint = 0;
break;
}
else if(got_sigterm)
{
log_msg(LOG_WARNING|LOG_STDERR, "Got SIGTERM. Exiting...");
got_sigterm = 0;
break;
}
else
{
log_msg(LOG_WARNING|LOG_STDERR,
"Got signal %i. No defined action but to exit.", last_sig);
break;
}
}
else /* got_signal was not set (should be if we are here) */
{
log_msg(LOG_WARNING|LOG_STDERR,
"Capture ended without signal. Exiting...");
break;
}
}
/* Other cleanup.
*/
pcap_capture(&opts);
free_logging();
free_configs(&opts);
return(0);
}
+46 -107
View File
@@ -78,19 +78,6 @@ MAX_SPA_PACKET_AGE 120;
#
ENABLE_DIGEST_PERSISTENCE Y;
# Default to using all of SHA1/256/384/512, and MD5 for SPA replay attack
# detection. This is overkill, but performance is not usually a concern.
# Further, the variable can also be set to "SHA1" or "MD5".
#
DIGEST_TYPE ALL;
# This variable controls whether fwknopd includes the source IP of each SPA
# packet in the DIGEST store. If a replayed SPA message is detected, then
# having this information can provide information about which networks have
# people sniffing your SPA packets.
#
ENABLE_DIGEST_INCLUDE_SRC Y;
# Allow SPA clients to request access to services through an iptables
# firewall instead of just to it (i.e. access through the FWKNOP_FORWARD
# chain instead of the INPUT chain). This also requires the
@@ -142,48 +129,33 @@ ENABLE_IPT_OUTPUT N;
#
REQUIRE_SOURCE_ADDRESS N;
# Config variable to force fwknopd to always treat the sniffing interface as
# the "cooked" interface type on Linux.
#
ENABLE_COOKED_INTF N;
# This pair of variables controls whether fwknopd voluntarily exits and over
# what time interval. When fwknopd exits, knopwatchd will restart it.
# Because fwknop controls the accessibility of services, this feature can be
# used to make sure that the fwknop rules are flushed (see the
# FLUSH_IPT_AT_INIT variable), and the effects of any potential logic (or
# other) bugs are minimized since fwknopd will start "fresh" when knopwatchd
# kicks it off. NOTE: This feature is almost never required since fwknopd is
# generally quite stable, and is mostly offered for the the extra paranoid.
#
ENABLE_VOLUNTARY_EXITS N;
EXIT_INTERVAL 1440; ### minutes (1 day)
# Specify the the maximum number of bytes to sniff per frame - 1500
# is a good default
#
MAX_SNIFF_BYTES 1500;
# Flush all existing rules in the fwknop chains at fwknop start time.
# Flush all existing rules in the fwknop chains at fwknop start time and/or
# exit time. They default to Y.
#
FLUSH_IPT_AT_INIT Y;
#FLUSH_IPT_AT_INIT Y;
#FLUSH_IPT_AT_EXIT Y;
# If running on ipfw firewalls, this variable defines the rule number that
# fwknopd uses to insert an ipfw pass rule.
#
IPFW_RULE_NUM 1;
#IPFW_RULE_NUM 1;
# If running on ipfw firewalls, this variable defines the rule set that will
# be used to store expired rules that still have a dynamic rule associated
# to them. That set will be disabled by fwknop and should not be enabled
# while fwknop is running. Not used when ipfw isn't using dynamic rules.
#
IPFW_SET_NUM 1;
#IPFW_SET_NUM 1;
# For ipfw firewalls set the interval (in seconds) over which rules that
# have no remaining dynamic rules associated with them will be removed.
#
IPFW_DYNAMIC_INTERVAL 60; ### seconds
#IPFW_DYNAMIC_INTERVAL 60; ### seconds
# Define the timeout for running a command
#
@@ -191,7 +163,7 @@ PCAP_CMD_TIMEOUT 10;
# If GPG keys are used instead of a Rijndael symmetric key, this is
# the default GPG keys directory. Note that each access block in
# /etc/fwknop/access.conf can specify its own GPG directory to override
# fwknop access.conf can specify its own GPG directory to override
# this default.
#
GPG_HOME_DIR /root/.gnupg;
@@ -200,50 +172,45 @@ GPG_HOME_DIR /root/.gnupg;
# be created by a sniffer process (or something like the ulogd pcap
# writer).
#
PCAP_PKT_FILE /var/log/sniff.pcap;
#PCAP_PKT_FILE /var/log/sniff.pcap;
# Define a comma-separated set of IP addresses and/or networks that should
# be globally blacklisted. That is, any SPA packet that is from a source
# IP (or has an internal --allow-ip) within a blacklisted network will be
# ignored.
#
BLACKLIST NONE;
#BLACKLIST NONE;
# 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.
#
MAX_HOPS 20;
#MAX_HOPS 20;
# Allow fwknopd to acquire SPA data from HTTP requests (generated with the
# fwknop client in --HTTP mode). Note that the PCAP_FILTER variable would
# need to be updated when this is enabled to sniff traffic over TCP/80
# connections
#
ENABLE_SPA_OVER_HTTP N;
#ENABLE_SPA_OVER_HTTP N;
# Note that fwknopd still only gets its data via pcap, so the filter
# defined by PCAP_FILTER needs to be updated to include this TCP port.
#
ENABLE_TCP_SERVER N;
#ENABLE_TCP_SERVER N;
# Set the default port number that the fwknop_serv "dummy" TCP server
# listens on. This server is only spawned when ENABLE_TCP_SERVER is set
# to "Y".
#
TCPSERV_PORT 62201;
#TCPSERV_PORT 62201;
# Set the locale (via the LC_ALL variable). This can be set to NONE to
# have fwknopd honor the default system locale.
#
LOCALE C;
# Set the type of syslog daemon that is used. The SYSLOG_DAEMON variable
# accepts three possible values: syslogd, syslog-ng, or metalog.
#
SYSLOG_DAEMON syslogd;
# syslog identity and facility (the defaults are usually ok)
# Override syslog identity and facility (the defaults are usually ok).
# The SYSLOG_FACILITY variable can be set to one of LOG_LOCAL{0-7}
# or LOG_DAEMON (the default).
#
@@ -257,29 +224,9 @@ SYSLOG_DAEMON syslogd;
# and "noemail" can be combined with a comma to disable all logging
# and alerting.
#
ALERTING_METHODS ALL;
#ALERTING_METHODS ALL;
# 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
# that fwknopd executes), so the default of 30 seconds is plenty.
#
IPT_CMD_ALARM 30;
# Set the strategy that the IPTables::ChainMgr module will use for executing
# iptables commands. The default of "waitpid" means that IPTables::ChainMgr
# will use fork(), exec(), and waitpid(), whereas "system" means that
# "system()" will used, and finally "popen" means that iptables will be
# executed via popen().
#
IPT_EXEC_STYLE waitpid;
# Define the number of seconds that the IPTables::ChainMgr policy uses to
# sleep between successive iptables commands. Zero is the default.
#
IPT_EXEC_SLEEP 0;
# Define the number of times that fwknopd or knoptm will run certain
# Define the number of times that fwknopd will run certain
# critical iptables commands (such as adding a new access rule) if any
# problems are encountered.
#
@@ -312,18 +259,18 @@ IPT_EXEC_TRIES 1;
# EXTERNAL_CMD_OPEN /path/someprog $SOURCE $OPEN_PORTS
# EXTERNAL_CMD_OPEN /path/otherprog $SRC
#
ENABLE_EXTERNAL_CMDS N;
EXTERNAL_CMD_OPEN __NONE__;
EXTERNAL_CMD_CLOSE __NONE__;
EXTERNAL_CMD_ALARM 30;
#ENABLE_EXTERNAL_CMDS N;
#EXTERNAL_CMD_OPEN __NONE__;
#EXTERNAL_CMD_CLOSE __NONE__;
#EXTERNAL_CMD_ALARM 30;
# if EXTERNAL_CMD_OPEN is used above, then the following two variables can
# be used to enforce a prefix on variable substitutions - useful if there
# are any naming conflicts with the external script and command line
# arguments that are named the same as the variables to be substituted.
#
ENABLE_EXT_CMD_PREFIX N;
EXT_CMD_PREFIX FWKNOP_;
#ENABLE_EXT_CMD_PREFIX N;
#EXT_CMD_PREFIX FWKNOP_;
# fwknop uses the IPTables::ChainMgr module to add allow rules to a
# custom iptables chain "FWKNOP_INPUT". This chain is called from
@@ -350,56 +297,48 @@ EXT_CMD_PREFIX FWKNOP_;
# "Rule_position": Defines the position where rule are added within the
# To_chain.
#
IPT_INPUT_ACCESS ACCEPT, src, filter, INPUT, 1, FWKNOP_INPUT, 1;
#IPT_INPUT_ACCESS ACCEPT, src, filter, INPUT, 1, FWKNOP_INPUT, 1;
# The IPT_OUTPUT_ACCESS variable is only used if ENABLE_IPT_OUTPUT is enabled
#
IPT_OUTPUT_ACCESS ACCEPT, dst, filter, OUTPUT, 1, FWKNOP_OUTPUT, 1;
#IPT_OUTPUT_ACCESS ACCEPT, dst, filter, OUTPUT, 1, FWKNOP_OUTPUT, 1;
# The IPT_FORWARD_ACCESS variable is only used if ENABLE_IPT_FORWARDING is
# enabled.
#
IPT_FORWARD_ACCESS ACCEPT, src, filter, FORWARD, 1, FWKNOP_FORWARD, 1;
IPT_DNAT_ACCESS DNAT, src, nat, PREROUTING, 1, FWKNOP_PREROUTING, 1;
#IPT_FORWARD_ACCESS ACCEPT, src, filter, FORWARD, 1, FWKNOP_FORWARD, 1;
#IPT_DNAT_ACCESS DNAT, src, nat, PREROUTING, 1, FWKNOP_PREROUTING, 1;
# The IPT_SNAT_ACCESS variable is not used unless both ENABLE_IPT_SNAT and
# ENABLE_IPT_FORWARDING are enabled. Also, the external static IP must be
# set with the SNAT_TRANSLATE_IP variable. The default is to use the
# IPT_MASQUERADE_ACCESS variable.
#
IPT_SNAT_ACCESS SNAT, src, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1;
IPT_MASQUERADE_ACCESS MASQUERADE, src, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1;
#IPT_SNAT_ACCESS SNAT, src, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1;
#IPT_MASQUERADE_ACCESS MASQUERADE, src, nat, POSTROUTING, 1, FWKNOP_POSTROUTING, 1;
# Directories
#
FWKNOP_DIR /var/log/fwknop;
#FWKNOP_DIR /var/log/fwknop;
FWKNOP_RUN_DIR /var/run/fwknop;
FWKNOP_MOD_DIR /usr/lib/fwknop;
FWKNOP_CONF_DIR /etc/fwknop;
FWKNOP_ERR_DIR $FWKNOP_DIR/errs;
#FWKNOP_MOD_DIR /usr/lib/fwknop;
#FWKNOP_CONF_DIR /etc/fwknop;
#FWKNOP_ERR_DIR $FWKNOP_DIR/errs;
# Files
#
ACCESS_CONF $FWKNOP_CONF_DIR/access.conf;
DIGEST_FILE $FWKNOP_DIR/digest.cache;
#ACCESS_CONF $FWKNOP_CONF_DIR/access.conf;
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;
PROC_IP_FORWARD_FILE /proc/sys/net/ipv4/ip_forward;
DIGEST_FILE $FWKNOP_RUN_DIR/digest.cache;
#FWKNOP_CMDLINE_FILE $FWKNOP_RUN_DIR/fwknopd.cmd;
#TCPSERV_PID_FILE $FWKNOP_RUN_DIR/fwknop_serv.pid;
#PROC_IP_FORWARD_FILE /proc/sys/net/ipv4/ip_forward;
# iptables command output and error collection files; these are
# used by IPTables::ChainMgr
# System binaries
#
IPT_OUTPUT_FILE $FWKNOP_DIR/fwknopd.iptout;
IPT_ERROR_FILE $FWKNOP_DIR/fwknopd.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;
EXE_GPG /usr/bin/gpg;
EXE_MAIL /bin/mail;
EXE_SENDMAIL /usr/sbin/sendmail;
EXE_SH /bin/sh;
EXE_MKNOD /bin/mknod;
EXE_IPTABLES /sbin/iptables;
EXE_IPFW /sbin/ipfw; ### BSD and Mac OS X only
###EOF###
+95 -86
View File
@@ -47,6 +47,7 @@
#define DEF_CONF_DIR SYSCONFDIR"/fwknop"
#endif
#define DEF_CONFIG_FILE DEF_CONF_DIR"/"MY_NAME".conf"
#define DEF_INTERFACE "eth0"
/* fwknopd-specific limits
@@ -70,7 +71,6 @@ enum {
*/
enum {
CONF_CONFIG_FILE = 0,
CONF_FIREWALL_LOG,
CONF_GPG_KEY,
CONF_OVERRIDE_CONFIG,
CONF_EMAIL_ADDRESSES,
@@ -83,8 +83,7 @@ enum {
CONF_ENABLE_SPA_PACKET_AGING,
CONF_MAX_SPA_PACKET_AGE,
CONF_ENABLE_DIGEST_PERSISTENCE,
CONF_DIGEST_TYPE,
CONF_ENABLE_DIGEST_INCLUDE_SRC,
//CONF_ENABLE_DIGEST_INCLUDE_SRC,
CONF_ENABLE_IPT_FORWARDING,
CONF_ENABLE_IPT_LOCAL_NAT,
CONF_ENABLE_IPT_SNAT,
@@ -92,56 +91,58 @@ enum {
CONF_ENABLE_PROC_IP_FORWARD,
CONF_ENABLE_IPT_OUTPUT,
CONF_REQUIRE_SOURCE_ADDRESS,
CONF_ENABLE_COOKED_INTF,
//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_FLUSH_IPT_AT_INIT,
//CONF_FLUSH_IPT_AT_EXIT,
//CONF_IPFW_RULE_NUM,
//CONF_IPFW_SET_NUM,
//CONF_IPFW_DYNAMIC_INTERVAL,
CONF_PCAP_CMD_TIMEOUT,
CONF_GPG_HOME_DIR,
CONF_PCAP_PKT_FILE,
CONF_BLACKLIST,
CONF_MAX_HOPS,
CONF_ENABLE_SPA_OVER_HTTP,
CONF_ENABLE_TCP_SERVER,
CONF_TCPSERV_PORT,
//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_ALERTING_METHODS,
CONF_IPT_CMD_ALARM,
CONF_IPT_EXEC_STYLE,
CONF_IPT_EXEC_SLEEP,
//CONF_ALERTING_METHODS,
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_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_MOD_DIR,
//CONF_FWKNOP_CONF_DIR,
//CONF_FWKNOP_ERR_DIR,
//CONF_ACCESS_CONF,
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,
CONF_DIGEST_FILE,
//CONF_FWKNOP_CMDLINE_FILE,
//CONF_TCPSERV_PID_FILE,
//CONF_PROC_IP_FORWARD_FILE,
CONF_EXE_GPG,
CONF_EXE_MAIL,
CONF_EXE_SENDMAIL,
CONF_EXE_SH,
CONF_EXE_MKNOD,
CONF_EXE_IPTABLES,
CONF_EXE_IPFW,
NUMBER_OF_CONFIG_ENTRIES /* Marks the end and number of entries */
};
@@ -153,7 +154,6 @@ enum {
*/
static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
"CONFIG_FILE",
"FIREWALL_LOG",
"GPG_KEY",
"OVERRIDE_CONFIG",
"EMAIL_ADDRESSES",
@@ -166,8 +166,7 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
"ENABLE_SPA_PACKET_AGING",
"MAX_SPA_PACKET_AGE",
"ENABLE_DIGEST_PERSISTENCE",
"DIGEST_TYPE",
"ENABLE_DIGEST_INCLUDE_SRC",
//"ENABLE_DIGEST_INCLUDE_SRC",
"ENABLE_IPT_FORWARDING",
"ENABLE_IPT_LOCAL_NAT",
"ENABLE_IPT_SNAT",
@@ -175,58 +174,69 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
"ENABLE_PROC_IP_FORWARD",
"ENABLE_IPT_OUTPUT",
"REQUIRE_SOURCE_ADDRESS",
"ENABLE_COOKED_INTF",
//"ENABLE_COOKED_INTF",
"ENABLE_VOLUNTARY_EXITS",
"EXIT_INTERVAL",
"MAX_SNIFF_BYTES",
"FLUSH_IPT_AT_INIT",
"IPFW_RULE_NUM",
"IPFW_SET_NUM",
"IPFW_DYNAMIC_INTERVAL",
//"FLUSH_IPT_AT_INIT",
//"FLUSH_IPT_AT_EXIT",
//"IPFW_RULE_NUM",
//"IPFW_SET_NUM",
//"IPFW_DYNAMIC_INTERVAL",
"PCAP_CMD_TIMEOUT",
"GPG_HOME_DIR",
"PCAP_PKT_FILE",
"BLACKLIST",
"MAX_HOPS",
"ENABLE_SPA_OVER_HTTP",
"ENABLE_TCP_SERVER",
"TCPSERV_PORT",
//"PCAP_PKT_FILE",
//"BLACKLIST",
//"MAX_HOPS",
//"ENABLE_SPA_OVER_HTTP",
//"ENABLE_TCP_SERVER",
//"TCPSERV_PORT",
"LOCALE",
"SYSLOG_DAEMON",
"SYSLOG_IDENTITY",
"SYSLOG_FACILITY",
"ALERTING_METHODS",
"IPT_CMD_ALARM",
"IPT_EXEC_STYLE",
"IPT_EXEC_SLEEP",
//"ALERTING_METHODS",
"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",
//"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_MOD_DIR",
//"FWKNOP_CONF_DIR",
//"FWKNOP_ERR_DIR",
//"ACCESS_CONF",
"FWKNOP_PID_FILE",
"FWKNOP_CMDLINE_FILE",
"TCPSERV_PID_FILE",
"PROC_IP_FORWARD_FILE",
"IPT_OUTPUT_FILE",
"IPT_ERROR_FILE"
"DIGEST_FILE",
//"FWKNOP_CMDLINE_FILE",
//"TCPSERV_PID_FILE",
//"PROC_IP_FORWARD_FILE",
"EXE_GPG",
"EXE_MAIL",
"EXE_SENDMAIL",
"EXE_SH",
"EXE_MKNOD",
"EXE_IPTABLES",
"EXE_IPFW"
};
/* SPA Packet info struct.
*/
typedef struct spa_pkt_info
{
unsigned int packet_data_len;
unsigned int packet_src_ip;
unsigned char packet_data[MAX_SPA_PACKET_LEN+1];
} spa_pkt_info_t;
/* fwknopd server configuration parameters and values
*/
typedef struct fko_srv_options
@@ -244,8 +254,7 @@ typedef struct fko_srv_options
int data_link_offset;
unsigned int packet_data_len; /* Is > 0 if we have data */
unsigned char packet_data[MAX_SPA_PACKET_LEN+1];
spa_pkt_info_t spa_pkt; /* The current SPA packet */
/* This array holds all of the config file entry values as strings
* indexed by their tag name.
+8 -7
View File
@@ -34,21 +34,19 @@ incoming_spa(fko_srv_options_t *opts)
fko_ctx_t ctx;
int res;
spa_pkt_info_t *spa_pkt = &(opts->spa_pkt);
/* Sanity check
*/
if(opts->packet_data_len <= 0)
if(spa_pkt->packet_data_len <= 0)
return;
/* Reset the packet data length to 0.
*/
opts->packet_data_len = 0;
fprintf(stderr, "SPA Packet: '%s'\n", opts->packet_data);
fprintf(stderr, "SPA Packet: '%s'\n", spa_pkt->packet_data);
/* Get the decryption key
*/
res = fko_new_with_data(&ctx, opts->packet_data, "sdf");
res = fko_new_with_data(&ctx, spa_pkt->packet_data, "sdf");
if(res == FKO_SUCCESS)
{
@@ -63,6 +61,9 @@ fprintf(stderr, "Decode res = %i\n", res);
fprintf(stderr, "Error creating fko context: %s\n", fko_errstr(res));
}
/* Reset the packet data length to 0.
*/
spa_pkt->packet_data_len = 0;
return(0);
}
+11 -4
View File
@@ -41,17 +41,24 @@ static int static_log_flag = 0;
*/
static char *log_name = NULL;
/* Free resources allocated for logging.
*/
void
free_logging(void)
{
if(log_name != NULL)
free(log_name);
}
/* Initialize logging sets the name used for syslog.
*/
void
init_logging(fko_srv_options_t *opts) {
char *my_name = NULL;
static unsigned char linit = 0;
/* Do nothing but silently return if we have already been called.
/* In case this is a re-init.
*/
if(linit++)
return;
free_logging();
/* Allocate memory for the log_name and set the my_name to point
* to the appropriate name. If the name is set in the config file,
+2 -1
View File
@@ -5,7 +5,7 @@
*
* Author: Damien Stuart (dstuart@dstuart.org)
*
* Purpose: Header file for pcap_capture.c.
* Purpose: Header file for log_msg.c.
*
* Copyright (C) 2009 Damien Stuart (dstuart@dstuart.org)
*
@@ -39,6 +39,7 @@
#define LOG_STDERR_MASK 0x0FFF
void init_logging(fko_srv_options_t *opts);
void free_logging(void);
void set_log_facility(int fac);
void log_msg(int, char*, ...);
+20 -3
View File
@@ -29,6 +29,8 @@
#include "pcap_capture.h"
#include "process_packet.h"
#include "incoming_spa.h"
#include "config_init.h"
#include "sig_handler.h"
/* The pcap capture routine.
*/
@@ -39,13 +41,14 @@ pcap_capture(fko_srv_options_t *opts)
pcap_t *pcap;
char errstr[PCAP_ERRBUF_SIZE] = {0};
struct bpf_program fp;
int res, pcap_errcnt = 0;
int promisc = 1;
/* Set non-promiscuous mode only of the ENABLE_PCAP_POROMISC is
/* Set non-promiscuous mode only of the ENABLE_PCAP_PROMISC is
* explicitly set to 'N'.
*/
if(opts->config[CONF_ENABLE_PCAP_PROMISC] != NULL
@@ -126,16 +129,27 @@ pcap_capture(fko_srv_options_t *opts)
exit(EXIT_FAILURE);
}
/* Initialize our signal handlers. You can check the return value for
* the number of signals that were *not* set. Those that we not set
* will be listed in the log/stderr output.
*/
set_sig_handlers();
/* Jump into our home-grown packet cature loop.
*/
while(1)
{
/* Any signal except USR1 and USR2 mean break the loop.
*/
if(got_signal && (got_sigusr1 + got_sigusr2) == 0)
pcap_breakloop(pcap);
res = pcap_dispatch(pcap, 1, (pcap_handler)&process_packet, (unsigned char *)opts);
/* If there was a packet and it was processed without error, then
* keep going.
*/
if(res > 0 && opts->packet_data_len > 0)
if(res > 0 && opts->spa_pkt.packet_data_len > 0)
{
incoming_spa(opts);
@@ -162,7 +176,7 @@ pcap_capture(fko_srv_options_t *opts)
}
else if(res == -2)
{
/* pcap_break_loop was called, so we bail. */
/* pcap_breakloop was called, so we bail. */
break;
}
else
@@ -176,6 +190,9 @@ pcap_capture(fko_srv_options_t *opts)
usleep(10000);
}
#endif /* HAVE_LIBPCAP */
pcap_close(pcap);
return(0);
}
+5 -4
View File
@@ -61,7 +61,7 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header,
unsigned short eth_type;
fko_srv_options_t *opts = (fko_srv_options_t *)args;
int offset = opts->data_link_offset;
unsigned short pkt_len = packet_header->len;
@@ -164,7 +164,7 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header,
return;
/*
* Now we have data. For now we are not checking IP or port values. We
* Now we have data. For now, we are not checking IP or port values. We
* are relying on the pcap filter. This may change so we do retain the IP
* addresses and ports just in case. We just go ahead and queue the
* data.
@@ -178,8 +178,9 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header,
/* Put the data in our 1-entry queue.
*/
memcpy(opts->packet_data, pkt_data, pkt_data_len);
opts->packet_data_len = pkt_data_len;
strlcpy(opts->spa_pkt.packet_data, pkt_data, pkt_data_len+1);
opts->spa_pkt.packet_data_len = pkt_data_len;
opts->spa_pkt.packet_src_ip = src_ip;
return;
}
+115
View File
@@ -0,0 +1,115 @@
/*
*****************************************************************************
*
* File: sig_handler.c
*
* Author: Damien S. Stuart
*
* Purpose: Signal handling dta and routines for fwknopd.
*
* Copyright (C) 2009 Damien Stuart (dstuart@dstuart.org)
*
* License (GNU Public License):
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
*****************************************************************************
*/
#include "fwknopd_common.h"
#include "log_msg.h"
#include "sig_handler.h"
sig_atomic_t got_signal = 0; /* General signal flag (break capture) */
sig_atomic_t got_sighup = 0; /* SIGHUP flag */
sig_atomic_t got_sigint = 0; /* SIGINT flag */
sig_atomic_t got_sigterm = 0; /* SIGTERM flag */
sig_atomic_t got_sigusr1 = 0; /* SIGUSR1 flag */
sig_atomic_t got_sigusr2 = 0; /* SIGUSR2 flag */
/* SIGHUP Handler
*/
void
sig_handler(int sig)
{
got_signal = sig;
switch(sig) {
case SIGHUP:
got_sighup = 1;
return;
case SIGINT:
got_sigint = 1;
return;
case SIGTERM:
got_sigterm = 1;
return;
case SIGUSR1:
got_sigusr1 = 1;
return;
case SIGUSR2:
got_sigusr2 = 1;
return;
}
}
/* Setup signal handlers
*/
int
set_sig_handlers(void)
{
int err = 0;
/* Clear the signal flags.
*/
got_signal = 0;
got_sighup = 0;
got_sigint = 0;
got_sigterm = 0;
got_sigusr1 = 0;
got_sigusr2 = 0;
/* Setup the handlers */
if(signal(SIGHUP, sig_handler) == SIG_ERR)
{
log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGHUP handler");
err++;
}
if(signal(SIGINT, sig_handler) == SIG_ERR)
{
log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGINT handler");
err++;
}
if(signal(SIGTERM, sig_handler) == SIG_ERR)
{
log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGTERM handler");
err++;
}
if(signal(SIGUSR1, sig_handler) == SIG_ERR)
{
log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGUSR1 handler");
err++;
}
if(signal(SIGUSR2, sig_handler) == SIG_ERR)
{
log_msg(LOG_ERR|LOG_STDERR, "* Error setting SIGUSR2 handler");
err++;
}
return(err);
}
/***EOF***/
+43
View File
@@ -0,0 +1,43 @@
/*
*****************************************************************************
*
* File: sig_handler.h
*
* Author: Damien Stuart (dstuart@dstuart.org)
*
* Purpose: Header file for sig_handler functions and data.
*
* Copyright (C) 2009 Damien Stuart (dstuart@dstuart.org)
*
* License (GNU Public License):
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
*****************************************************************************
*/
#ifndef SIG_HANDLER_H
#define SIG_HANDLER_H
#include <signal.h>
extern sig_atomic_t got_signal;
extern sig_atomic_t got_sighup;
extern sig_atomic_t got_sigint;
extern sig_atomic_t got_sigterm;
extern sig_atomic_t got_sigusr1;
extern sig_atomic_t got_sigusr2;
void sig_handler(int sig);
#endif /* SIG_HANDLER_H */
/***EOF***/