File Coverage

blib/lib/App/CveClient.pm
Criterion Covered Total %
statement 48 97 49.4
branch 9 44 20.4
condition 1 3 33.3
subroutine 5 6 83.3
pod 0 3 0.0
total 63 153 41.1


line stmt bran cond sub pod time code
1             # CVE-Client: CLI-based client / toolbox for CVE.org
2             # Copyright © 2021-2023 CVE-Client Authors
3             # SPDX-License-Identifier: AGPL-3.0-only
4             package App::CveClient;
5             our $VERSION = 'v1.1.1';
6              
7 2     2   297003 use warnings;
  2         5  
  2         122  
8 2     2   14 use strict;
  2         4  
  2         95  
9              
10 2     2   14 use Exporter qw(import);
  2         2  
  2         2880  
11              
12             our @EXPORT_OK = qw(print_cve print_cve50 print_cve40);
13              
14             sub print_cve {
15 4     4 0 372994 my ($object, $cve_id, $format) = @_;
16              
17 4         207 print "CVE ID: ", $cve_id, "\n";
18              
19 4 0 33     27 if ($object->{'error'} and $object->{'message'}) {
20 0         0 die "Error ($object->{'error'}): $object->{'message'}\n";
21             }
22              
23 4 50       44 if ($object->{'dataVersion'} =~ /5\./) {
    0          
24 4         17 print_cve5($object, $cve_id, $format);
25             } elsif ($object->{'data_version'} == "4.0") {
26 0         0 print_cve4($object, $cve_id, $format);
27             } else {
28 0         0 print STDERR "Error: unknown CVE format:\n";
29             print STDERR "- data_version: ", $object->{'data_version'}, "\n"
30 0 0       0 if $object->{'data_version'};
31             print STDERR "- dataVersion: ", $object->{'dataVersion'}, "\n"
32 0 0       0 if $object->{'dataVersion'};
33             }
34             }
35              
36             # https://github.com/CVEProject/cve-schema/blob/master/schema/v5.0/
37             sub print_cve5 {
38 4     4 0 14 my ($object, $cve_id, $format) = @_;
39              
40 4 100       17 if ($object->{'cveMetadata'}->{'cveId'} ne $cve_id) {
41 2         50 print STDERR "Warning: Got <", $object->{'cveMetadata'}->{'cveId'},
42             "> instead of <", $cve_id, ">\n";
43             }
44              
45 4         15 my $affected = $object->{'containers'}->{'cna'}->{'affected'};
46 4 50       12 if ($affected) {
47 4         46 foreach (@{$affected}) {
  4         17  
48 4         211 print "Vendor Name: ", $_->{'vendor'}, "\n"; # vendor required
49 4         97 print "Product Name: ", $_->{'product'}, "\n"; # product required
50              
51 4         10 foreach (@{$_->{'versions'}}) {
  4         18  
52 4         148 print "- ", $_->{'status'}, ": ", $_->{'version'}, "\n";
53             }
54             }
55             } else {
56 0         0 print STDERR
57             "Warning: No CVE affected versions could be found! (as required by the spec)\n";
58             }
59              
60 4         48 print "\n";
61              
62 4         24 my $metrics = $object->{'containers'}->{'cna'}->{'metrics'};
63 4 100       15 if ($metrics) {
64 2         4 foreach (@{$metrics}) {
  2         5  
65 2 50       6 if ($_->{'cvssV3_1'}) {
66 2         5 my $metric = $_->{'cvssV3_1'};
67             print "- Score: ", $metric->{'baseScore'}, " ",
68 2         64 $metric->{'baseSeverity'}, "\n";
69             } else {
70 0         0 print "Notice: unhandled metrics (CVSS) data\n";
71             }
72             }
73             }
74              
75 4         42 print "\n";
76              
77 4         16 my $desc = $object->{'containers'}->{'cna'}->{'descriptions'};
78 4 50       10 if ($desc) {
79 4         7 foreach (@{$desc}) {
  4         83  
80 4         58 print "Description Language: ", $_->{'lang'}, "\n";
81 4         50 print "Description:\n", $_->{'value'}, "\n\n";
82             }
83             } else {
84 0         0 print STDERR
85             "Warning: No CVE description could be found! (as required by the spec)\n";
86             }
87              
88 4         41 print "\n";
89              
90 4         11 my $refs = $object->{'containers'}->{'cna'}->{'references'};
91 4 50       11 if ($refs) {
92 4         41 print "References: \n";
93              
94 4         29 foreach (@{$refs}) {
  4         152  
95 16         196 print "=> ", $_->{'url'}, "\n";
96             }
97             } else {
98 0           print STDERR
99             "Warning: No CVE references could be found! (as required by the spec)\n";
100             }
101             }
102              
103             # https://github.com/CVEProject/cve-schema/blob/master/schema/v4.0/
104             sub print_cve4 {
105 0     0 0   my ($object, $cve_id, $format) = @_;
106              
107 0 0         if ($object->{'CVE_data_meta'}->{'ID'} ne $cve_id) {
108 0           print STDERR "Warning: Got ", $object->{'CVE_data_meta'}->{'ID'},
109             " instead of ", $cve_id, "\n";
110             }
111              
112             print "TITLE: ", $object->{'CVE_data_meta'}->{'TITLE'}, "\n"
113 0 0         if $object->{'CVE_data_meta'}->{'TITLE'};
114              
115 0           print "\n";
116              
117 0 0         if ($object->{'affects'}->{'vendor'}) {
118 0           foreach (@{$object->{'affects'}->{'vendor'}->{'vendor_data'}}) {
  0            
119             print "Vendor Name: ", $_->{'vendor_name'}, "\n"
120 0 0         if $_->{'vendor_name'};
121              
122 0           foreach (@{$_->{'product'}->{'product_data'}}) {
  0            
123 0           print "Product name: ", $_->{'product_name'}, "\n";
124 0           print "Product versions: ";
125              
126 0           foreach (@{$_->{'version'}->{'version_data'}}) {
  0            
127 0           print $_->{'version_value'}, "; ";
128             }
129              
130 0           print "\n";
131             }
132             }
133             }
134              
135 0           print "\n";
136              
137 0 0         if ($object->{'description'}->{'description_data'}) {
138 0           my $descs = $object->{'description'}->{'description_data'};
139              
140 0           foreach (@{$descs}) {
  0            
141 0           print "Description Language: ", $_->{'lang'}, "\n";
142 0           print "Description:\n", $_->{'value'}, "\n\n";
143             }
144             } else {
145 0           print STDERR "Warning: No CVE description could be found!\n";
146             }
147              
148 0 0         if ($object->{'references'}->{'reference_data'}) {
149 0           my $refs = $object->{'references'}->{'reference_data'};
150              
151 0           foreach (@{$refs}) {
  0            
152 0 0         if ($format == 'gemini') {
153 0           print "Reference Source: ", $_->{'refsource'}, "\n";
154              
155 0 0         print "=> ", $_->{'url'} if $_->{'url'};
156 0 0         if ($_->{'name'}) {
157 0           print " ", $_->{'name'}, "\n\n";
158             } else {
159 0           print "\n\n";
160             }
161             } else {
162 0           print "Reference Source: ", $_->{'refsource'}, "\n";
163 0 0         print "- Name: ", $_->{'name'}, "\n" if $_->{'name'};
164 0 0         print "- URL: ", $_->{'url'}, "\n" if $_->{'url'};
165 0           print "\n";
166             }
167             }
168             } else {
169 0           print STDERR "Warning: No CVE references could be found!\n";
170             }
171             }
172              
173             1;