merged from master

This commit is contained in:
Michael Rash
2012-08-10 22:30:07 -04:00
19 changed files with 368 additions and 71 deletions
+12
View File
@@ -36,3 +36,15 @@ Franck Joncourt
Jonathan Schulz
- Submitted patches to change HTTP connection type to 'close' for -R mode
in the client and fix a bug for recv() calls against returned HTTP data.
Aldan Beaubien
- Reported an issue with the Morpheus client sending SPA packets with NULL
IP addresses, and code was added to fwknopd to better validate incoming
SPA data as a result of this report.
Geoff Carstairs
- Suggested a way to redirect valid connection requests to a specific
internal service via NAT, configurable by each stanza in access.conf.
This allows for better access control for multple users requiring access
to multiple internal systems, in a manner that is transparent to the
user. The result was the FORCE_NAT mode.
+23
View File
@@ -1,4 +1,16 @@
fwknop-2.0.2 (08//2012):
- [server] For GPG mode, added a new access.conf variable
"GPG_ALLOW_NO_PW" to make it possible to leverage a server-side GPG key
pair that has no associated password. This comes in handy when a system
requires the user to leverage gpg-agent / pinentry which can present a
problem in automated environments as required by the fwknopd server.
Now, it might seem like a problem to remove the passphrase from a GPG
key pair, but it's important to note that simply doing this is little
worse than storing the passphrase in the clear on disk anyway in the
access.conf file. Further, this link helps provide additional detail:
http://www.gnupg.org/faq/GnuPG-FAQ.html#how-can-i-use-gnupg-in-an-automated-environment
- [client] In IP resolution mode (-R) changed HTTP connection type to
'close' since there is no need for connection persistence, and indeed the
client expects to just get the IP and the connection to be closed.
@@ -7,6 +19,14 @@ fwknop-2.0.2 (08//2012):
remote webserver IP resolution mode (-R). Previously IP resolution
could fail if HTTP headers were transferred separately from the data
(for whatever reason). Jonathan Schulz submitted a patch for this.
- [server] Bug fix to implement FLUSH_IPT_AT_INIT and FLUSH_IPT_AT_EXIT
functionality. These are enabled by default, and now iptables rules
added by fwknopd can be made persistant by setting these variables to
"N" in the fwknopd.conf file (this is not a recommended setting
however).
[server] Added FLUSH_IPFW_AT_INIT and FLUSH_IPFW_AT_EXIT for ipfw
firewalls to emulate the corresponding functionality that is implemented
for iptables firewalls. This was suggested by Jonathan Schulz.
- [server] Replay attack bug fix to ensure that an attacker cannot force a
replay attack by intercepting an SPA packet and the replaying it with the
base64 version of "Salted__" (for Rindael) or the "hQ" prefix (for
@@ -36,6 +56,9 @@ fwknop-2.0.2 (08//2012):
by 0x10DABF: pcap_capture (pcap_capture.c:226)
by 0x10A798: main (fwknopd.c:299)
- [test suite] Added GPG tests for keyrings that have no associated
passphrases.
fwknop-2.0.1 (07/23/2012):
- [server] Bug fix where the same encryption key used for two stanzas in
the access.conf file would result in access requests that matched the
+9 -3
View File
@@ -109,6 +109,15 @@ EXTRA_DIST = \
test/conf/client-gpg/pubring.gpg \
test/conf/client-gpg/secring.gpg \
test/conf/client-gpg/trustdb.gpg \
test/conf/client-gpg-no-pw/pubring.gpg \
test/conf/client-gpg-no-pw/secring.gpg \
test/conf/client-gpg-no-pw/trustdb.gpg \
test/conf/server-gpg/pubring.gpg \
test/conf/server-gpg/secring.gpg \
test/conf/server-gpg/trustdb.gpg \
test/conf/server-gpg-no-pw/pubring.gpg \
test/conf/server-gpg-no-pw/secring.gpg \
test/conf/server-gpg-no-pw/trustdb.gpg \
test/conf/default_access.conf \
test/conf/default_fwknopd.conf \
test/conf/dual_key_usage_access.conf \
@@ -133,9 +142,6 @@ EXTRA_DIST = \
test/conf/override_fwknopd.conf \
test/conf/require_src_access.conf \
test/conf/require_user_access.conf \
test/conf/server-gpg/pubring.gpg \
test/conf/server-gpg/secring.gpg \
test/conf/server-gpg/trustdb.gpg \
test/conf/subnet_source_match_access.conf \
test/conf/local_nat_fwknopd.conf \
test/hardening-check \
+13
View File
@@ -46,6 +46,9 @@
static void
add_acc_string(char **var, const char *val)
{
if(*var != NULL)
free(*var);
if((*var = strdup(val)) == NULL)
{
log_msg(LOG_ERR,
@@ -437,6 +440,9 @@ add_string_list_ent(acc_string_list_t **stlist, const char *str_str)
last_stlist->next = new_stlist;
}
if(new_stlist->str != NULL)
free(new_stlist->str);
new_stlist->str = strdup(str_str);
if(new_stlist->str == NULL)
@@ -1044,6 +1050,13 @@ parse_access_file(fko_srv_options_t *opts)
}
add_acc_string(&(curr_acc->gpg_decrypt_pw), val);
}
else if(CONF_VAR_IS(var, "GPG_ALLOW_NO_PW"))
{
if(curr_acc->gpg_decrypt_pw != NULL && curr_acc->gpg_decrypt_pw[0] != '\0')
free(curr_acc->gpg_decrypt_pw);
add_acc_string(&(curr_acc->gpg_decrypt_pw), "");
}
else if(CONF_VAR_IS(var, "GPG_REQUIRE_SIG"))
{
add_acc_bool(&(curr_acc->gpg_require_sig), val);
+2
View File
@@ -79,6 +79,8 @@ static char *config_map[NUMBER_OF_CONFIG_ENTRIES] = {
"IPT_SNAT_ACCESS",
"IPT_MASQUERADE_ACCESS",
#elif FIREWALL_IPFW
"FLUSH_IPFW_AT_INIT",
"FLUSH_IPFW_AT_EXIT",
"IPFW_START_RULE_NUM",
"IPFW_MAX_RULES",
"IPFW_ACTIVE_SET_NUM",
+25 -1
View File
@@ -43,7 +43,7 @@ range_check(fko_srv_options_t *opts, char *var, char *val, int low, int high)
{
if (low > atoi(val) || high < atoi(val))
{
fprintf(stderr, "[*] var %s value '%s' not in the range %d-%d",
fprintf(stderr, "[*] var %s value '%s' not in the range %d-%d\n",
var, val, low, high);
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
@@ -150,6 +150,19 @@ validate_int_var_ranges(fko_srv_options_t *opts)
opts->config[CONF_IPFW_EXPIRE_PURGE_INTERVAL],
1, RCHK_MAX_IPFW_PURGE_INTERVAL);
/* Make sure the active and expire sets are not identical whenever
* they are non-zero
*/
if((opts->config[CONF_IPFW_ACTIVE_SET_NUM] > 0
&& opts->config[CONF_IPFW_EXPIRE_SET_NUM] > 0)
&& (opts->config[CONF_IPFW_ACTIVE_SET_NUM]
== opts->config[CONF_IPFW_EXPIRE_SET_NUM]))
{
fprintf(stderr,
"[*] Cannot set identical ipfw active and expire sets.\n");
clean_exit(opts, NO_FW_CLEANUP, EXIT_FAILURE);
}
#elif FIREWALL_PF
range_check(opts, "PF_EXPIRE_INTERVAL", opts->config[CONF_PF_EXPIRE_INTERVAL],
1, RCHK_MAX_PF_EXPIRE_INTERVAL);
@@ -446,6 +459,17 @@ validate_options(fko_srv_options_t *opts)
DEF_IPT_MASQUERADE_ACCESS);
#elif FIREWALL_IPFW
/* Flush ipfw rules at init.
*/
if(opts->config[CONF_FLUSH_IPFW_AT_INIT] == NULL)
set_config_entry(opts, CONF_FLUSH_IPFW_AT_INIT, DEF_FLUSH_IPFW_AT_INIT);
/* Flush ipfw rules at exit.
*/
if(opts->config[CONF_FLUSH_IPFW_AT_EXIT] == NULL)
set_config_entry(opts, CONF_FLUSH_IPFW_AT_EXIT, DEF_FLUSH_IPFW_AT_EXIT);
/* Set IPFW start rule number.
*/
if(opts->config[CONF_IPFW_START_RULE_NUM] == NULL)
+29 -17
View File
@@ -212,7 +212,8 @@ fw_initialize(const fko_srv_options_t *opts)
/* For now, we just call fw_cleanup to start with clean slate.
*/
res = fw_cleanup(opts);
if(strncasecmp(opts->config[CONF_FLUSH_IPFW_AT_INIT], "Y", 1) == 0)
res = fw_cleanup(opts);
if(res != 0)
{
@@ -261,26 +262,30 @@ fw_initialize(const fko_srv_options_t *opts)
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
}
/* Make sure our expire set is disabled.
*/
zero_cmd_buffers();
if(fwc.expire_set_num > 0
&& (strncasecmp(opts->config[CONF_FLUSH_IPFW_AT_INIT], "Y", 1) == 0))
{
/* Make sure our expire set is disabled.
*/
zero_cmd_buffers();
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPFW_DISABLE_SET_ARGS,
fwc.fw_command,
fwc.expire_set_num
);
snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPFW_DISABLE_SET_ARGS,
fwc.fw_command,
fwc.expire_set_num
);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
if (opts->verbose)
log_msg(LOG_INFO, "fw_initialize() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
if (opts->verbose)
log_msg(LOG_INFO, "fw_initialize() CMD: '%s' (res: %d, err: %s)",
cmd_buf, res, err_buf);
if(EXTCMD_IS_SUCCESS(res))
log_msg(LOG_INFO, "Set ipfw expire set %u to disabled.",
fwc.expire_set_num);
else
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
if(EXTCMD_IS_SUCCESS(res))
log_msg(LOG_INFO, "Set ipfw expire set %u to disabled.",
fwc.expire_set_num);
else
log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
}
/* Now read the expire set in case there are existing
* rules to track.
@@ -351,6 +356,13 @@ fw_cleanup(const fko_srv_options_t *opts)
{
int res, got_err = 0;
if(strncasecmp(opts->config[CONF_FLUSH_IPFW_AT_EXIT], "N", 1) == 0)
{
if(fwc.rule_map != NULL)
free(fwc.rule_map);
return(0);
}
zero_cmd_buffers();
if(fwc.active_set_num > 0
+6 -2
View File
@@ -454,7 +454,8 @@ fw_initialize(const fko_srv_options_t *opts)
/* Flush the chains (just in case) so we can start fresh.
*/
delete_all_chains(opts);
if(strncasecmp(opts->config[CONF_FLUSH_IPT_AT_INIT], "Y", 1) == 0)
delete_all_chains(opts);
/* Now create any configured chains.
*/
@@ -470,6 +471,9 @@ fw_initialize(const fko_srv_options_t *opts)
int
fw_cleanup(const fko_srv_options_t *opts)
{
if(strncasecmp(opts->config[CONF_FLUSH_IPT_AT_EXIT], "N", 1) == 0)
return(0);
delete_all_chains(opts);
return(0);
}
@@ -650,7 +654,7 @@ process_spa_request(const fko_srv_options_t *opts, const acc_stanza_t *acc, spa_
nat_port = atoi(ndx+1);
}
}
if(spadat->message_type == FKO_LOCAL_NAT_ACCESS_MSG)
{
/* Need to add an ACCEPT rule into the INPUT chain
+61 -47
View File
@@ -77,53 +77,11 @@
# the pcap loop. The default is 100000 microseconds, or 1/10th of a second.
#PCAP_LOOP_SLEEP 100000;
# 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).
#
#ENABLE_IPT_FORWARDING N;
# Allow SPA clients to request access to a local socket via NAT. This still
# puts an ACCEPT rule into the FWKNOP_INPUT chain, but a different port is
# translated via DNAT rules to the real one. So, the user would do
# "ssh -p <port>" to access the local service (see the --NAT-local and
# --NAT-rand-port on the fwknop client command line).
#
#ENABLE_IPT_LOCAL_NAT Y;
# By default, if forwarding access is enabled (see the ENABLE_IPT_FORWARDING
# variable above), then fwknop creates DNAT rules for incoming connections,
# but does not also complement these rules with SNAT rules at the same time.
# In some situations, internal systems may not have a route back out for the
# source address of the incoming connection, so it is necessary to also
# apply SNAT rules so that the internal systems see the IP of the internal
# interface where fwknopd is running. This functionality is only enabled
# when ENABLE_IPT_SNAT is set to "Y", and by default SNAT rules are built
# with the MASQUERADE target (since then the internal IP does not have to be
# defined here in the fwknop.conf file), but if you want fwknopd to use the
# SNAT target then also defined an IP address with the SNAT_TRANSLATE_IP
# variable.
#
#ENABLE_IPT_SNAT N;
#SNAT_TRANSLATE_IP __CHANGEME__;
# Add ACCEPT rules to the FWKNOP_OUTPUT chain. This is usually only useful
# if there are no state tracking rules to allow connection responses out and
# the OUTPUT chain has a default-drop stance.
#
#ENABLE_IPT_OUTPUT N;
# 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 and/or
# exit time. They default to Y and it is recommended setting for both.
#
#FLUSH_IPT_AT_INIT Y;
#FLUSH_IPT_AT_EXIT Y;
# If GPG keys are used instead of a Rijndael symmetric key, this is
# the default GPG keys directory. Note that each access block in
# fwknop access.conf can specify its own GPG directory to override
@@ -144,7 +102,7 @@
# accept incoming TCP request. This server only accepts the
# request. It does not otherwise communicate. This is only to allow the
# incoming SPA over TCP packet which is detected via PCAP. The connection
# is closed after 1 second regardless.
# is closed after 1 second regardless.
# 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.
#
@@ -209,7 +167,50 @@
##############################################################################
# Parameters specific to iptables:
# Flush all existing rules in the fwknop chains at fwknop start time and/or
# exit time. They default to Y and it is a recommended setting for both.
#
#FLUSH_IPT_AT_INIT Y;
#FLUSH_IPT_AT_EXIT 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).
#
#ENABLE_IPT_FORWARDING N;
# Allow SPA clients to request access to a local socket via NAT. This still
# puts an ACCEPT rule into the FWKNOP_INPUT chain, but a different port is
# translated via DNAT rules to the real one. So, the user would do
# "ssh -p <port>" to access the local service (see the --NAT-local and
# --NAT-rand-port on the fwknop client command line).
#
#ENABLE_IPT_LOCAL_NAT Y;
# By default, if forwarding access is enabled (see the ENABLE_IPT_FORWARDING
# variable above), then fwknop creates DNAT rules for incoming connections,
# but does not also complement these rules with SNAT rules at the same time.
# In some situations, internal systems may not have a route back out for the
# source address of the incoming connection, so it is necessary to also
# apply SNAT rules so that the internal systems see the IP of the internal
# interface where fwknopd is running. This functionality is only enabled
# when ENABLE_IPT_SNAT is set to "Y", and by default SNAT rules are built
# with the MASQUERADE target (since then the internal IP does not have to be
# defined here in the fwknop.conf file), but if you want fwknopd to use the
# SNAT target then also defined an IP address with the SNAT_TRANSLATE_IP
# variable.
#
#ENABLE_IPT_SNAT N;
#SNAT_TRANSLATE_IP __CHANGEME__;
# Add ACCEPT rules to the FWKNOP_OUTPUT chain. This is usually only useful
# if there are no state tracking rules to allow connection responses out and
# the OUTPUT chain has a default-drop stance.
#
#ENABLE_IPT_OUTPUT N;
# fwknopd adds 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. However, additional chains can be added
@@ -278,17 +279,30 @@
#
#IPFW_MAX_RULES 1000;
# Flush all existing rules in the fwknop ipfw sets at fwknop start time and/or
# exit time. They default to Y and it is a recommended setting for both.
#
#FLUSH_IPFW_AT_INIT Y;
#FLUSH_IPFW_AT_EXIT Y;
# This variable defines the rule set fwknopd uses for active rules. By
# default, it is set 0, but can be set to any number between 0 and 31 in
# case you want to keep fwknopd generated rules segregated from the default
# ruleset.
# default, it is set 1 and fwknopd assumes that it has full control over this
# set. That is, fwknopd routinely creates and deletes rules in this set, and
# the entire set itself is also created/deleted during routine operations.
# You have some measure of control over whether the entire set is deleted at
# init/exit with the FLUSH_IPFW_AT_INIT and FLUSH_IPFW_AT_EXIT, but in general
# it is recommended to leave these variables set to the default "Y" setting.
#
#IPFW_ACTIVE_SET_NUM 1;
# 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 isn't using dynamic rules. By default, it is set 2, but can be anything
# in the range 1-31 except that it shouldn't be the same as
# IPFW_ACTIVE_SET_NUM. Note that fwknopd disables this set through routine
# operations according to the FLUSH_IPFW_AT_INIT and FLUSH_IPFW_AT_EXIT
# variables.
#
#IPFW_EXPIRE_SET_NUM 2;
+4
View File
@@ -121,6 +121,8 @@
*/
#elif FIREWALL_IPFW
#define DEF_FLUSH_IPFW_AT_INIT "Y"
#define DEF_FLUSH_IPFW_AT_EXIT "Y"
#define DEF_IPFW_START_RULE_NUM "10000"
#define DEF_IPFW_MAX_RULES "1000"
#define DEF_IPFW_ACTIVE_SET_NUM "1"
@@ -200,6 +202,8 @@ enum {
CONF_IPT_SNAT_ACCESS,
CONF_IPT_MASQUERADE_ACCESS,
#elif FIREWALL_IPFW
CONF_FLUSH_IPFW_AT_INIT,
CONF_FLUSH_IPFW_AT_EXIT,
CONF_IPFW_START_RULE_NUM,
CONF_IPFW_MAX_RULES,
CONF_IPFW_ACTIVE_SET_NUM,
+1 -1
View File
@@ -440,7 +440,7 @@ incoming_spa(fko_srv_options_t *opts)
else
{
log_msg(LOG_ERR,
"(stanza #%d) No GPG_DECRYPT_PW for GPG encrypted messages",
"(stanza #%d) No GPG_DECRYPT_PW for GPG encrypted messages, set GPG_ALLOW_NO_PW",
stanza_num
);
acc = acc->next;
Binary file not shown.
Binary file not shown.
Binary file not shown.
+7
View File
@@ -0,0 +1,7 @@
SOURCE: ANY;
KEY: fwknoptest;
FW_ACCESS_TIMEOUT: 3;
GPG_HOME_DIR: conf/server-gpg-no-pw;
GPG_DECRYPT_ID: 361BBAD4;
GPG_ALLOW_NO_PW: Y;
GPG_REMOTE_ID: 6A3FAD56;
Binary file not shown.
Binary file not shown.
Binary file not shown.
+176
View File
@@ -19,6 +19,7 @@ my $configure_path = '../configure';
my $cmd_out_tmp = 'cmd.out';
my $server_cmd_tmp = 'server_cmd.out';
my $gpg_client_home_dir = "$conf_dir/client-gpg";
my $gpg_client_home_dir_no_pw = "$conf_dir/client-gpg-no-pw";
my %cf = (
'nat' => "$conf_dir/nat_fwknopd.conf",
@@ -33,6 +34,7 @@ my %cf = (
'local_nat' => "$conf_dir/local_nat_fwknopd.conf",
'dual_key_access' => "$conf_dir/dual_key_usage_access.conf",
'gpg_access' => "$conf_dir/gpg_access.conf",
'gpg_no_pw_access' => "$conf_dir/gpg_no_pw_access.conf",
'open_ports_access' => "$conf_dir/open_ports_access.conf",
'multi_gpg_access' => "$conf_dir/multi_gpg_access.conf",
'multi_stanza_access' => "$conf_dir/multi_stanzas_access.conf",
@@ -196,6 +198,10 @@ my $default_client_gpg_args = "$default_client_args " .
"--gpg-signer-key $gpg_client_key " .
"--gpg-home-dir $gpg_client_home_dir";
my $default_client_gpg_args_no_homedir = "$default_client_args " .
"--gpg-recipient-key $gpg_server_key " .
"--gpg-signer-key $gpg_client_key ";
my $default_client_gpg_args_no_get_key = "$default_client_args_no_get_key " .
"--gpg-recipient-key $gpg_server_key " .
"--gpg-signer-key $gpg_client_key " .
@@ -209,6 +215,11 @@ my $default_server_gpg_args = "LD_LIBRARY_PATH=$lib_dir " .
"-a $cf{'gpg_access'} $intf_str " .
"-d $default_digest_file -p $default_pid_file";
my $default_server_gpg_args_no_pw = "LD_LIBRARY_PATH=$lib_dir " .
"$valgrind_str $fwknopdCmd -c $cf{'def'} " .
"-a $cf{'gpg_no_pw_access'} $intf_str " .
"-d $default_digest_file -p $default_pid_file";
### point the compiled binaries at the local libary path
### instead of any installed libfko instance
$ENV{'LD_LIBRARY_PATH'} = $lib_dir;
@@ -1589,6 +1600,171 @@ my @tests = (
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'complete cycle (tcp/22 ssh)',
'err_msg' => 'could not complete SPA cycle',
'function' => \&spa_cycle,
'cmdline' => "$default_client_gpg_args_no_homedir "
. "--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'multi gpg-IDs (tcp/22 ssh)',
'err_msg' => 'could not complete SPA cycle',
'function' => \&spa_cycle,
'cmdline' => "$default_client_gpg_args_no_homedir "
. "--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir " .
"$valgrind_str $fwknopdCmd -c $cf{'def'} " .
"-a $cf{'multi_gpg_access'} $intf_str " .
"-d $default_digest_file -p $default_pid_file",
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'complete cycle (tcp/23 telnet)',
'err_msg' => 'could not complete SPA cycle',
'function' => \&spa_cycle,
'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
"$fwknopCmd -A tcp/23 -a $fake_ip -D $loopback_ip --get-key " .
"$local_key_file --verbose --verbose " .
"--gpg-recipient-key $gpg_server_key " .
"--gpg-signer-key $gpg_client_key " .
"--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'complete cycle (tcp/9418 git)',
'err_msg' => 'could not complete SPA cycle',
'function' => \&spa_cycle,
'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
"$fwknopCmd -A tcp/9418 -a $fake_ip -D $loopback_ip --get-key " .
"$local_key_file --verbose --verbose " .
"--gpg-recipient-key $gpg_server_key " .
"--gpg-signer-key $gpg_client_key " .
"--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'complete cycle (udp/53 dns)',
'err_msg' => 'could not complete SPA cycle',
'function' => \&spa_cycle,
'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
"$fwknopCmd -A udp/53 -a $fake_ip -D $loopback_ip --get-key " .
"$local_key_file --verbose --verbose " .
"--gpg-recipient-key $gpg_server_key " .
"--gpg-signer-key $gpg_client_key " .
"--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
'fw_rule_created' => $NEW_RULE_REQUIRED,
'fw_rule_removed' => $NEW_RULE_REMOVED,
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'replay attack detection',
'err_msg' => 'could not detect replay attack',
'function' => \&replay_detection,
'cmdline' => "$default_client_gpg_args_no_homedir "
. "--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
'replay_positive_output_matches' => [qr/Replay\sdetected\sfrom\ssource\sIP/],
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'replay detection (GnuPG prefix)',
'err_msg' => 'could not detect replay attack',
'function' => \&replay_detection,
'pkt_prefix' => 'hQ',
'cmdline' => "$default_client_gpg_args_no_homedir "
. "--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
"$fwknopdCmd $default_server_conf_args $intf_str",
'replay_positive_output_matches' => [qr/Data\sis\snot\sa\svalid\sSPA\smessage\sformat/],
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'non-base64 altered SPA data',
'err_msg' => 'allowed improper SPA data',
'function' => \&altered_non_base64_spa_data,
'cmdline' => "$default_client_gpg_args_no_homedir "
. "--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'base64 altered SPA data',
'err_msg' => 'allowed improper SPA data',
'function' => \&altered_base64_spa_data,
'cmdline' => "$default_client_gpg_args_no_homedir "
. "--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'appended data to SPA pkt',
'err_msg' => 'allowed improper SPA data',
'function' => \&appended_spa_data,
'cmdline' => "$default_client_gpg_args_no_homedir "
. "--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'prepended data to SPA pkt',
'err_msg' => 'allowed improper SPA data',
'function' => \&prepended_spa_data,
'cmdline' => "$default_client_gpg_args_no_homedir "
. "--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
'fatal' => $NO
},
{
'category' => 'GPG (no pw) SPA',
'subcategory' => 'client+server',
'detail' => 'spoof username (tcp/22 ssh)',
'err_msg' => 'could not spoof username',
'function' => \&spoof_username,
'cmdline' => "SPOOF_USER=$spoof_user $default_client_gpg_args_no_homedir "
. "--gpg-home-dir $gpg_client_home_dir_no_pw",
'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
'fatal' => $NO
},
{
'category' => 'GnuPG (GPG) SPA',
'subcategory' => 'client+server',