IPTables-Parse
view release on metacpan or search on metacpan
lib/IPTables/Parse.pm view on Meta::CPAN
my $sigchld_handler = $self->{'_sigchld_handler'};
croak "[*] $cmd does not look like an $self->{'_ipt_bin_name'} command."
unless $cmd =~ m|^\s*iptables| or $cmd =~ m|^\S+/iptables|
or $cmd =~ m|^\s*ip6tables| or $cmd =~ m|^\S+/ip6tables|
or $cmd =~ m|^\s*firewall-cmd| or $cmd =~ m|^\S+/firewall-cmd|;
### sanitize $cmd - this is not bullet proof, but better than
### nothing (especially for strange iptables chain names). Further,
### quotemeta() is too aggressive since things like IPv6 addresses
### contain ":" chars, etc.
$cmd =~ s/([;<>\$\|`\@&\(\)\[\]\{\}])/\\$1/g;
my $rv = 1;
my @stdout = ();
my @stderr = ();
my $fh = *STDERR;
$fh = *STDOUT if $verbose;
if ($debug or $verbose) {
print $fh localtime() . " [+] IPTables::Parse::",
"exec_iptables(${ipt_exec_style}()) $cmd\n";
if ($ipt_exec_sleep > 0) {
print $fh localtime() . " [+] IPTables::Parse::",
"exec_iptables() sleep seconds: $ipt_exec_sleep\n";
}
}
if ($ipt_exec_sleep > 0) {
if ($debug or $verbose) {
print $fh localtime() . " [+] IPTables::Parse: ",
"sleeping for $ipt_exec_sleep seconds before ",
"executing $self->{'_ipt_bin_name'} command.\n";
}
sleep $ipt_exec_sleep;
}
if ($ipt_exec_style eq 'system') {
system qq{$cmd > $iptout 2> $ipterr};
} elsif ($ipt_exec_style eq 'popen') {
open CMD, "$cmd 2> $ipterr |" or croak "[*] Could not execute $cmd: $!";
@stdout = <CMD>;
close CMD;
open F, "> $iptout" or croak "[*] Could not open $iptout: $!";
print F for @stdout;
close F;
} else {
my $ipt_pid;
if ($debug or $verbose) {
print $fh localtime() . " [+] IPTables::Parse: " .
"Setting SIGCHLD handler to: " . $sigchld_handler . "\n";
}
local $SIG{'CHLD'} = $sigchld_handler;
if ($ipt_pid = fork()) {
eval {
### iptables should never take longer than 30 seconds to execute,
### unless there is some absolutely enormous policy or the kernel
### is exceedingly busy
local $SIG{'ALRM'} = sub {die "[*] $self->{'_ipt_bin_name'} " .
"command timeout.\n"};
alarm $ipt_alarm;
waitpid($ipt_pid, 0);
alarm 0;
};
if ($@) {
kill 9, $ipt_pid unless kill 15, $ipt_pid;
}
} else {
croak "[*] Could not fork $self->{'_ipt_bin_name'}: $!"
unless defined $ipt_pid;
### exec the iptables command and preserve stdout and stderr
exec qq{$cmd > $iptout 2> $ipterr};
}
}
if (-e $iptout) {
open F, "< $iptout" or croak "[*] Could not open $iptout";
@stdout = <F>;
close F;
}
if (-e $ipterr) {
open F, "< $ipterr" or croak "[*] Could not open $ipterr";
@stderr = <F>;
close F;
$rv = 0 if @stderr;
}
if (@stdout) {
if ($stdout[$#stdout] =~ /^success/) {
pop @stdout;
}
if ($self->{'_ipt_bin_name'} eq 'firewall-cmd') {
for (@stdout) {
if (/COMMAND_FAILED/) {
$rv = 0;
last;
}
}
}
}
if ($debug or $verbose) {
print $fh localtime() . " $self->{'_ipt_bin_name'} " .
"command stdout:\n";
for my $line (@stdout) {
if ($line =~ /\n$/) {
print $fh $line;
} else {
print $fh $line, "\n";
}
}
print $fh localtime() . " $self->{'_ipt_bin_name'} " .
"command stderr:\n";
for my $line (@stderr) {
if ($line =~ /\n$/) {
print $fh $line;
( run in 1.877 second using v1.01-cache-2.11-cpan-39bf76dae61 )