Permalink
Browse files

Add INPUT ACCEPT rule for --nat-local connections

When using the --nat-local argument on the fwknop client command line, the
fwknopd server needs to add an INPUT ACCEPT rule for the requested access
since the incoming connection is destined for a local socket.  Added test
suite support to test --nat-local access.

[test suite] Minor bug fix to ensure that all file_find_regex() calls return
true if all regex's are matched and false if any regex does not match data in
the specified file.
  • Loading branch information...
1 parent 2a5bc7e commit de7aa3b619f05f9c7df7e943d899e973fa8ac904 @mrash committed Jul 16, 2012
Showing with 94 additions and 33 deletions.
  1. +10 −13 client/fwknop.c
  2. +43 −0 server/fw_util_iptables.c
  3. +41 −20 test/test-fwknop.pl
View
@@ -664,22 +664,19 @@ set_message_type(fko_ctx_t ctx, fko_cli_options_t *options)
{
message_type = FKO_COMMAND_MSG;
}
+ else if(options->nat_local)
+ {
+ if (options->fw_timeout >= 0)
+ message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG;
+ else
+ message_type = FKO_LOCAL_NAT_ACCESS_MSG;
+ }
else if(options->nat_access_str[0] != 0x0)
{
- if (options->nat_local)
- {
- if (options->fw_timeout >= 0)
- message_type = FKO_CLIENT_TIMEOUT_LOCAL_NAT_ACCESS_MSG;
- else
- message_type = FKO_LOCAL_NAT_ACCESS_MSG;
- }
+ if (options->fw_timeout >= 0)
+ message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG;
else
- {
- if (options->fw_timeout >= 0)
- message_type = FKO_CLIENT_TIMEOUT_NAT_ACCESS_MSG;
- else
- message_type = FKO_NAT_ACCESS_MSG;
- }
+ message_type = FKO_NAT_ACCESS_MSG;
}
else
{
View
@@ -650,6 +650,49 @@ 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
+ */
+ zero_cmd_buffers();
+
+ snprintf(cmd_buf, CMD_BUFSIZE-1, "%s " IPT_ADD_RULE_ARGS,
+ opts->fw_config->fw_command,
+ in_chain->table,
+ in_chain->to_chain,
+ fst_proto,
+ spadat->use_src_ip,
+ nat_port,
+ exp_ts,
+ in_chain->target
+ );
+
+ res = run_extcmd(cmd_buf, err_buf, CMD_BUFSIZE, 0);
+
+ if (opts->verbose)
+ log_msg(LOG_INFO, "process_spa_request() CMD: '%s' (res: %d, err: %s)",
+ cmd_buf, res, err_buf);
+
+ if(EXTCMD_IS_SUCCESS(res))
+ {
+ log_msg(LOG_INFO, "Added Rule to %s for %s, %s expires at %u",
+ in_chain->to_chain, spadat->use_src_ip,
+ spadat->spa_message_remain, exp_ts
+ );
+
+ in_chain->active_rules++;
+
+ /* Reset the next expected expire time for this chain if it
+ * is warranted.
+ */
+ if(in_chain->next_expire < now || exp_ts < in_chain->next_expire)
+ in_chain->next_expire = exp_ts;
+ }
+ else
+ log_msg(LOG_ERR, "Error %i from cmd:'%s': %s", res, cmd_buf, err_buf);
+
+ }
/* Make our FORWARD and NAT rules
*/
View
@@ -27,6 +27,7 @@
my $expired_epoch_access_conf = "$conf_dir/expired_epoch_stanza_access.conf";
my $invalid_expire_access_conf = "$conf_dir/invalid_expire_access.conf";
my $force_nat_access_conf = "$conf_dir/force_nat_access.conf";
+my $local_nat_fwknopd_conf = "$conf_dir/local_nat_fwknopd.conf";
my $dual_key_usage_access_conf = "$conf_dir/dual_key_usage_access.conf";
my $gpg_access_conf = "$conf_dir/gpg_access.conf";
my $default_digest_file = "$run_dir/digest.cache";
@@ -931,7 +932,6 @@
'server_conf' => $nat_conf,
'fatal' => $NO
},
-
{
'category' => 'Rijndael SPA',
'subcategory' => 'client+server',
@@ -949,7 +949,24 @@
'server_conf' => $nat_conf,
'fatal' => $NO
},
-
+ {
+ 'category' => 'Rijndael SPA',
+ 'subcategory' => 'client+server',
+ 'detail' => "local NAT $force_nat_host (tcp/22 ssh)",
+ 'err_msg' => "could not complete NAT SPA cycle",
+ 'function' => \&spa_cycle,
+ 'cmdline' => "$default_client_args --nat-local",
+ 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
+ "$fwknopdCmd -c $local_nat_fwknopd_conf -a $force_nat_access_conf " .
+ "-d $default_digest_file -p $default_pid_file $intf_str",
+ 'server_positive_output_matches' => [qr/to\:$force_nat_host\:22/i,
+ qr/FWKNOP_INPUT.*dport\s22.*\sACCEPT/],
+ 'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
+ 'fw_rule_created' => $NEW_RULE_REQUIRED,
+ 'fw_rule_removed' => $NEW_RULE_REMOVED,
+ 'server_conf' => $nat_conf,
+ 'fatal' => $NO
+ },
{
'category' => 'Rijndael SPA',
'subcategory' => 'client+server',
@@ -1490,7 +1507,8 @@ ()
### look for compilation warnings - something like:
### warning: ‘test’ is used uninitialized in this function
- return 0 if &file_find_regex([qr/\swarning:\s/, qr/gcc\:.*\sunused/], $current_test_file);
+ return 0 if &file_find_regex([qr/\swarning:\s/, qr/gcc\:.*\sunused/],
+ $current_test_file);
### the new binaries should exist
unless (-e $fwknopCmd and -x $fwknopCmd) {
@@ -2089,7 +2107,7 @@ ()
if (&is_fwknopd_running()) {
&stop_fwknopd();
- unless (&file_find_regex([qr/Got\sSIGTERM/, qr/^Terminated/],
+ unless (&file_find_regex([qr/Got\sSIGTERM/],
$server_test_file)) {
$server_was_stopped = 0;
}
@@ -2702,34 +2720,37 @@ ()
sub file_find_regex() {
my ($re_ar, $file) = @_;
- my $found = 0;
+ my $found_all_regexs = 1;
my @write_lines = ();
+ my @file_lines = ();
open F, "< $file" or die "[*] Could not open $file: $!";
- LINE: while (<F>) {
- my $line = $_;
- next LINE if $line =~ /file_file_regex\(\)/;
- for my $re (@$re_ar) {
+ while (<F>) {
+ push @file_lines, $_;
+ }
+ close F;
+
+ for my $re (@$re_ar) {
+ my $matched = 0;
+ for my $line (@file_lines) {
if ($line =~ $re) {
push @write_lines, "[.] file_find_regex() " .
"Matched '$re' with line: $line";
- $found = 1;
- last LINE;
+ $matched = 1;
}
}
+ unless ($matched) {
+ push @write_lines, "[.] file_find_regex() " .
+ "Did not match any regex in '@$re_ar' in file: $file\n";
+ $found_all_regexs = 0;
+ }
}
- close F;
- if ($found) {
- for my $line (@write_lines) {
- &write_test_file($line, $file);
- }
- } else {
- &write_test_file("[.] find_find_regex() Did not " .
- "match any regex in: '@$re_ar'\n", $file);
+ for my $line (@write_lines) {
+ &write_test_file($line, $file);
}
- return $found;
+ return $found_all_regexs;
}
sub find_command() {

0 comments on commit de7aa3b

Please sign in to comment.