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