Started firewall rule processing. Added rule initialization. Added some of the initial routines for external command execution with ability to capture stdout, stderr, and exit status.

git-svn-id: file:///home/mbr/svn/fwknop/trunk@211 510a4753-2344-4c79-9c09-4d669213fbeb
This commit is contained in:
Damien Stuart 2010-04-12 12:41:57 +00:00
parent 9282a0fd29
commit 83a10b96f6
9 changed files with 894 additions and 32 deletions

View File

@ -5,7 +5,7 @@ fwknopd_SOURCES = fwknopd.c fwknopd.h config_init.c config_init.h \
pcap_capture.c pcap_capture.h process_packet.c \
process_packet.h log_msg.c log_msg.h utils.c utils.h \
sig_handler.c sig_handler.h replay_dbm.c replay_dbm.h \
access.c access.h
access.c access.h fw_util.c fw_util.h extcmd.c extcmd.h
fwknopd_LDADD = $(top_builddir)/lib/libfko.la

View File

@ -296,6 +296,45 @@ validate_options(fko_srv_options_t *opts)
return;
}
void
set_preconfig_entries(fko_srv_options_t *opts)
{
/* First, set any default or otherwise static settings here. Some may
* 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");
/* Set the conf hostname entry here in case it is not set in the conf
* file.
*/
set_config_entry(opts, CONF_HOSTNAME, opts->hostname);
/* Setup the local executables based on build-time info.
*/
#ifdef GPG_EXE
set_config_entry(opts, CONF_EXE_GPG, GPG_EXE);
#endif
#ifdef MAIL_EXE
set_config_entry(opts, CONF_EXE_MAIL, MAIL_EXE);
#endif
#ifdef SENDMAIL_EXE
set_config_entry(opts, CONF_EXE_SENDMAIL, SENDMAIL_EXE);
#endif
#ifdef SH_EXE
set_config_entry(opts, CONF_EXE_SH, SH_EXE);
#endif
#ifdef IPTABLES_EXE
set_config_entry(opts, CONF_EXE_IPTABLES, IPTABLES_EXE);
#endif
#ifdef IPFW_EXE
set_config_entry(opts, CONF_EXE_IPFW, IPFW_EXE);
#endif
}
/* Initialize program configuration via config file and/or command-line
* switches.
*/
@ -312,18 +351,9 @@ 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 via config file or command-line.
/* Set some preconfiguration options (i.e. build-time defaults)
*/
/* Default Hostname (or unknown if gethostname cannot tell us).
*/
if(gethostname(opts->hostname, MAX_HOSTNAME_LEN-1) < 0)
strcpy(opts->hostname, "UNKNOWN");
/* Set the conf hostname entry here in case it is not set in the conf
* file.
*/
set_config_entry(opts, CONF_HOSTNAME, opts->hostname);
set_preconfig_entries(opts);
/* In case this is a re-config.
*/

261
server/extcmd.c Normal file
View File

@ -0,0 +1,261 @@
/* extcmd.c
*
* A test program to run an external command and capture its
* stdout and stderr and exit code into varaibles to print later.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/types.h>
#include <signal.h>
#include "extcmd.h"
/* Takes a file descriptor and makes it non-blocking.
*/
static int
set_nonblock(int fd)
{
int val;
if((val = fcntl(fd, F_GETFL, 0)) < 0)
{
perror("fcntl F_GETFL error:");
return(-1);
}
val |= O_NONBLOCK;
if(fcntl(fd, F_SETFL, val) < 0)
{
perror("fcntl F_SETFL error setting O_NONBLOCK");
return(-1);
}
return(0);
}
/* Run en external command returning exit status, and filling provided
* buffers with STDOUT an STDERR up to the size provided.
*/
int
run_extcmd(char *cmd, char *so_buf, char *se_buf, size_t so_buf_sz, size_t se_buf_sz, int *status)
{
pid_t pid;
struct timeval tv;
fd_set rfds;
fd_set efds;
int selval;
int so[2], se[2]; /* For our pipes */
int bytes_read;
char so_read_buf[IO_READ_BUF_LEN];
char se_read_buf[IO_READ_BUF_LEN];
/* Set our remaining_buf counters to one less than the given size so we
* can leave room for a terminating '\0'.
*/
int so_buf_remaining = (so_buf_sz > 0) ? so_buf_sz-1 : 0;
int se_buf_remaining = (se_buf_sz > 0) ? se_buf_sz-1 : 0;
/* Be optimistic :)
*/
int retval = EXTCMD_SUCCESS_ALL_OUTPUT;
/* Create the pipes we will use for getting stdout and stderr
* from the child process.
*/
pipe(so);
pipe(se);
/* Fork off a child process to run the command and provide its outputs.
*/
pid = fork();
if(pid == -1)
{
return(EXTCMD_FORK_ERROR);
}
else if (pid == 0)
{
/* We are the child, so we dup stdout and stderr to our respective
* write-end of the pipes, close stdin and the read-end of the pipes
* (since we don't need them here). Then use system() to run the
* command and exit with the exit status of that command so we can
* grab it from the waitpid call in the parent.
*/
close(fileno(stdin));
dup2(so[1], fileno(stdout));
dup2(se[1], fileno(stderr));
close(so[0]);
close(se[0]);
/* --DSS XXX: It would be more efficient to use one of the exec()
* calls. (i.e. 'return(execvp(ext_cmd, &argv[1]));' ).
* but for now, we use system() and exit with the external
* command exit status.
*/
exit(WEXITSTATUS(system(cmd)));
}
/* Parent from here */
/* Give the exit status an initial value of -1.
*/
*status = -1;
/* Close the write-end of the pipes (we are only reading).
*/
close(so[1]);
close(se[1]);
/* Set our pipes to non-blocking
*/
set_nonblock(so[0]);
set_nonblock(se[0]);
tv.tv_sec = EXTCMD_DEF_TIMEOUT;
tv.tv_usec = 0;
/* Initialize and setup our file descriptor sets for select.
*/
FD_ZERO(&rfds);
FD_ZERO(&efds);
FD_SET(so[0], &rfds);
FD_SET(se[0], &rfds);
FD_SET(so[0], &efds);
FD_SET(se[0], &efds);
/* Start with fully clear buffers.
*/
memset(so_buf, 0x0, so_buf_sz);
memset(se_buf, 0x0, se_buf_sz);
/* Read both stdout and stderr piped from the child until we get eof,
* fill the buffers, or error out.
*/
while(so_buf_remaining > 0 || se_buf_remaining > 0)
{
selval = select(8, &rfds, NULL, &efds, &tv);
if(selval == -1)
{
/* Select error - so kill the child and bail.
*/
kill(pid, SIGTERM);
return(EXTCMD_SELECT_ERROR);
}
if(selval == 0)
{
/* Timeout - so kill the child and bail
*/
kill(pid, SIGTERM);
return(retval | EXTCMD_EXECUTION_TIMEOUT);
}
/* The stdout pipe...
*/
if(so_buf_remaining > 0)
{
bytes_read = read(so[0], so_read_buf, IO_READ_BUF_LEN);
if(bytes_read > 0)
{
/* We have data, so process it...
*/
if(bytes_read > so_buf_remaining)
{
bytes_read = so_buf_remaining;
retval |= EXTCMD_SUCCESS_PARTIAL_STDOUT;
}
memcpy(so_buf, so_read_buf, bytes_read);
so_buf += bytes_read;
so_buf_remaining -= bytes_read;
}
else if(bytes_read < 0)
{
/* Anything other than EAGAIN or EWOULDBLOCK is conisdered
* error enough to bail. We are done here so we force the
* buf_remaining value to 0.
*/
if(errno != EAGAIN && errno != EWOULDBLOCK)
{
retval |= EXTCMD_STDOUT_READ_ERROR;
so_buf_remaining = 0;
}
}
else
{
/* Bytes read was 0 which indicate end of file. So we are
* done.
*/
so_buf_remaining = 0;
}
}
/* The stderr pipe...
*/
if(se_buf_remaining > 0)
{
bytes_read = read(se[0], se_read_buf, IO_READ_BUF_LEN);
if(bytes_read > 0)
{
/* We have data, so process it...
*/
if(bytes_read > se_buf_remaining)
{
bytes_read = se_buf_remaining;
retval |= EXTCMD_SUCCESS_PARTIAL_STDERR;
}
memcpy(se_buf, se_read_buf, bytes_read);
se_buf += bytes_read;
se_buf_remaining -= bytes_read;
}
else if(bytes_read < 0)
{
/* Anything other than EAGAIN or EWOULDBLOCK is conisdered
* error enough to bail. We are done here so we force the
* buf_remaining value to 0.
*/
if(errno != EAGAIN && errno != EWOULDBLOCK)
{
retval |= EXTCMD_STDERR_READ_ERROR;
se_buf_remaining = 0;
}
}
else
{
/* Bytes read was 0 which indicate end of file. So we are
* done.
*/
se_buf_remaining = 0;
}
}
}
close(so[0]);
close(se[0]);
/* Wait for the external command to finish and capture its exit status.
*/
waitpid(pid, status, 0);
if(*status != 0)
retval != EXTCMD_EXECUTION_ERROR;
/* Return the our status of this operation command.
*/
return(retval);
}

71
server/extcmd.h Normal file
View File

@ -0,0 +1,71 @@
/* $Id$
*****************************************************************************
*
* File: extcmd.h
*
* Author: Damien Stuart (dstuart@dstuart.org)
*
* Purpose: Header file for extcmd.c.
*
* Copyright (C) 2010 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 EXTCMD_H
#define EXTCMD_H
#define IO_READ_BUF_LEN 256
#define EXTCMD_DEF_TIMEOUT 15
/* The various return status states in which an external command result
* may end up in.
*/
enum {
EXTCMD_SELECT_ERROR = -2,
EXTCMD_FORK_ERROR = -1,
EXTCMD_SUCCESS_ALL_OUTPUT = 0x00,
EXTCMD_SUCCESS_PARTIAL_STDOUT = 0x01,
EXTCMD_SUCCESS_PARTIAL_STDERR = 0x02,
EXTCMD_STDOUT_READ_ERROR = 0x04,
EXTCMD_STDERR_READ_ERROR = 0x08,
EXTCMD_EXECUTION_ERROR = 0x10,
EXTCMD_EXECUTION_TIMEOUT = 0x20
};
/* Some convenience macros for testing the extcmd return status.
*/
#define EXTCMD_IS_SUCCESS(x) (x == EXTCMD_SUCCESS_ALL_OUTPUT)
#define EXTCMD_IS_SUCCESS_PARTIAL_STDOUT(x) (x && EXTCMD_SUCCESS_PARTIAL_STDOUT)
#define EXTCMD_IS_SUCCESS_PARTIAL_STDERR(x) (x && EXTCMD_SUCCESS_PARTIAL_STDERR)
#define EXTCMD_IS_SUCCESS_PARTIAL_OUTPUT(x) \
((x && EXTCMD_SUCCESS_PARTIAL_STDOUT) \
|| x && EXTCMD_SUCCESS_PARTIAL_STDERR)
#define EXTCMD_STDOUT_READ_ERROR(x) (x && EXTCMD_STDOUT_READ_ERROR)
#define EXTCMD_STDERR_READ_ERROR(x) (x && EXTCMD_STDERR_READ_ERROR)
#define EXTCMD_READ_ERROR(x) \
((x && EXTCMD_STDOUT_READ_ERROR) \
|| x && EXTCMD_STDERR_READ_ERROR)
#define EXTCMD_EXECUTION_ERROR(x) (x && EXTCMD_EXECUTION_ERROR)
#define EXTCMD_NOERROR(x,y) ((y == 0) \
&& (EXTCMD_IS_SUCCESS(x) || EXTCMD_IS_SUCCESS_PARTIAL_OUTPUT(x))
/* Function prototypes
*/
int run_extcmd(char *cmd, char *so_buf, char *se_buf, size_t so_buf_sz, size_t se_buf_sz, int *status);
#endif /* EXTCMD_H */
/***EOF***/

384
server/fw_util.c Normal file
View File

@ -0,0 +1,384 @@
/* $Id$
*****************************************************************************
*
* File: fw_util.c
*
* Author: Damien S. Stuart
*
* Purpose: Fwknop routines for managing the firewall rules.
*
* Copyright (C) 2010 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 "fw_util.h"
#include "log_msg.h"
#include "config_init.h" /* for the IS_EMPTY_LINE macro */
#include "extcmd.h"
static struct fw_config fwc;
static void
parse_extcmd_error(int retval, int status, char *se_buf)
{
char errmsg[256];
char *emptr = errmsg;
if(retval < 0)
{
log_msg(LOG_ERR|LOG_STDERR, "Extcmd fork error: %s", strerror(errno));
return;
}
sprintf(emptr, "Extcmd return: %i, command exit status: %i", retval, status);
emptr += strlen(emptr);
if(EXTCMD_EXECUTION_ERROR(retval))
{
sprintf(errmsg, "Extcmd stderr=%s", se_buf);
emptr += strlen(emptr);
}
if(EXTCMD_IS_SUCCESS_PARTIAL_STDOUT(retval))
{
sprintf(errmsg, "\n - Got partial stdout");
emptr += strlen(emptr);
}
if(EXTCMD_IS_SUCCESS_PARTIAL_STDERR(retval))
{
sprintf(errmsg, "\n - Got partial stderr");
emptr += strlen(emptr);
}
if(EXTCMD_STDOUT_READ_ERROR(retval))
{
sprintf(errmsg, "\n - Got read error on stdout");
emptr += strlen(emptr);
}
if(EXTCMD_STDERR_READ_ERROR(retval))
{
sprintf(errmsg, "\n - Got read error on stderr");
emptr += strlen(emptr);
}
log_msg(LOG_WARNING|LOG_STDERR, errmsg);
}
static int
jump_rule_exists(int chain_num)
{
int num, x, pos = 0;
char cmd_buf[256];
char target[256];
char line_buf[256] = {0};
FILE *ipt;
sprintf(cmd_buf, "%s " IPT_LIST_RULES_ARGS,
fwc.fw_command,
fwc.chain[chain_num].table,
fwc.chain[chain_num].from_chain
);
ipt = popen(cmd_buf, "r");
if(ipt == NULL)
{
log_msg(LOG_ERR|LOG_STDERR,
"Got error %i trying to get rules list.\n", errno);
return(-1);
}
while((fgets(line_buf, 255, ipt)) != NULL)
{
/* Get past comments and empty lines (note: we only look at the
* first character.
*/
if(IS_EMPTY_LINE(line_buf[0]))
continue;
if(sscanf(line_buf, "%i %s ", &num, target) == 2)
{
//printf("GOT MATCH: '%s' - (pos=%i, target=%s)\n",
// line_buf, num, target);
if(strcmp(target, fwc.chain[chain_num].to_chain) == 0)
{
pos = num;
break;
}
}
}
pclose(ipt);
return(pos);
}
/* Quietly flush and delete all fwknop custom chains.
*/
static void
delete_all_chains(void)
{
int i, pos, res, status;
int jump_rule_num;
char cmd_buf[256];
char err[256];
for(i=0; i<(NUM_FWKNOP_CHAIN_TYPES-1); i++)
{
if(fwc.chain[i].target[0] == '\0')
continue;
/* First look for a jump rule to this chain and remove it if it
* is there.
*/
if((jump_rule_num = jump_rule_exists(i)) > 0)
{
sprintf(cmd_buf, "%s " IPT_DEL_RULE_ARGS,
fwc.fw_command,
fwc.chain[i].table,
fwc.chain[i].from_chain,
jump_rule_num
);
//printf("CMD: '%s'\n", cmd_buf);
//system(cmd_buf);
res = run_extcmd(cmd_buf, NULL, err, 0, 256, &status);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
parse_extcmd_error(res, status, err);
}
/* Now flush and remove the chain.
*/
sprintf(cmd_buf,
"(%s " IPT_FLUSH_CHAIN_ARGS "; %s " IPT_DEL_CHAIN_ARGS ")", // > /dev/null 2>&1",
fwc.fw_command,
fwc.chain[i].table,
fwc.chain[i].to_chain,
fwc.fw_command,
fwc.chain[i].table,
fwc.chain[i].to_chain
);
//printf("CMD: '%s'\n", cmd_buf);
//system(cmd_buf);
res = run_extcmd(cmd_buf, NULL, err, 0, 256, &status);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
parse_extcmd_error(res, status, err);
}
}
/* Create the fwknop custom chains (at least those that are configured).
*/
static int
create_fw_chains(void)
{
int i;
int res, status, got_err = 0;
char cmd_buf[256];
char err[256];
for(i=0; i<(NUM_FWKNOP_CHAIN_TYPES-1); i++)
{
if(fwc.chain[i].target[0] == '\0')
continue;
/* Create the custom chain.
*/
sprintf(cmd_buf, "%s " IPT_NEW_CHAIN_ARGS,
fwc.fw_command,
fwc.chain[i].table,
fwc.chain[i].to_chain
);
//printf("CMD: '%s'\n", cmd_buf);
//res = system(cmd_buf);
res = run_extcmd(cmd_buf, NULL, err, 0, 256, &status);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
{
parse_extcmd_error(res, status, err);
got_err++;
}
/* Then create the jump rule to that chain.
*/
sprintf(cmd_buf, "%s " IPT_ADD_JUMP_RULE_ARGS,
fwc.fw_command,
fwc.chain[i].table,
fwc.chain[i].from_chain,
fwc.chain[i].jump_rule_pos,
fwc.chain[i].to_chain
);
//printf("CMD: '%s'\n", cmd_buf);
//res = system(cmd_buf);
res = run_extcmd(cmd_buf, NULL, err, 0, 256, &status);
/* Expect full success on this */
if(! EXTCMD_IS_SUCCESS(res))
{
parse_extcmd_error(res, status, err);
got_err++;
}
}
return(got_err);
}
static void
set_fw_chain_conf(int type, char *conf_str)
{
int i, j;
char *mark;
char tbuf[1024] = {0};
char *ndx = conf_str;
char *chain_fields[FW_NUM_CHAIN_FIELDS];
struct fw_chain *chain = &(fwc.chain[type]);
chain->type = type;
if(ndx != NULL)
chain_fields[0] = tbuf;
i = 0;
j = 1;
while(*ndx != '\0')
{
if(*ndx != ' ')
{
if(*ndx == ',')
{
tbuf[i] = '\0';
chain_fields[j++] = &(tbuf[++i]);
}
else
tbuf[i++] = *ndx;
}
ndx++;
}
/* Sanity check - j should be the number of chain fields
* (excluding the type).
*/
if(j != FW_NUM_CHAIN_FIELDS)
{
fprintf(stderr, "[*] Custom Chain config parse error.\n"
"Wrong number of fields for chain type %i\n"
"Line: %s\n", type, conf_str);
exit(EXIT_FAILURE);
}
/* Pull and set Target */
strlcpy(chain->target, chain_fields[0], MAX_TARGET_NAME_LEN);
/* Pull and set Direction */
if(strcmp(chain_fields[1], FW_CHAIN_DIR_SRC_STR) == 0)
chain->direction = FW_CHAIN_DIR_SRC;
else if(strcmp(chain_fields[1], FW_CHAIN_DIR_DST_STR) == 0)
chain->direction = FW_CHAIN_DIR_DST;
else if(strcmp(chain_fields[1], FW_CHAIN_DIR_BOTH_STR) == 0)
chain->direction = FW_CHAIN_DIR_BOTH;
else
chain->direction = FW_CHAIN_DIR_UNKNOWN;
/* Pull and set Table */
strlcpy(chain->table, chain_fields[2], MAX_TABLE_NAME_LEN);
/* Pull and set From_chain */
strlcpy(chain->from_chain, chain_fields[3], MAX_CHAIN_NAME_LEN);
/* Pull and set Jump_rule_position */
chain->jump_rule_pos = atoi(chain_fields[4]);
/* Pull and set To_chain */
strlcpy(chain->to_chain, chain_fields[5], MAX_CHAIN_NAME_LEN);
/* Pull and set Jump_rule_position */
chain->rule_pos = atoi(chain_fields[6]);
}
void
fw_initialize(fko_srv_options_t *opts)
{
int res;
memset(&fwc, 0x0, sizeof(struct fw_config));
/* Set our firewall exe command path (iptables in most cases).
*/
strlcpy(fwc.fw_command, opts->config[CONF_EXE_IPTABLES], MAX_PATH_LEN);
/* Pull the fwknop chain config info and setup our internal
* config struct. The IPT_INPUT is the only one that is
* required. The rest are optional.
*/
if(opts->config[CONF_IPT_INPUT_ACCESS] != NULL)
set_fw_chain_conf(IPT_INPUT_ACCESS, opts->config[CONF_IPT_INPUT_ACCESS]);
else
{
fprintf(stderr, "The IPT_INPUT_ACCESS chain must be defined in the config file.\n");
exit(EXIT_FAILURE);
}
if(opts->config[CONF_IPT_OUTPUT_ACCESS] != NULL)
set_fw_chain_conf(IPT_OUTPUT_ACCESS, opts->config[CONF_IPT_OUTPUT_ACCESS]);
if(opts->config[CONF_IPT_FORWARD_ACCESS] != NULL)
set_fw_chain_conf(IPT_FORWARD_ACCESS, opts->config[CONF_IPT_FORWARD_ACCESS]);
if(opts->config[CONF_IPT_DNAT_ACCESS] != NULL)
set_fw_chain_conf(IPT_DNAT_ACCESS, opts->config[CONF_IPT_DNAT_ACCESS]);
if(opts->config[CONF_IPT_SNAT_ACCESS] != NULL)
set_fw_chain_conf(IPT_SNAT_ACCESS, opts->config[CONF_IPT_SNAT_ACCESS]);
if(opts->config[CONF_IPT_MASQUERADE_ACCESS] != NULL)
set_fw_chain_conf(IPT_MASQUERADE_ACCESS, opts->config[CONF_IPT_MASQUERADE_ACCESS]);
/* Let us find it via our opts struct as well.
*/
opts->fw_config = &fwc;
/* Flush the chains (just in case) so we can start fresh.
*/
delete_all_chains();
/* Now create any configured chains.
*/
res = create_fw_chains();
if(res != 0)
{
fprintf(stderr, "Warning: Errors detected during fwknop custom chain creation.\n");
exit(EXIT_FAILURE);
}
}
void
fw_cleanup(void)
{
delete_all_chains();
}
/***EOF***/

36
server/fw_util.h Normal file
View File

@ -0,0 +1,36 @@
/* $Id$
*****************************************************************************
*
* File: fw_util.h
*
* Author: Damien Stuart (dstuart@dstuart.org)
*
* Purpose: Header file for fw_util.c.
*
* Copyright (C) 2010 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 FW_UTIL_H
#define FW_UTIL_H
/* Function prototypes
*/
void fw_initialize(fko_srv_options_t *opts);
void fw_cleanup(void);
#endif /* FW_UTIL_H */
/***EOF***/

View File

@ -238,6 +238,10 @@ main(int argc, char **argv)
);
}
/* Initialize the firewall rules handler.
*/
fw_initialize(&opts);
/* Intiate pcap capture mode...
*/
pcap_capture(&opts);
@ -287,6 +291,7 @@ main(int argc, char **argv)
/* Other cleanup.
*/
fw_cleanup();
free_logging();
free_configs(&opts);

View File

@ -46,7 +46,7 @@ PCAP_INTF eth0;
# By default fwknopd puts the pcap interface into promiscuous mode. Set
# this to 'N' to disable that behavior (non-promiscuous).
#
#ENABLE_PCAP_PROMISC N;
ENABLE_PCAP_PROMISC Y;
# Define the filter used for PCAP modes; we default to udp port 62201.
# However, if an fwknop client uses the --rand-port option to send the
@ -276,22 +276,25 @@ IPT_EXEC_TRIES 1;
# "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
#

View File

@ -149,12 +149,12 @@ enum {
//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_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,
@ -232,12 +232,12 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
//"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",
"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",
@ -314,6 +314,74 @@ typedef struct acc_stanza
struct acc_stanza *next;
} acc_stanza_t;
/* Firewall-related data and types. */
/* --DSS XXX: These are arbitrary. We should determine appropriate values.
*/
#define MAX_TABLE_NAME_LEN 16
#define MAX_CHAIN_NAME_LEN 32
#define MAX_TARGET_NAME_LEN 32
#define MAX_FW_COMMAND_ARGS_LEN 256
/* iptables command args
*/
#define IPT_ADD_RULE_ARGS "-t %s -I %s %i -p %s -s %s -d %s --dport %s -j %s"
#define IPT_DEL_RULE_ARGS "-t %s -D %s %i"
#define IPT_NEW_CHAIN_ARGS "-t %s -N %s"
#define IPT_FLUSH_CHAIN_ARGS "-t %s -F %s"
#define IPT_DEL_CHAIN_ARGS "-t %s -X %s"
#define IPT_ADD_JUMP_RULE_ARGS "-t %s -I %s %i -j %s"
#define IPT_LIST_RULES_ARGS " -t %s -L %s --line-numbers -n"
/* Fwknop custom chain types
*/
enum {
IPT_INPUT_ACCESS,
IPT_OUTPUT_ACCESS,
IPT_FORWARD_ACCESS,
IPT_DNAT_ACCESS,
IPT_SNAT_ACCESS,
IPT_MASQUERADE_ACCESS,
NUM_FWKNOP_CHAIN_TYPES /* Leave this entry last */
};
#define FW_CHAIN_DIR_SRC_STR "src"
#define FW_CHAIN_DIR_DST_STR "dst"
#define FW_CHAIN_DIR_BOTH_STR "both"
/* Fwknop chain directions
*/
enum {
FW_CHAIN_DIR_UNKNOWN,
FW_CHAIN_DIR_SRC,
FW_CHAIN_DIR_DST,
FW_CHAIN_DIR_BOTH
};
/* Structure to define an fwknop firewall chain configuration.
*/
struct fw_chain {
int type;
char target[MAX_TARGET_NAME_LEN];
int direction;
char table[MAX_TABLE_NAME_LEN];
char from_chain[MAX_CHAIN_NAME_LEN];
int jump_rule_pos;
char to_chain[MAX_CHAIN_NAME_LEN];
int rule_pos;
};
/* Based on the fw_chain fields (not counting type)
*/
#define FW_NUM_CHAIN_FIELDS 7
struct fw_config {
struct fw_chain chain[NUM_FWKNOP_CHAIN_TYPES];
char fw_command[MAX_PATH_LEN];
};
/* SPA Packet info struct.
*/
typedef struct spa_pkt_info
@ -354,7 +422,11 @@ typedef struct fko_srv_options
*/
char *config[NUMBER_OF_CONFIG_ENTRIES];
acc_stanza_t *acc_stanzas; /* List of access stanzas */
acc_stanza_t *acc_stanzas; /* List of access stanzas */
/* Firewall config info.
*/
struct fw_config *fw_config;
/* Misc
*/