#!/usr/bin/perl -w
# dumps all CVSS scores for all released updates into CSV.
use strict;

my $dn = `dirname $0`;chomp($dn);
my $pwd = `pwd`;chomp($pwd);
if ($dn !~ /^\//) { $dn = $pwd . "/" . $dn; }
push @INC,$dn;

use JSON;
use Data::Dumper;

require CPE;
require CanDBReader;
require SMASHData;

my %cve2cpe = ();

my @jsonfiles=<nvdcve-1.1-*.json>;
for my $jsonfile (@jsonfiles) {
	my $mapref;
	my $json;

	open(JSON,"<$jsonfile");
	$json = join("\n",<JSON>);
	close(JSON);

        eval {
                $mapref = decode_json($json);
        } or do {
                die "json invalid: $json\n";
        };
	my @allcves = @{$mapref->{"CVE_Items"}};
	foreach my $cveentry (@allcves) {
		my $cve = $cveentry->{"cve"}->{"CVE_data_meta"}->{"ID"};
		my @nodes = @{$cveentry->{"configurations"}->{"nodes"}};
		foreach my $node (@nodes) {
			my @cpematch = @{$node->{"cpe_match"}};
			foreach my $cpematch (@cpematch) {
				# print Dumper($cpematch);
				next if ($cpematch->{"cpe23Uri"} =~ /:apple:iphone/);
				next if ($cpematch->{"cpe23Uri"} =~ /:apple:mac_os_x/);
				next if ($cpematch->{"cpe23Uri"} =~ /:canonical:ubuntu_linux/);
				next if ($cpematch->{"cpe23Uri"} =~ /:cisco:crosswork_network_automation/);
				next if ($cpematch->{"cpe23Uri"} =~ /:cisco:integrated_management_controller_supervisor/);
				next if ($cpematch->{"cpe23Uri"} =~ /:cisco:unified/);
				next if ($cpematch->{"cpe23Uri"} =~ /:cisco:webex_meetings_server/);
				next if ($cpematch->{"cpe23Uri"} =~ /:conectiva:linux/);
				next if ($cpematch->{"cpe23Uri"} =~ /:debian:debian_linux:/);
				next if ($cpematch->{"cpe23Uri"} =~ /:fedoraproject:fedora/);
				next if ($cpematch->{"cpe23Uri"} =~ /:freebsd:freebsd/);
				next if ($cpematch->{"cpe23Uri"} =~ /:google:android:/);
				next if ($cpematch->{"cpe23Uri"} =~ /:intel:atom/);
				next if ($cpematch->{"cpe23Uri"} =~ /:intel:celeron/);
				next if ($cpematch->{"cpe23Uri"} =~ /:intel:computer_vision_annotation_tool/);
				next if ($cpematch->{"cpe23Uri"} =~ /:intel:core/);
				next if ($cpematch->{"cpe23Uri"} =~ /:intel:pentium/);
				next if ($cpematch->{"cpe23Uri"} =~ /:intel:xeon/);
				next if ($cpematch->{"cpe23Uri"} =~ /:netapp:active/);
				next if ($cpematch->{"cpe23Uri"} =~ /:netapp:hci/);
				next if ($cpematch->{"cpe23Uri"} =~ /:netapp:clustered_data_ontap/);
				next if ($cpematch->{"cpe23Uri"} =~ /:netapp:e-series/);
				next if ($cpematch->{"cpe23Uri"} =~ /:netapp:ontap_select_deploy_administration_utility/);
				next if ($cpematch->{"cpe23Uri"} =~ /:netapp:santricity_smi-s_provider/);
				next if ($cpematch->{"cpe23Uri"} =~ /:nullsoft:winamp/);
				next if ($cpematch->{"cpe23Uri"} =~ /:opensuse:leap/);
				next if ($cpematch->{"cpe23Uri"} =~ /:opensuse:opensuse/);
				next if ($cpematch->{"cpe23Uri"} =~ /:opensuse:backports_sle/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:agile/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:spatial_studio/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:managed_file_transfer/);
				next if ($cpematch->{"cpe23Uri"} =~ /:hp:envy/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:banking/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:banking_digital_experience/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:communications/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:communications_webrtc_session_controller/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:financial/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:flexcube_private_banking/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:health/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:hospitality/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:insurance/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:retail/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:policy/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:primavera/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:retail_returns_management/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:siebel/);
				next if ($cpematch->{"cpe23Uri"} =~ /:oracle:weblogic_server/);
				next if ($cpematch->{"cpe23Uri"} =~ /:redhat:decision/);
				next if ($cpematch->{"cpe23Uri"} =~ /:redhat:enterprise_linux/);
				next if ($cpematch->{"cpe23Uri"} =~ /:siemens:desigo_cc_advanced_reports/);
				next if ($cpematch->{"cpe23Uri"} =~ /:slackware:slackware_linux/);
				next if ($cpematch->{"cpe23Uri"} =~ /:turbolinux:turbolinux/);
				next if ($cpematch->{"cpe23Uri"} =~ /:ubuntu:ubuntu_linux/);
				next if ($cpematch->{"cpe23Uri"} =~ /:vmware:esxi/);
				push @{$cve2cpe{$cve}}, $cpematch->{"cpe23Uri"};
				# print "$cve - " . $cpematch->{"cpe23Uri"} . "\n";
			}
		}
	}
}
#print Dumper(\%cve2cpe);

my %cves = ();
open(TW,"data/ga/opensuse_tumbleweed.csv");
while (<TW>) {
        chomp;
        my ($date,$pkgs,$cve) = split(/,/);

        $cves{$cve} = $pkgs;
}
close(TW);

foreach my $cve (sort keys %CanDBReader::bugzillas) {
	&SMASHData::read_smash_issue($cve);

	if (!defined($SMASHData::state{$cve})) {
		print STDERR "no smash state for $cve?\n" if -t STDERR;
		next;
	}

	my %pkgs = ();

	if (defined($SMASHData::pkgstate{$cve})) {
		my %prods = %{$SMASHData::pkgstate{$cve}};

		foreach my $prod (keys %prods) {
			my %pkgstates = %{$prods{$prod}};
			#print STDERR "$prod\n";

			foreach my $pkg (sort keys %pkgstates) {
				next if ($pkg =~ /kernel-livepatch-/);
				next if ($pkg =~ /kgraft-patch-/);
				next if ($pkg =~ /firefox-libffi-gcc5/);
				next if ($pkg =~ /sles12-docker-image/);
				next if ($pkg =~ /sles12sp1-docker-image/);
				next if ($pkg =~ /sles11sp4-docker-image/);
				next if ($pkg =~ /MozillaFirefox-branding-SLE/);
				next if ($pkg =~ /(dtb-aarch64,dtb-armv7l,kernel-debug,kernel-kvmsmall,kernel-lpae,kernel-obs-qa,kernel-zfcpdump)/);
				next if ($pkg =~ /rpmlint/);
				next if (package2cpe($pkg));
				$pkgs{$pkg} = 1;
			}
		}
	}
	if (defined($cves{$cve})) {
		my (@pkgs) = split(/;/,$cves{$cve});
		foreach my $pkg (sort @pkgs) {
			$pkg =~ s/-[^-]*-[^-]*$//;


			next if ($pkg =~ /-devel/);
			next if ($pkg =~ /-lang/);
			next if ($pkg =~ /-doc/);
			next if ($pkg =~ /-32bit/);

			next if (package2cpe($pkg)) ;
			$pkgs{$pkg} = 1;
		}
	}
	if (defined($cve2cpe{$cve}) && %pkgs) {
		print "$cve - " . join(",",sort keys %pkgs) . " - " . join(",",@{$cve2cpe{$cve}}) . "\n";
	}
}
