#!/usr/bin/perl
($_pathname,$_filename) = ($0=~m#(.*)/([^/]+)$#)?($1,$2):(".",$0);

sub usage {
################################################################
#
# Title       : rsfilter.pl
#
# Author      : 
#
# Date        : 29 September 2000
#
# Description :
print STDERR "\nERROR: $_[0]\nUsage:\n", <<"EndOfDescription";

    $_filename <filename>

        <filename>  is the name of the Real Secure 'policy' file.

EndOfDescription
#
# SCCS Version:
#
# SCCS Source :
#
#
#################################################################
exit 2;
}

#
# Internal Variables
####################

#
# User Defined Constants/Variables
##################################

#
# Global Constants/Variables
############################

#
# Global Functions
###################


sub enabled {
	my( $enabled ) = shift;

	if ( $enabled == 1 ) {
		$enabled = "Enabled";
	} elsif ( $enabled == 0 ) {
		$enabled = "Disabled";
	} else {
		$enabled = "Undefined value $enabled";
	}
	return $enabled;
}


sub features {
	my( $fh, $event ) = @_;
	my( $eventenabled ) = 0;
	my( $priority );
	my( $response );
	my( $desc );
	my( %choice ) = ();
	my( %enabled ) = ();

	$event = quotemeta ($event);
	while ( <$fh> ) {
		chomp;
		last if (/^\[\\template/o && !/\\features\\$event\\/);

		if (/\\Response\\(\w+?)\\\]/o) {
			$response = $1;
			next;
		}

		if (/^Priority\s*=L\s*(\w+);/o) {
			$priority = $1;
			next;
		}

		if (/^CheckDescription\s*=S\s*(\S.*?)\s*;/o) {
			$desc = $1;
			next;
		}

		if (/^Enabled\s*=B\s*(\w+);/o) {
			if ( $response ) {
				$enabled{$response} = $1;
			} else {
				$eventenabled = $1;
			}
			next;
		}

		if (/^Choice\s*=S\s*(\w+);/o) {
			if ( $response ) {
				$choice{$response} = $1;
			}
			next;
		}
	}

	# Print collected feature information.
	$event =~ s/\\//g;
	print "$event,$desc,",&enabled($eventenabled),",";
	if	($priority eq 1) {	
		print "High";
	} elsif ($priority eq 2) {
		print "Medium";
	} elsif ($priority eq 3) {
		print "Low";
	} else {
		print "Unknown Priority";
	}

	foreach ('DISPLAY','LOGDB','SNMP','OPSEC','VIEWSESSION','RSKILL') {
		print ",";
		if ( $enabled{$_} == 1 ) {
			if ( $choice{$_} =~ /^(Default)?$/i ) {
				print "YES";
			} else {
				print "$choice{$_}";
			}
		} else {
			print "NO";
		}
	}
	print "\n";
}


sub connections {
	my( $fh, $connection ) = @_;
	my( $number ) = ($connection =~ /^connection(\d+)/o);
	my( $connenabled ) = 0;
	my( $priority );
	my( $response );

	my( %choice ) = ();
	my( %enabled ) = ();
	my( %details ) = ();

	while ( <$fh> ) {
		chomp;
		last if (/^\[\\template/o && !/\\connections\\$connection\\/);

		if (/\\Response\\(\w+?)\\\]/o) {
			$response = $1;
			next;
		}

		if (/^Priority\s*=L\s*(\w+);/o) {
			$priority = $1;
			next;
		}

		if (/^Enabled\s*=B\s*(\w+);/o) {
			if ( $response ) {
				$enabled{$response} = $1;
			} else {
				$connenabled = $1;
			}
			next;
		}

		if (/^Choice\s*=S\s*(\w+);/o) {
			if ( $response ) {
				$choice{$response} = $1;
			}
			next;
		}

		if (/^([^=]+?)\s*=S\s*(.*?);/o) {
			$details{$1} = $2;
		}
	}

	# Print collected connection information.
	print "$number,",$details{'shrt'},",",&enabled($connenabled),",";
	if	($priority eq 1) {	
		print "High";
	} elsif ($priority eq 2) {
		print "Medium";
	} elsif ($priority eq 3) {
		print "Low";
	} else {
		print "Unknown Priority";
	}

	foreach ('source address','source mask','dest address','dest mask','protocol','source port','dest port') {
		print ",$details{$_}";
	}
	foreach ('DISPLAY','LOGDB','SNMP','OPSEC','VIEWSESSION','RSKILL') {
		print ",";
		if ( $enabled{$_} == 1 ) {
			if ( $choice{$_} =~ /^(Default)?$/i ) {
				print "YES";
			} else {
				print "$choice{$_}";
			}
		} else {
			print "NO";
		}
	}
	print "\n";
}


sub filters {
	my( $fh, $filter ) = @_;
	my( $number ) = ($filter =~ /^filter(\d+)/o);
	my( $enabled ) = 0;
	my( %details ) = ();

	while ( <$fh> ) {
		chomp;   # Remove end of line Newlines
		last if (/^\[\\template/o && !/\\filters\\$filter\\/);

		if (($enabled) = /^Enabled\s*=B\s*(\w+);/o) {
			next;
		}

		if (/^([^=]+?)\s*=S\s*(.*?);/o) {
			$details{$1} = $2;
			$details{$1} =~ s/,/-/g; # Replace ',' with '-'.
		}
	}

	# Print collected filter information.
	print "$number,",&enabled($enabled);

	foreach ('shrt','source address','source mask','source asset','dest address','dest mask','dest asset','protocol','source port','dest port') {
		print ",$details{$_}";
	}
	print "\n";
}


sub rules {
	my( $fh, $event ) = @_;
	my( $eventenabled ) = 0;
	my( $priority );
	my( $response );
	my( $desc );
	my( %choice ) = ();
	my( %enabled ) = ();

	$event = quotemeta ($event);
	while ( <$fh> ) {
		chomp;
		last if (/^\[\\Advanced/o && !/\\$event\\/);

		if (/\\Response\\(\w+?)\\\]/o) {
			$response = $1;
			next;
		}

		if (/^Priority\s*=L\s*(\w+);/o) {
			$priority = $1;
			next;
		}

		if (/^CheckDescription\s*=S\s*(\S.*?)\s*;/o) {
			$desc = $1;
			$desc =~ s/,/-/go;
			next;
		}

		if (/^Enabled\s*=B\s*(\w+);/o) {
			if ( $response ) {
				$enabled{$response} = $1;
			} else {
				$eventenabled = $1;
			}
			next;
		}

		if (/^Choice\s*=S\s*(\w+);/o) {
			if ( $response ) {
				$choice{$response} = $1;
			}
			next;
		}
	}
	# Print collected feature information.
	$event =~ s/\\//g;
	print "$event,$desc,",&enabled($eventenabled),",";
	if	($priority eq 1) {	
		print "High";
	} elsif ($priority eq 2) {
		print "Medium";
	} elsif ($priority eq 3) {
		print "Low";
	} else {
		print "Unknown Priority";
	}

	foreach ('DISPLAY','LOGDB','DISABLE','RSKILL','SUSPEND','BANNER','SNMP','USER SPECIFIED','EMAIL') {
		print ",";
		if ( $enabled{$_} == 1 ) {
			if ( $choice{$_} =~ /^(Default)?$/i ) {
				print "YES";
			} else {
				print "$choice{$_}";
			}
		} else {
			print "NO";
		}
	}
	print "\n";
}


sub printtitle {
	local( $_ ) = shift;
	
	if (/^features$/o) { #   Prepare "features" output file.
		print "Event,Description,Enabled Flag,Priority,Display Setting,";
		print "Log Setting,SNMP,OPSEC Setting,View Session,Kill Response\n";

	} elsif (/^connections$/o) { #   Prepare "connections" output file.
		print "Number,Name,Enabled Flag,Priority,Source,Source Mask,";
		print "Destination,Dest. Mask,Protocol,Source Port,Dest. Port,";
		print "Display Setting,Log Setting,SNMP,OPSEC Setting,";
		print "View Session,Kill Response\n";

	} elsif (/^filters$/o) { #   Prepare "filters" output file.
		print "Number,Enabled Flag,Name,Source,Source Mask,Source Asset,";
		print "Destination,Dest. Mask,Dest. Asset,Protocol,Source Port,";
		print "Dest. Port\n";

	} elsif (/^rules$/o) { #   Prepare "rules" output file.
		print "Event,Description,Enabled Flag,Priority,Display Setting,";
		print "Log Setting,Disable Setting,Kill Response,Suspend Setting,";
		print "Banner,SNMP,User Specified,E-mail\n";
	}

}


##################################################################
# Main
##################################################################

# Get input filename and open it.
my( $filename ) = shift @ARGV;
usage("ERROR: No <filename> argument found.") if (! $filename);
open(IN,"< $filename") || usage("Failed opening file: $filename");

my( $shrt_filename ) = ($filename =~ /^(.+?)(\.policy)?$/o);

my( %titleline ) = ();

my( $report, $eventname );
my( $read ) = 1;
while ( ! eof(IN) ) {
	$_ = <IN> if ( $read );
	$read = 1;
	if ( !( ($report, $eventname) = /\[\\template\\([^\\]+)\\([^\\\]]+)/o )) {
		if ( ($eventname) = /\[\\Advanced\\Rules\\[^\\]+\\([^\\\]]+)/o ) {
			$report = 'rules';
		} else {
			next;
		}
	}
	if (($report) = ($report =~ /^(features|connections|filters|rules)$/o)) {
		if ( ! $titleline{$report} ) {
			open(OUT,">$shrt_filename.$report.csv") ||
				usage("Failed appending to file: $shrt_filename.$report.csv");
			select(OUT);
			printtitle($report);
			$titleline{$report} = 1;
		} else {
			open(OUT,">>$shrt_filename.$report.csv") ||
				usage("Failed appending to file: $shrt_filename.$report.csv");
			select(OUT);
		}
		&$report(\*IN,$eventname);
		close( OUT );
		$read =0;
	}
}

close( IN );

