Skip to content

Commit

Permalink
added --firewall-type <type> argument, calls to log parsing routines …
Browse files Browse the repository at this point in the history
…done via function references
  • Loading branch information
mrash committed Mar 26, 2012
1 parent 54846da commit 2488081
Showing 1 changed file with 61 additions and 24 deletions.
85 changes: 61 additions & 24 deletions psad
Expand Up @@ -330,6 +330,9 @@ my %pidfiles = ();

### initialize and scope some default variables (command
### line args can override some default values)
my $fw_parse_func = '';
my $firewall_type = '';
my $cmdline_fw_type = '';
my $sigs_file = '';
my $posf_file = '';
my $auto_dl_file = '';
Expand Down Expand Up @@ -393,7 +396,7 @@ my $csv_end_line = 0;
my $csv_regex = '';
my $csv_neg_regex = '';
my $csv_have_timestamp = 0;
my $dump_ipt_policy = 0;
my $dump_fw_policy = 0;
my $fw_include_ips = 0;
my $benchmark = 0;
my $num_packets = 0;
Expand Down Expand Up @@ -491,7 +494,7 @@ my @unsupported_snort_opts = qw(
flowbits
ip_proto
); ### the ip_proto keyword could be supported, but would require
### refactoring parse_NF_pkt_str().
### refactoring parse_iptables_pkt_str().

### for Snort signature sp/dp matching
my @port_types = (
Expand Down Expand Up @@ -752,7 +755,7 @@ my $fw_data_file_check_ctr = 0;
### Get an open filehandle for the main firewall data file FW_DATA_FILE.
### All firewall drop/reject log messages are written to FW_DATA_FILE
### by kmsgsd (or by ulogd directly).
print STDERR "[+] Opening $config{'FIREWALL_TYPE'} ",
print STDERR "[+] Opening $firewall_type ",
"log file: $fw_data_file\n" if $debug;
open FWDATA, $fw_data_file or die '[*] Could not open ',
"$fw_data_file: $!";
Expand Down Expand Up @@ -856,7 +859,7 @@ MAIN: for (;;) {

close FWDATA;

&sys_log('[+]', "$config{'FIREWALL_TYPE'} " .
&sys_log('[+]', "$firewall_type " .
"syslog file $fw_data_file " .
"shrank or was rotated, so re-opening");

Expand Down Expand Up @@ -1049,7 +1052,7 @@ sub check_scan() {
}

### main parsing routine for the firewall packet logging message
my $pkt_parse_rv = &parse_NF_pkt_str(\%pkt, $pkt_str);
my $pkt_parse_rv = &{$fw_parse_func}(\%pkt, $pkt_str);
print STDERR Dumper \%pkt if $debug and $verbose;
if ($pkt_parse_rv == $PKT_ERROR) {
push @err_pkts, $pkt_str unless $no_ipt_errors;
Expand Down Expand Up @@ -1424,7 +1427,7 @@ sub check_scan() {
return;
}

sub parse_NF_pkt_str() {
sub parse_iptables_pkt_str() {
my ($pkt_hr, $pkt_str) = @_;

my $is_ipv6 = 0;
Expand Down Expand Up @@ -1943,6 +1946,36 @@ sub parse_NF_pkt_str() {
return $PKT_SUCCESS;
}

sub parse_pf_pkt_str() {
return;
}

sub parse_ipfw_pkt_str() {
return;
}

sub set_firewall_type() {
if ($cmdline_fw_type) {
$firewall_type = $cmdline_fw_type;
} else {
$firewall_type = $config{'FIREWALL_TYPE'};
}

if ($firewall_type eq 'iptables'
or $firewall_type eq 'ip6tables') {
$fw_parse_func = \&parse_iptables_pkt_str,
} elsif ($firewall_type eq 'pf') {
$fw_parse_func = \&parse_pf_pkt_str,
} elsif ($firewall_type eq 'ipfw') {
$fw_parse_func = \&parse_ipfw_pkt_str,
} else {
die "[*] Invalid firewall type: $firewall_type, must be one of ",
"iptables, ip6tables, pf, or ipfw";
}

return;
}

sub check_ignore_proto() {
my $pkt_proto = shift;

Expand Down Expand Up @@ -2371,7 +2404,7 @@ sub match_snort_ip_keywords() {
'psad_ip_len', $sig_hr);
}

### to handle the ip_proto keyword parse_NF_pkt_str() would have to be
### to handle the ip_proto keyword parse_iptables_pkt_str() would have to be
### modified to handle packets besides TCP, UDP, and ICMP.
return 0, $NO_SIG_MATCH if defined $sig_hr->{'ip_proto'};

Expand Down Expand Up @@ -3183,6 +3216,9 @@ sub psad_init() {
### expand any embedded vars within config values
&expand_vars();

### set firewall type
&set_firewall_type();

### pid file hash
%pidfiles = (
'psadwatchd' => $config{'PSADWATCHD_PID_FILE'},
Expand All @@ -3191,11 +3227,11 @@ sub psad_init() {
);

### dump configuration to STDOUT
if ($dump_conf or $dump_ipt_policy) {
if ($dump_conf or $dump_fw_policy) {
my $rv = 0;
my $rv_tmp = 0;
$rv = &dump_conf() if $dump_conf;
$rv_tmp = &dump_ipt_policy() if $dump_ipt_policy;
$rv_tmp = &dump_fw_policy() if $dump_fw_policy;
$rv += $rv_tmp if $rv_tmp != 0;
exit $rv;
}
Expand Down Expand Up @@ -3434,7 +3470,7 @@ sub validate_config() {
}

if ($gnuplot_mode and not $csv_fields) {
die "[*] Must specify which $config{'FIREWALL_TYPE'} fields ",
die "[*] Must specify which $firewall_type fields ",
"to plot with the --CSV-fields argument.";
}

Expand Down Expand Up @@ -7227,7 +7263,7 @@ sub analysis_mode() {
}
}
}
print "[+] Found ", ($#ipt_msgs+1), " $config{'FIREWALL_TYPE'} ",
print "[+] Found ", ($#ipt_msgs+1), " $firewall_type ",
"log messages out of ", ($#lines+1), " total lines.\n";
print " This may take a while...\n" if $#ipt_msgs > 15000;

Expand Down Expand Up @@ -7330,11 +7366,11 @@ sub csv_mode() {

my $fh = '';
if ($csv_stdin) {
print "[+] Parsing $config{'FIREWALL_TYPE'} log messages from STDIN\n"
print "[+] Parsing $firewall_type log messages from STDIN\n"
if $gnuplot_mode;
$fh = *STDIN;
} else {
print "[+] Parsing $config{'FIREWALL_TYPE'} log messages from file: $fw_data_file\n"
print "[+] Parsing $firewall_type log messages from file: $fw_data_file\n"
if $gnuplot_mode;
open MSGS, "< $fw_data_file" or die "[*] Could not open ",
"$fw_data_file: $!";
Expand All @@ -7361,16 +7397,16 @@ sub csv_mode() {
next MSG unless $pkt_str =~ /IN.*OUT/;
my %pkt = %pkt_NF_init;
if ($config{'FW_SEARCH_ALL'} eq 'Y') {
my $rv = &parse_NF_pkt_str(\%pkt, $pkt_str);
my $rv = &{$fw_parse_func}(\%pkt, $pkt_str);
next MSG if $rv == $PKT_ERROR or $rv == $PKT_IGNORE;
} else {
if ($pkt_str =~ /$config{'SNORT_SID_STR'}/) {
my $rv = &parse_NF_pkt_str(\%pkt, $pkt_str);
my $rv = &{$fw_parse_func}(\%pkt, $pkt_str);
next MSG if $rv == $PKT_ERROR or $rv == $PKT_IGNORE;
} else {
for my $fw_search_str (@fw_search) {
if ($pkt_str =~ /$fw_search_str/) {
my $rv = &parse_NF_pkt_str(\%pkt, $pkt_str);
my $rv = &{$fw_parse_func}(\%pkt, $pkt_str);
next MSG if $rv == $PKT_ERROR or $rv == $PKT_IGNORE;
}
}
Expand Down Expand Up @@ -7433,7 +7469,7 @@ sub csv_mode() {
chmod 0644, $store_file;
}
} else {
print "[+] Parsed $line_ctr $config{'FIREWALL_TYPE'} log messages.\n";
print "[+] Parsed $line_ctr $firewall_type log messages.\n";
}
### print out the gnuplot data after appropriate
### integer conversions
Expand Down Expand Up @@ -7482,7 +7518,7 @@ sub gnuplot_write_plot_file() {
"$gnuplot_plot_file: $!";
print GP "$_\n", for @{&gnuplot_header()};
unless ($gnuplot_title) {
$gnuplot_title = "psad $config{'FIREWALL_TYPE'} log visualization: $csv_fields";
$gnuplot_title = "psad $firewall_type log visualization: $csv_fields";
$gnuplot_title =~ s/_//g; ### some fonts used by Gnuplot don't like "-" chars
}
print GP "reset\n", qq|set title "$gnuplot_title"\n|;
Expand Down Expand Up @@ -7608,7 +7644,7 @@ sub gnuplot_write_data() {
### of just the port values themselves)
my @gnuplot_count_data = ();

print "[+] Writing parsed $config{'FIREWALL_TYPE'} data to: $gnuplot_data_file\n";
print "[+] Writing parsed $firewall_type data to: $gnuplot_data_file\n";
open GP, "> $gnuplot_data_file" or die "[*] Could not open ",
"$gnuplot_data_file: $!";
print GP "$_\n", for @{&gnuplot_header()};
Expand Down Expand Up @@ -8706,9 +8742,9 @@ sub print_blocked_ip_status() {

my @print_lines = ();
if ($specific_ip) {
push @print_lines, " $config{'FIREWALL_TYPE'} auto-blocking status for: $specific_ip: \n";
push @print_lines, " $firewall_type auto-blocking status for: $specific_ip: \n";
} else {
push @print_lines, " $config{'FIREWALL_TYPE'} auto-blocked IPs:\n";
push @print_lines, " $firewall_type auto-blocked IPs:\n";
}

my %ipt_opts = (
Expand Down Expand Up @@ -9996,7 +10032,7 @@ sub dump_conf() {
return 0;
}

sub dump_ipt_policy() {
sub dump_fw_policy() {
my $rv = 0;

my $fh = *STDOUT;
Expand Down Expand Up @@ -10026,7 +10062,7 @@ sub dump_ipt_policy() {
}
}

print $fh "\n[+] $config{'FIREWALL_TYPE'} policy dump:\n";
print $fh "\n[+] $firewall_type policy dump:\n";
if (defined $cmds{'iptables'} and -x $cmds{'iptables'}) {
my @ipt_ver = @{&run_command($cmds{'iptables'}, '-V')};
if (@ipt_ver) {
Expand Down Expand Up @@ -10477,6 +10513,7 @@ sub getopt_wrapper() {
Getopt::Long::Configure('no_ignore_case');

die "[*] See 'psad -h' for usage information" unless (GetOptions(
'firewall-type=s' => \$cmdline_fw_type, # Set 'iptables', 'pf', or 'ipfw'.
'signatures=s' => \$sigs_file, # Path to psad signatures file.
'sig-update' => \$download_sigs, # Download the latest signatures from
# http://www.cipherdyne.org/psad/signatures
Expand Down Expand Up @@ -10578,7 +10615,7 @@ sub getopt_wrapper() {
# flushing them (requires --F as
# well).
'X' => \$fw_del_chains, # Synonym for --fw-del-chains.
'fw-dump' => \$dump_ipt_policy, # Dump the firewall policy
'fw-dump' => \$dump_fw_policy, # Dump the firewall policy
# (requires -D as well).
'fw-include-ips' => \$fw_include_ips, # Include all IPs/nets in firewall
# dump (--fw-dump) output.
Expand Down

0 comments on commit 2488081

Please sign in to comment.