#
# perl/cve.pl
#
# by Sam, WWDSI 2/28/00
# added SANS top 10, 6/00
# converted to SANS top 20, 10/01
#
# SAINT support for Common Vulnerability Exposure and
# SANS top 20 vulnerability list

$cve_files = "rules/cve";

sub build_infer_cve {
    local($files) = @_;
    local($code, $cond, $top, $number);

    $code = "sub infer_cve {\n";

    foreach $file (split(/\s+/, $files)) {
	open(RULES, $file) || die "cannot open $file: $!";
	while (<RULES>) {
	    chop;
	    while (/\\$/) {
		chop;
		$_ .= <RULES>;
		chop;
	    }
	    s/#.*$//;
	    s/\s+$//;
	    next if /^$/;
	    s/@/\\@/g;
	    ($cond, $top, $number) = split(/\t+/, $_, 3);
	    $code .= "\tif (\$text =~ $cond) {\n";
	    $code .= "\t\t\$cve{\$text} = \"$number\";\n" if ($number);
	    $code .= "\t\t\$top20{\$text} = \"$top\";\n";
	    $code .= "\t}\n";
	}
	close(RULES);
    }
    $code .= "\t\$cve_data{\"\$top20{\$text}|\$cve{\$text}|\$text\"} = 1 if \$top20{\$text};\n";
    $code .= "}\n";
    return $code;
}

sub save_cves {
	local($path) = @_;

	open(CVES, ">$path") || die "cannot save cves to $path: $!";
	for (keys %cve_data) {
		print CVES "$_\n";
	}
	close(CVES);
}

sub clear_cves {
	%cve_data = ();
	%cve = ();
	%top20 = ();
}

sub read_cves {
	local($path) = @_;

	&clear_cves();
	&merge_cves($path);
}

sub merge_cves {
	local($path) = @_;
	local($t, $c, $text);

	open(CVES, $path) || die "Cannot read cve file $path: $!";
	print "Reading cves from $path...\n" if $debug;
	while (<CVES>) {
		chop;
		if (!exists($cve_data{$_})) {
			$cve_data{$_} = 1;
			($t, $c, $text) = split (/\|/,$_);
			$cve{$text} = $c;
			$top20{$text} = $t;
		}
	}
	close(CVES);
}

if ($running_under_saint) {
    eval &build_infer_cve($cve_files);
    die "error in $cve_files: $@" if $@;
}

1;
