Skip to content

Commit

Permalink
merge
Browse files Browse the repository at this point in the history
  • Loading branch information
mrash committed Feb 21, 2015
2 parents dceb48f + ef279f5 commit 5894ef3
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 44 deletions.
39 changes: 24 additions & 15 deletions lib/IPTables/Parse.pm
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,24 @@ sub new() {
_ipt_exec_style => $args{'ipt_exec_style'} || 'waitpid',
_ipt_exec_sleep => $args{'ipt_exec_sleep'} || 0,
_sigchld_handler => $args{'sigchld_handler'} || \&REAPER,
_skip_ipt_exec_check => $args{'skip_ipt_exec_check'} || 0
};

if ($self->{'_firewall_cmd'}) {
croak "[*] $self->{'_firewall_cmd'} incorrect path.\n"
unless -e $self->{'_firewall_cmd'};
croak "[*] $self->{'_firewall_cmd'} not executable.\n"
unless -x $self->{'_firewall_cmd'};
} else {
if ($self->{'_ipv6'} and $self->{'_iptables'} eq '/sbin/iptables') {
$self->{'_iptables'} = '/sbin/ip6tables';
unless ($self->{'_skip_ipt_exec_check'}) {
if ($self->{'_firewall_cmd'}) {
croak "[*] $self->{'_firewall_cmd'} incorrect path.\n"
unless -e $self->{'_firewall_cmd'};
croak "[*] $self->{'_firewall_cmd'} not executable.\n"
unless -x $self->{'_firewall_cmd'};
} else {
if ($self->{'_ipv6'} and $self->{'_iptables'} eq '/sbin/iptables') {
$self->{'_iptables'} = '/sbin/ip6tables';
}
croak "[*] $self->{'_iptables'} incorrect path.\n"
unless -e $self->{'_iptables'};
croak "[*] $self->{'_iptables'} not executable.\n"
unless -x $self->{'_iptables'};
}
croak "[*] $self->{'_iptables'} incorrect path.\n"
unless -e $self->{'_iptables'};
croak "[*] $self->{'_iptables'} not executable.\n"
unless -x $self->{'_iptables'};
}

### set the firewall binary name
Expand All @@ -74,8 +77,10 @@ sub new() {
}
} else {
if ($self->{'_ipt_bin_name'} eq 'iptables') {
croak "[*] use_ipv6 is true, " .
"but $self->{'_iptables'} not ip6tables.\n";
unless ($self->{'_skip_ipt_exec_check'}) {
croak "[*] use_ipv6 is true, " .
"but $self->{'_iptables'} not ip6tables.\n";
}
}
}
}
Expand Down Expand Up @@ -941,7 +946,11 @@ Note that if you initialize the IPTables::Parse object with the 'ipt_rules_file'
key, then all parsing routines will open the specified file for iptables rules
data. So, you can create this file with a command like
'iptables -t filter -nL -v > ipt.rules', and then initialize the object with
IPTables::Parse->new({'ipt_rules_file'=>'ipt.rules'})
IPTables::Parse->new({'ipt_rules_file'=>'ipt.rules'}). Further, if you are
running on a system without iptables installed, but you have an iptables policy
written to the ipt.rules file, then you can pass in 'skip_ipt_exec_check=>1'
in order to analyze the file without having IPTables::Parse check for the
iptables binary.
=head1 FUNCTIONS
Expand Down
118 changes: 89 additions & 29 deletions t/basic_tests.pl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
my $iptables_bin = '/sbin/iptables';
my $ip6tables_bin = '/sbin/ip6tables';
my $fw_cmd_bin = '/bin/firewall-cmd';
my $dummy_path = '/bin/invalidpath';

my $logfile = 'test.log';
my $ipt_rules_file = 'ipt_rules.tmp';
Expand All @@ -20,6 +21,7 @@
my $verbose = 0;
my $debug = 0;
my $help = 0;
my $use_fw_cmd = 0;

die "[*] See 'psad -h' for usage information" unless (GetOptions(
'verbose' => \$verbose,
Expand Down Expand Up @@ -68,29 +70,42 @@
my $failed = 0;
my $executed = 0;

my $SKIP_IPT_EXEC_CHECK = 1;
my $IPT_EXEC_CHECK = 0;

&init();

### main test routines
&iptables_tests('');
&iptables_tests($ipt_rules_file);
&ip6tables_tests('');
&ip6tables_tests($ipt_rules_file);
### main testing routines
&iptables_tests('', $IPT_EXEC_CHECK);
&iptables_tests($ipt_rules_file, $IPT_EXEC_CHECK);
&iptables_tests($ipt_rules_file, $SKIP_IPT_EXEC_CHECK);
&ip6tables_tests('', $IPT_EXEC_CHECK);
&ip6tables_tests($ipt_rules_file, $IPT_EXEC_CHECK);
&ip6tables_tests($ipt_rules_file, $SKIP_IPT_EXEC_CHECK);

&logr("\n[+] passed/failed/executed: $passed/$failed/$executed tests\n\n");

exit 0;

sub iptables_tests() {
my $rules_file = shift;

if ($rules_file) {
&logr("[+] Running $iptables_bin $rules_file tests...\n");
} else {
&logr("[+] Running $iptables_bin tests...\n");
}
my ($rules_file, $skip_ipt_exec_check) = @_;

if ($rules_file) {
if ($skip_ipt_exec_check) {
&logr("\n[+] Running $iptables_bin $rules_file " .
"(skip ipt exec check) tests...\n");
} else {
&logr("\n[+] Running $iptables_bin $rules_file tests...\n");
}
$ipt_opts{'ipt_rules_file'} = $rules_file;
if ($skip_ipt_exec_check == $SKIP_IPT_EXEC_CHECK) {
$ipt_opts{'iptables'} = $dummy_path;
$ipt_opts{'firewall-cmd'} = $dummy_path if $use_fw_cmd;
$ipt_opts{'skip_ipt_exec_check'} = $skip_ipt_exec_check;
}
} else {
&logr("\n[+] Running $iptables_bin tests...\n");
$ipt_opts{'ipt_rules_file'} = '';
}

my $ipt_obj = IPTables::Parse->new(%ipt_opts)
Expand All @@ -105,16 +120,23 @@ ()
}

sub ip6tables_tests() {
my $rules_file = shift;

if ($rules_file) {
&logr("[+] Running $ip6tables_bin $rules_file tests...\n");
} else {
&logr("[+] Running $ip6tables_bin tests...\n");
}
my ($rules_file, $skip_ipt_exec_check) = @_;

if ($rules_file) {
if ($skip_ipt_exec_check) {
&logr("\n[+] Running $iptables_bin $rules_file " .
"(skip ipt exec check) tests...\n");
} else {
&logr("\n[+] Running $ip6tables_bin $rules_file tests...\n");
}
$ipt_opts{'ipt_rules_file'} = $rules_file;
if ($skip_ipt_exec_check == $SKIP_IPT_EXEC_CHECK) {
$ipt_opts{'iptables'} = $dummy_path;
$ipt_opts{'skip_ipt_exec_check'} = $skip_ipt_exec_check;
}
} else {
&logr("\n[+] Running $ip6tables_bin tests...\n");
$ipt_opts{'ipt_rules_file'} = '';
}

my $ipt_obj = IPTables::Parse->new(%ipt6_opts)
Expand All @@ -135,9 +157,8 @@ ()
&dots_print("default_log($ipt_obj->{'_ipt_rules_file'}): filter $chain");

if ($ipt_obj->{'_ipt_rules_file'}) {
my ($rv, $out_ar, $err_ar) = $ipt_obj->exec_iptables(
&write_rules($ipt_obj,
"$ipt_obj->{'_cmd'} -t filter -v -n -L $chain");
&write_rules_file($out_ar);
}

my ($ipt_log, $rv) = $ipt_obj->default_log('filter', $chain);
Expand All @@ -160,9 +181,8 @@ ()
&dots_print("default_drop($ipt_obj->{'_ipt_rules_file'}): filter $chain");

if ($ipt_obj->{'_ipt_rules_file'}) {
my ($rv, $out_ar, $err_ar) = $ipt_obj->exec_iptables(
&write_rules($ipt_obj,
"$ipt_obj->{'_cmd'} -t filter -v -n -L $chain");
&write_rules_file($out_ar);
}

my ($ipt_drop, $rv) = $ipt_obj->default_drop('filter', $chain);
Expand All @@ -185,9 +205,8 @@ ()
for my $chain (@{$tables_chains_hr->{$table}}) {

if ($ipt_obj->{'_ipt_rules_file'}) {
my ($rv, $out_ar, $err_ar) = $ipt_obj->exec_iptables(
&write_rules($ipt_obj,
"$ipt_obj->{'_cmd'} -t $table -v -n -L $chain");
&write_rules_file($out_ar);
}

&dots_print("chain_policy($ipt_obj->{'_ipt_rules_file'}): $table $chain policy");
Expand Down Expand Up @@ -218,9 +237,8 @@ ()
&dots_print("list_table_chains($ipt_obj->{'_ipt_rules_file'}): $table");

if ($ipt_obj->{'_ipt_rules_file'}) {
my ($rv, $out_ar, $err_ar) = $ipt_obj->exec_iptables(
&write_rules($ipt_obj,
"$ipt_obj->{'_cmd'} -t $table -v -n -L");
&write_rules_file($out_ar);
}

my $chains_ar = $ipt_obj->list_table_chains($table);
Expand All @@ -236,11 +254,10 @@ ()
for my $chain (@{$tables_chains_hr->{$table}}) {
&dots_print("chain_rules($ipt_obj->{'_ipt_rules_file'}): $table $chain rules");

my ($rv, $out_ar, $err_ar) = $ipt_obj->exec_iptables(
my $out_ar = &write_rules($ipt_obj,
"$ipt_obj->{'_cmd'} -t $table -v -n -L $chain");

if ($ipt_obj->{'_ipt_rules_file'}) {
&write_rules_file($out_ar);
}

my $rules_ar = $ipt_obj->chain_rules($table, $chain);
Expand Down Expand Up @@ -322,6 +339,7 @@ ()
$ipt_opts{'firewall-cmd'} = $fw_cmd_bin;
$ipt6_opts{'firewall-cmd'} = $fw_cmd_bin;
$ipt6_opts{'use_ipv6'} = 1;
$use_fw_cmd = 1;
} else {
for my $bin ($iptables_bin, $ip6tables_bin) {
die "[*] $bin does not exist" unless -e $bin;
Expand All @@ -332,6 +350,48 @@ ()
return;
}

sub write_rules() {
my ($ipt_obj, $cmd) = @_;

my $rv = 0;
my $out_ar = ();
my $err_ar = ();

### if the original iptables object skipped the iptables exec
### check, then acquire a new object to execute the command
if ($ipt_obj->{'_skip_ipt_exec_check'}) {
my %opts_cp = %ipt_opts;
$opts_cp{'iptables'} = $iptables_bin;

if ($use_fw_cmd) {
$cmd =~ s|^$dummy_path|$fw_cmd_bin|;
} else {
if ($ipt_obj->{'use_ipv6'}) {
%opts_cp = %ipt6_opts;
$opts_cp{'iptables'} = $ip6tables_bin;
$cmd =~ s|^$dummy_path|$ip6tables_bin|;
} else {
$cmd =~ s|^$dummy_path|$iptables_bin|;
}
}
if ($use_fw_cmd) {
$opts_cp{'firewall-cmd'} = $fw_cmd_bin;
} else {
$opts_cp{'firewall-cmd'} = '';
}
$opts_cp{'skip_ipt_exec_check'} = 0;

my $obj = IPTables::Parse->new(%opts_cp);
($rv, $out_ar, $err_ar) = $obj->exec_iptables($cmd);
} else {
($rv, $out_ar, $err_ar) = $ipt_obj->exec_iptables($cmd);
}

&write_rules_file($out_ar);

return $out_ar;
}

sub write_rules_file() {
my $lines_ar = shift;
open F, "> $ipt_rules_file" or die $!;
Expand Down

0 comments on commit 5894ef3

Please sign in to comment.