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 )