Author: pere Date: 2011-02-07 13:49:40 +0000 (Mon, 07 Feb 2011) New Revision: 16078 Modified: bin/compare-nvd-cve Log: Improve CVE/CPE reporting. Modified: bin/compare-nvd-cve ==================================================================--- bin/compare-nvd-cve 2011-02-07 13:33:01 UTC (rev 16077) +++ bin/compare-nvd-cve 2011-02-07 13:49:40 UTC (rev 16078) @@ -8,63 +8,33 @@ use XML::Simple; use Data::Dumper; +use Getopt::Std; -use vars qw($debug %cpemap %cperevmap %cvemap %reportedmissing); +use vars qw(%opts $debug %cpealiases %cpemap %cperevmap %cvemap + %reportedmissing); $| = 1; -my %cpealiases; -open (my $fh, "<", "data/CPE/aliases") || die; -my $lastcpe = ""; -while (<$fh>) { - chomp; - s/#.*$//; # Remove comments - unless ($_) { - $lastcpe = ""; - next; - } - if ($lastcpe) { - $cpealiases{$_} = $lastcpe; - } else { - $cpealiases{$_} = $_; - $lastcpe = $_; - } -} -close ($fh); +getopts(''d'', \%opts); +$debug = exists $opts{''d''} ? 1 : 0; -sub cpe_expand_alias { - my $cpe = shift; - my $retval = $cpe; - if (defined $cpe && exists $cpealiases{$cpe}) { - $retval = $cpealiases{$cpe}; - } - return $retval; -} +cpe_load_aliases("data/CPE/aliases"); +cpe_load_list("data/CPE/list"); -open($fh, "<", "data/CPE/list") || die; -while (<$fh>) { - chomp; - s/#.*$//; # Remove comments - my ($binpkg, $cpe) = split(/;/); - $cpe = cpe_expand_alias($cpe); -# $cpe = "unknown-$binpkg" unless $cpe; - if ($cpe) { - $cpemap{$binpkg} = $cpe; - $cperevmap{$cpe} = $binpkg; - } -} -close $fh; - -open ($fh, "<", "data/CVE/list") || die; +open (my $fh, "<", "data/CVE/list") || die; my $cve; while (<$fh>) { chomp; $cve = $1 if (m/^(CVE-\S+)\s*/); s/^(\s+)\[\S+\] /$1/; # Trim away distribution name if ( m/^\s+- (\S+)\S*/ - && ! m/<not-affected>/ +# && ! m/<not-affected>/ ) { my $srcpkg = $1; + unless (exists $cpemap{$srcpkg}) { + my $cpe = "missing-cpe-for-$srcpkg";; + cpe_map_debiansrc($cpe, $srcpkg); + } if (exists $cvemap{$cve}) { push(@{$cvemap{$cve}}, $srcpkg); } else { @@ -80,24 +50,24 @@ for my $cvelist ( "nvdcve-2.0-2011.xml", -# "nvdcve-2.0-2010.xml", -# "nvdcve-2.0-2009.xml", -# "nvdcve-2.0-2008.xml", -# "nvdcve-2.0-2007.xml", -# "nvdcve-2.0-2006.xml", -# "nvdcve-2.0-2005.xml", -# "nvdcve-2.0-2004.xml", + "nvdcve-2.0-2010.xml", + "nvdcve-2.0-2009.xml", + "nvdcve-2.0-2008.xml", + "nvdcve-2.0-2007.xml", + "nvdcve-2.0-2006.xml", + "nvdcve-2.0-2005.xml", + "nvdcve-2.0-2004.xml", ) { - print "Loading $cvelist\n" if $debug; + print STDERR "Loading $cvelist\n" if $debug; my $ref = XMLin("../../" . $cvelist); for my $cve (sort {$b cmp $a} keys %{$ref->{entry}}) { - print "Checking $cve\n" if $debug; + print STDERR "Checking $cve\n" if $debug; my $entry = $ref->{entry}->{$cve}; my %info; my @debiancpe = get_debian_cpe($cve); for my $cpe (@debiancpe) { - $info{cpe_expand_alias($cpe)} = 1; + $info{cpe_expand_product_alias($cpe)} = 1; } my @products; @@ -108,11 +78,14 @@ @products = ($entry->{''vuln:vulnerable-software-list''}->{''vuln:product''}); } } + unless (1 || @products) { + print STDERR Dumper($entry); + } for my $cpe (@products) { - if (exists $info{cpe_expand_alias(cpe_product($cpe))}) { - $info{cpe_expand_alias(cpe_product($cpe))} += 2; + if (exists $info{cpe_expand_product_alias(cpe_product($cpe))}) { + $info{cpe_expand_product_alias(cpe_product($cpe))} += 2; } else { - $info{cpe_expand_alias(cpe_product($cpe))} = 2; + $info{cpe_expand_product_alias(cpe_product($cpe))} = 2; } } for my $cpe (sort keys %info) { @@ -130,7 +103,7 @@ } } } - print "Done loading $cvelist\n" if $debug; + print STDERR "Done loading $cvelist\n" if $debug; } for my $missing (sort { $reportedmissing{$a} <=> $reportedmissing{$b} } @@ -157,3 +130,53 @@ my $cpe = shift; return join(":", (split(/:/, $cpe))[0..3]); } + +sub cpe_map_debiansrc { + my ($cpe, $srcpkg) = @_; + if ($cpe) { + $cpemap{$srcpkg} = $cpe; + $cperevmap{$cpe} = $srcpkg; + } +} + +sub cpe_load_list { + my $filename = shift; + open(my $fh, "<", $filename) || + die "unable to load CPE list from $filename"; + while (<$fh>) { + chomp; + s/#.*$//; # Remove comments + my ($srcpkg, $cpe) = split(/;/); + $cpe = cpe_expand_product_alias($cpe); + cpe_map_debiansrc($cpe, $srcpkg); + } + close $fh; +} +sub cpe_load_aliases { + my $filename = shift; + open (my $fh, "<", $filename) || die; + my $lastcpe = ""; + while (<$fh>) { + chomp; + s/#.*$//; # Remove comments + unless ($_) { + $lastcpe = ""; + next; + } + if ($lastcpe) { + $cpealiases{$_} = $lastcpe; + } else { + $cpealiases{$_} = $_; + $lastcpe = $_; + } + } + close ($fh); +} +sub cpe_expand_product_alias { + my $cpe = shift; + my $retval = $cpe; + if (defined $cpe && exists $cpealiases{$cpe}) { + $retval = $cpealiases{$cpe}; + } + return $retval; +}