PF support on OpenBSD in progress, fwknop --fw-list now works
This is the first commit that has fwknopd interact with the PF firewall on OpenBSD (via fwknopd --fw-list to show any active fwknopd rules).
This commit is contained in:
+10
-1
@@ -46,6 +46,15 @@
|
||||
#if HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#if PLATFORM_OPENBSD /* OpenBSD hack due to autoconf net/if.h difficulties */
|
||||
#include <net/if.h>
|
||||
#include <net/ethertypes.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#ifndef ETHER_IS_VALID_LEN
|
||||
#define ETHER_IS_VALID_LEN(x) \
|
||||
((x) >= ETHER_MIN_LEN && (x) <= ETHER_MAX_LEN)
|
||||
#endif
|
||||
#endif
|
||||
#if HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
@@ -62,7 +71,7 @@
|
||||
#endif
|
||||
|
||||
/* We will roll our own packet header structs. */
|
||||
|
||||
|
||||
/* The IP header
|
||||
*/
|
||||
struct iphdr
|
||||
|
||||
+3
-2
@@ -158,7 +158,7 @@ case "$host" in
|
||||
*-*-freebsd*)
|
||||
# disable read-only relocations and immediate binding protection on FreeBSD
|
||||
# due the following errors (there is probably a solution to this in another
|
||||
# way, please email Michael Rash mbr.at.cipherdyne.org
|
||||
# way, please email Michael Rash mbr.at.cipherdyne.org)
|
||||
# gcc: -z: linker input file unused because linking not done
|
||||
# gcc: relro: linker input file unused because linking not done
|
||||
# gcc: -z: linker input file unused because linking not done
|
||||
@@ -169,13 +169,14 @@ case "$host" in
|
||||
*-*-openbsd*)
|
||||
# disable read-only relocations and immediate binding protection on FreeBSD
|
||||
# due the following errors (there is probably a solution to this in another
|
||||
# way, please email Michael Rash mbr.at.cipherdyne.org
|
||||
# way, please email Michael Rash mbr.at.cipherdyne.org)
|
||||
# gcc: -z: linker input file unused because linking not done
|
||||
# gcc: relro: linker input file unused because linking not done
|
||||
# gcc: -z: linker input file unused because linking not done
|
||||
# gcc: now: linker input file unused because linking not done
|
||||
use_ro_relocations=no
|
||||
use_immediate_binding=no
|
||||
AC_DEFINE_UNQUOTED([PLATFORM_OPENBSD], [1], [Define if you are running on OpenBSD])
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
+4
-3
@@ -7,9 +7,10 @@ fwknopd_SOURCES = fwknopd.c fwknopd.h config_init.c config_init.h \
|
||||
sig_handler.c sig_handler.h replay_cache.c replay_cache.h \
|
||||
access.c access.h fwknopd_errors.c fwknopd_errors.h \
|
||||
tcp_server.c tcp_server.h extcmd.c extcmd.h \
|
||||
fw_util.c fw_util.h fw_util_ipf.c fw_util_ipf.h \
|
||||
fw_util_iptables.c fw_util_iptables.h \
|
||||
fw_util_ipfw.c fw_util_ipfw.h
|
||||
fw_util.c fw_util.h fw_util_ipf.c fw_util_ipf.h \
|
||||
fw_util_iptables.c fw_util_iptables.h \
|
||||
fw_util_ipfw.c fw_util_ipfw.h \
|
||||
fw_util_pf.c fw_util_pf.h
|
||||
|
||||
fwknopd_LDADD = $(top_builddir)/lib/libfko.la -lpcap
|
||||
|
||||
|
||||
+7
-7
@@ -33,10 +33,10 @@
|
||||
#if HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#include <arpa/inet.h>
|
||||
#include "pwd.h"
|
||||
|
||||
#include "fwknopd_common.h"
|
||||
#include <arpa/inet.h>
|
||||
#include "pwd.h"
|
||||
#include "access.h"
|
||||
#include "utils.h"
|
||||
#include "log_msg.h"
|
||||
@@ -52,7 +52,7 @@ add_acc_string(char **var, char *val)
|
||||
"Fatal memory allocation error adding access list entry: %s", var
|
||||
);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Add an access int entry
|
||||
@@ -206,7 +206,7 @@ parse_proto_and_port(char *pstr, int *proto, int *port)
|
||||
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
strlcpy(proto_str, pstr, (ndx - pstr)+1);
|
||||
|
||||
*port = atoi(ndx+1);
|
||||
@@ -537,7 +537,7 @@ acc_stanza_init(fko_srv_options_t *opts)
|
||||
free_acc_stanza_data(last_acc);
|
||||
free(last_acc);
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -571,10 +571,10 @@ acc_stanza_add(fko_srv_options_t *opts)
|
||||
do {
|
||||
last_acc = acc;
|
||||
} while((acc = acc->next));
|
||||
|
||||
|
||||
last_acc->next = new_acc;
|
||||
}
|
||||
|
||||
|
||||
return(new_acc);
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -83,9 +83,10 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
|
||||
"IPFW_EXPIRE_SET_NUM",
|
||||
"IPFW_EXPIRE_PURGE_INTERVAL",
|
||||
"IPFW_ADD_CHECK_STATE",
|
||||
#elif FIREWALL_IPF
|
||||
/* --DSS Place-holder */
|
||||
#elif FIREWALL_PF
|
||||
"PF_ANCHOR_NAME",
|
||||
"PF_EXPIRE_INTERVAL",
|
||||
#elif FIREWALL_IPF
|
||||
/* --DSS Place-holder */
|
||||
#endif /* FIREWALL type */
|
||||
"FWKNOP_RUN_DIR",
|
||||
@@ -99,7 +100,7 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
|
||||
#endif
|
||||
"GPG_HOME_DIR",
|
||||
"FIREWALL_EXE",
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/* Long options values (for those that may not have a short option).
|
||||
|
||||
+12
-4
@@ -419,12 +419,20 @@ validate_options(fko_srv_options_t *opts)
|
||||
set_config_entry(opts, CONF_IPFW_ADD_CHECK_STATE,
|
||||
DEF_IPFW_ADD_CHECK_STATE);
|
||||
|
||||
#elif FIREWALL_IPF
|
||||
|
||||
/* --DSS Place-holder */
|
||||
|
||||
#elif FIREWALL_PF
|
||||
/* Set PF anchor name
|
||||
*/
|
||||
if(opts->config[CONF_PF_ANCHOR_NAME] == NULL)
|
||||
set_config_entry(opts, CONF_PF_ANCHOR_NAME,
|
||||
DEF_PF_ANCHOR_NAME);
|
||||
|
||||
/* Set PF rule expiry interval.
|
||||
*/
|
||||
if(opts->config[CONF_PF_EXPIRE_INTERVAL] == NULL)
|
||||
set_config_entry(opts, CONF_PF_EXPIRE_INTERVAL,
|
||||
DEF_PF_EXPIRE_INTERVAL);
|
||||
|
||||
#elif FIREWALL_IPF
|
||||
/* --DSS Place-holder */
|
||||
|
||||
#endif /* FIREWALL type */
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "fw_util_iptables.h"
|
||||
#elif FIREWALL_IPFW
|
||||
#include "fw_util_ipfw.h"
|
||||
#elif FIREWALL_PF
|
||||
#include "fw_util_pf.h"
|
||||
#elif FIREWALL_IPF
|
||||
#include "fw_util_ipf.h"
|
||||
#endif
|
||||
|
||||
@@ -43,7 +43,7 @@ static char cmd_buf[CMD_BUFSIZE];
|
||||
static char err_buf[CMD_BUFSIZE];
|
||||
static char cmd_out[STANDARD_CMD_OUT_BUFSIZE];
|
||||
|
||||
unsigned short
|
||||
static unsigned short
|
||||
get_next_rule_num(void)
|
||||
{
|
||||
unsigned short i;
|
||||
@@ -57,7 +57,7 @@ get_next_rule_num(void)
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
zero_cmd_buffers(void)
|
||||
{
|
||||
memset(cmd_buf, 0x0, CMD_BUFSIZE);
|
||||
@@ -255,7 +255,7 @@ fw_initialize(fko_srv_options_t *opts)
|
||||
/* Find the first "# DISABLED" string (if any).
|
||||
*/
|
||||
ndx = strstr(cmd_out, "# DISABLED ");
|
||||
|
||||
|
||||
/* Assume no disabled rules if we did not see the string.
|
||||
*/
|
||||
if(ndx == NULL)
|
||||
|
||||
@@ -44,7 +44,7 @@ static char cmd_buf[CMD_BUFSIZE];
|
||||
static char err_buf[CMD_BUFSIZE];
|
||||
static char cmd_out[STANDARD_CMD_OUT_BUFSIZE];
|
||||
|
||||
void
|
||||
static void
|
||||
zero_cmd_buffers(void)
|
||||
{
|
||||
memset(cmd_buf, 0x0, CMD_BUFSIZE);
|
||||
|
||||
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
*****************************************************************************
|
||||
*
|
||||
* File: fw_util_pf.c
|
||||
*
|
||||
* Author: Damien S. Stuart, Michael Rash
|
||||
*
|
||||
* Purpose: Fwknop routines for managing pf firewall rules.
|
||||
*
|
||||
* Copyright 2010 Damien Stuart (dstuart@dstuart.org)
|
||||
*
|
||||
* License (GNU Public License):
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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"
|
||||
|
||||
#if FIREWALL_PF
|
||||
|
||||
#include "fw_util.h"
|
||||
#include "utils.h"
|
||||
#include "log_msg.h"
|
||||
#include "extcmd.h"
|
||||
#include "access.h"
|
||||
|
||||
static struct fw_config fwc;
|
||||
static char cmd_buf[CMD_BUFSIZE];
|
||||
static char err_buf[CMD_BUFSIZE];
|
||||
static char cmd_out[STANDARD_CMD_OUT_BUFSIZE];
|
||||
|
||||
static void
|
||||
zero_cmd_buffers(void)
|
||||
{
|
||||
memset(cmd_buf, 0x0, CMD_BUFSIZE);
|
||||
memset(err_buf, 0x0, CMD_BUFSIZE);
|
||||
memset(cmd_out, 0x0, STANDARD_CMD_OUT_BUFSIZE);
|
||||
}
|
||||
|
||||
/* Print all firewall rules currently instantiated by the running fwknopd
|
||||
* daemon to stdout.
|
||||
*/
|
||||
int
|
||||
fw_dump_rules(fko_srv_options_t *opts)
|
||||
{
|
||||
int i = 0;
|
||||
int res, got_err = 0;
|
||||
|
||||
zero_cmd_buffers();
|
||||
|
||||
/* Create the list command for active rules
|
||||
*/
|
||||
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " PF_LIST_RULES_ARGS,
|
||||
opts->fw_config->fw_command,
|
||||
opts->fw_config->anchor
|
||||
);
|
||||
|
||||
printf("\nActive Rules in PF anchor: %s:\n", opts->fw_config->anchor);
|
||||
res = system(cmd_buf);
|
||||
|
||||
/* Expect full success on this */
|
||||
if(! EXTCMD_IS_SUCCESS(res))
|
||||
{
|
||||
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
|
||||
got_err++;
|
||||
}
|
||||
|
||||
return(got_err);
|
||||
}
|
||||
|
||||
void
|
||||
fw_config_init(fko_srv_options_t *opts)
|
||||
{
|
||||
memset(&fwc, 0x0, sizeof(struct fw_config));
|
||||
|
||||
/* Set our firewall exe command path (iptables in most cases).
|
||||
*/
|
||||
strlcpy(fwc.fw_command, opts->config[CONF_FIREWALL_EXE], MAX_PATH_LEN);
|
||||
|
||||
/* Set the PF anchor name
|
||||
*/
|
||||
strlcpy(fwc.anchor, opts->config[CONF_PF_ANCHOR_NAME], MAX_PF_ANCHOR_LEN);
|
||||
|
||||
/* Let us find it via our opts struct as well.
|
||||
*/
|
||||
opts->fw_config = &fwc;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
fw_initialize(fko_srv_options_t *opts)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
if(res != 0)
|
||||
{
|
||||
fprintf(stderr, "Warning: Errors detected during fwknop custom chain creation.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
fw_cleanup(void)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* Rule Processing - Create an access request...
|
||||
*/
|
||||
int
|
||||
process_spa_request(fko_srv_options_t *opts, spa_data_t *spadat)
|
||||
{
|
||||
char nat_ip[16] = {0};
|
||||
char *ndx;
|
||||
|
||||
unsigned int nat_port = 0;;
|
||||
|
||||
acc_port_list_t *port_list = NULL;
|
||||
acc_port_list_t *ple;
|
||||
|
||||
unsigned int fst_proto;
|
||||
unsigned int fst_port;
|
||||
|
||||
int res = 0;
|
||||
time_t now;
|
||||
unsigned int exp_ts;
|
||||
|
||||
/* Parse and expand our access message.
|
||||
*/
|
||||
expand_acc_port_list(&port_list, spadat->spa_message_remain);
|
||||
|
||||
/* Start at the top of the proto-port list...
|
||||
*/
|
||||
ple = port_list;
|
||||
|
||||
/* Remember the first proto/port combo in case we need them
|
||||
* for NAT access requests.
|
||||
*/
|
||||
fst_proto = ple->proto;
|
||||
fst_port = ple->port;
|
||||
|
||||
/* Set our expire time value.
|
||||
*/
|
||||
time(&now);
|
||||
exp_ts = now + spadat->fw_access_timeout;
|
||||
|
||||
return(res);
|
||||
}
|
||||
|
||||
/* Iterate over the configure firewall access chains and purge expired
|
||||
* firewall rules.
|
||||
*/
|
||||
void
|
||||
check_firewall_rules(fko_srv_options_t *opts)
|
||||
{
|
||||
char exp_str[12];
|
||||
char rule_num_str[6];
|
||||
char *ndx, *rn_start, *rn_end, *tmp_mark;
|
||||
|
||||
int i, res, rn_offset;
|
||||
time_t now, rule_exp, min_exp = 0;
|
||||
|
||||
time(&now);
|
||||
|
||||
zero_cmd_buffers();
|
||||
}
|
||||
|
||||
#endif /* FIREWALL_PF */
|
||||
|
||||
/***EOF***/
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
*****************************************************************************
|
||||
*
|
||||
* File: fw_util_pf.h
|
||||
*
|
||||
* Author: Damien Stuart (dstuart@dstuart.org), Michael Rash
|
||||
* (mbr@cipherdyne.org)
|
||||
*
|
||||
* Purpose: Header file for fw_util_pf.c.
|
||||
*
|
||||
* Copyright 2010 Damien Stuart (dstuart@dstuart.org)
|
||||
*
|
||||
* License (GNU Public License):
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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_PF_H
|
||||
#define FW_UTIL_PF_H
|
||||
|
||||
/* pf command args
|
||||
*/
|
||||
#define PF_LIST_RULES_ARGS "-a %s -s rules"
|
||||
#define PF_LIST_ALL_RULES_ARGS "-s rules" /* to check for fwknop anchor */
|
||||
|
||||
#endif /* FW_UTIL_PF_H */
|
||||
|
||||
/***EOF***/
|
||||
@@ -290,6 +290,22 @@
|
||||
#
|
||||
# IPFW_ADD_CHECK_STATE N;
|
||||
|
||||
##############################################################################
|
||||
# Parameters specific to the pf firewall:
|
||||
#
|
||||
#
|
||||
# This variable defines the pf anchor name to which fwknopd will add and
|
||||
# delete rules. This anchor must be linked into the pf policy (typically
|
||||
# done by adding it into the /etc/pf.conf file), and fwknopd runs a check at
|
||||
# init time to ensure that the anchor exists.
|
||||
#
|
||||
#PF_ANCHOR_NAME fwknop;
|
||||
|
||||
# Set the interval (in seconds) over which rules that are expired
|
||||
#
|
||||
#PF_EXPIRE_INTERVAL 30;
|
||||
|
||||
|
||||
# Directories - These can override compile-time defaults.
|
||||
#
|
||||
#FWKNOP_RUN_DIR /var/run/fwknop;
|
||||
|
||||
+22
-10
@@ -33,6 +33,10 @@
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#if PLATFORM_OPENBSD
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_SYS_STAT_H
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
@@ -122,12 +126,13 @@
|
||||
#define DEF_IPFW_EXPIRE_PURGE_INTERVAL "30"
|
||||
#define DEF_IPFW_ADD_CHECK_STATE "N"
|
||||
|
||||
#elif FIREWALL_IPF
|
||||
|
||||
/* --DSS Place-holder */
|
||||
|
||||
#elif FIREWALL_PF
|
||||
|
||||
#define DEF_PF_ANCHOR_NAME "fwknop"
|
||||
#define DEF_PF_EXPIRE_INTERVAL "30"
|
||||
|
||||
#elif FIREWALL_IPF
|
||||
|
||||
/* --DSS Place-holder */
|
||||
|
||||
#endif /* FIREWALL Type */
|
||||
@@ -197,9 +202,10 @@ enum {
|
||||
CONF_IPFW_EXPIRE_SET_NUM,
|
||||
CONF_IPFW_EXPIRE_PURGE_INTERVAL,
|
||||
CONF_IPFW_ADD_CHECK_STATE,
|
||||
#elif FIREWALL_IPF
|
||||
/* --DSS Place-holder */
|
||||
#elif FIREWALL_PF
|
||||
CONF_PF_ANCHOR_NAME,
|
||||
CONF_PF_EXPIRE_INTERVAL,
|
||||
#elif FIREWALL_IPF
|
||||
/* --DSS Place-holder */
|
||||
#endif /* FIREWALL type */
|
||||
CONF_FWKNOP_RUN_DIR,
|
||||
@@ -335,12 +341,18 @@ typedef struct acc_stanza
|
||||
char fw_command[MAX_PATH_LEN];
|
||||
};
|
||||
|
||||
#elif FIREWALL_IPF
|
||||
|
||||
/* --DSS Place-holder */
|
||||
|
||||
#elif FIREWALL_PF
|
||||
|
||||
#define MAX_PF_ANCHOR_LEN 64
|
||||
|
||||
struct fw_config {
|
||||
time_t next_expire;
|
||||
char anchor[MAX_PF_ANCHOR_LEN];
|
||||
char fw_command[MAX_PATH_LEN];
|
||||
};
|
||||
|
||||
#elif FIREWALL_IPF
|
||||
|
||||
/* --DSS Place-holder */
|
||||
|
||||
#endif /* FIREWALL type */
|
||||
|
||||
Reference in New Issue
Block a user