scanoss 1.20.0__py3-none-any.whl → 1.20.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- protoc_gen_swagger/__init__.py +13 -13
- protoc_gen_swagger/options/__init__.py +13 -13
- protoc_gen_swagger/options/annotations_pb2.py +12 -9
- protoc_gen_swagger/options/annotations_pb2_grpc.py +1 -1
- protoc_gen_swagger/options/openapiv2_pb2.py +98 -96
- protoc_gen_swagger/options/openapiv2_pb2_grpc.py +1 -1
- scanoss/__init__.py +18 -18
- scanoss/api/__init__.py +17 -17
- scanoss/api/common/__init__.py +17 -17
- scanoss/api/common/v2/__init__.py +17 -17
- scanoss/api/common/v2/scanoss_common_pb2.py +18 -18
- scanoss/api/common/v2/scanoss_common_pb2_grpc.py +1 -1
- scanoss/api/components/__init__.py +17 -17
- scanoss/api/components/v2/__init__.py +17 -17
- scanoss/api/components/v2/scanoss_components_pb2.py +48 -38
- scanoss/api/components/v2/scanoss_components_pb2_grpc.py +142 -96
- scanoss/api/cryptography/v2/scanoss_cryptography_pb2.py +22 -16
- scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py +75 -49
- scanoss/api/dependencies/__init__.py +17 -17
- scanoss/api/dependencies/v2/__init__.py +17 -17
- scanoss/api/dependencies/v2/scanoss_dependencies_pb2.py +30 -24
- scanoss/api/dependencies/v2/scanoss_dependencies_pb2_grpc.py +75 -49
- scanoss/api/scanning/__init__.py +17 -17
- scanoss/api/scanning/v2/__init__.py +17 -17
- scanoss/api/scanning/v2/scanoss_scanning_pb2.py +10 -8
- scanoss/api/scanning/v2/scanoss_scanning_pb2_grpc.py +40 -32
- scanoss/api/semgrep/__init__.py +17 -17
- scanoss/api/semgrep/v2/__init__.py +17 -17
- scanoss/api/semgrep/v2/scanoss_semgrep_pb2.py +22 -18
- scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py +71 -49
- scanoss/api/vulnerabilities/__init__.py +17 -17
- scanoss/api/vulnerabilities/v2/__init__.py +17 -17
- scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py +37 -27
- scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py +109 -72
- scanoss/cli.py +576 -293
- scanoss/components.py +67 -45
- scanoss/csvoutput.py +83 -56
- scanoss/cyclonedx.py +48 -46
- scanoss/data/build_date.txt +1 -1
- scanoss/file_filters.py +13 -15
- scanoss/filecount.py +43 -36
- scanoss/inspection/__init__.py +17 -17
- scanoss/inspection/copyleft.py +71 -58
- scanoss/inspection/policy_check.py +76 -53
- scanoss/inspection/undeclared_component.py +98 -75
- scanoss/inspection/utils/license_utils.py +66 -44
- scanoss/results.py +51 -60
- scanoss/scancodedeps.py +61 -38
- scanoss/scanner.py +203 -135
- scanoss/scanoss_settings.py +5 -3
- scanoss/scanossapi.py +98 -69
- scanoss/scanossbase.py +19 -19
- scanoss/scanossgrpc.py +73 -51
- scanoss/scanpostprocessor.py +9 -6
- scanoss/scantype.py +22 -21
- scanoss/spdxlite.py +265 -171
- scanoss/threadeddependencies.py +91 -61
- scanoss/threadedscanning.py +37 -31
- scanoss/utils/file.py +4 -4
- scanoss/winnowing.py +111 -47
- {scanoss-1.20.0.dist-info → scanoss-1.20.1.dist-info}/METADATA +1 -1
- scanoss-1.20.1.dist-info/RECORD +74 -0
- scanoss-1.20.0.dist-info/RECORD +0 -74
- {scanoss-1.20.0.dist-info → scanoss-1.20.1.dist-info}/LICENSE +0 -0
- {scanoss-1.20.0.dist-info → scanoss-1.20.1.dist-info}/WHEEL +0 -0
- {scanoss-1.20.0.dist-info → scanoss-1.20.1.dist-info}/entry_points.txt +0 -0
- {scanoss-1.20.0.dist-info → scanoss-1.20.1.dist-info}/top_level.txt +0 -0
scanoss/components.py
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
2
|
+
SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2023, SCANOSS
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in
|
|
14
|
+
all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
22
|
+
THE SOFTWARE.
|
|
23
23
|
"""
|
|
24
|
+
|
|
24
25
|
import json
|
|
25
26
|
import os
|
|
26
27
|
import sys
|
|
@@ -38,10 +39,19 @@ class Components(ScanossBase):
|
|
|
38
39
|
Class for Component functionality
|
|
39
40
|
"""
|
|
40
41
|
|
|
41
|
-
def __init__(
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
42
|
+
def __init__(
|
|
43
|
+
self,
|
|
44
|
+
debug: bool = False,
|
|
45
|
+
trace: bool = False,
|
|
46
|
+
quiet: bool = False,
|
|
47
|
+
grpc_url: str = None,
|
|
48
|
+
api_key: str = None,
|
|
49
|
+
timeout: int = 600,
|
|
50
|
+
proxy: str = None,
|
|
51
|
+
grpc_proxy: str = None,
|
|
52
|
+
ca_cert: str = None,
|
|
53
|
+
pac: PACFile = None,
|
|
54
|
+
):
|
|
45
55
|
"""
|
|
46
56
|
Handle all component style requests
|
|
47
57
|
|
|
@@ -58,9 +68,19 @@ class Components(ScanossBase):
|
|
|
58
68
|
"""
|
|
59
69
|
super().__init__(debug, trace, quiet)
|
|
60
70
|
ver_details = Scanner.version_details()
|
|
61
|
-
self.grpc_api = ScanossGrpc(
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
self.grpc_api = ScanossGrpc(
|
|
72
|
+
url=grpc_url,
|
|
73
|
+
debug=debug,
|
|
74
|
+
quiet=quiet,
|
|
75
|
+
trace=trace,
|
|
76
|
+
api_key=api_key,
|
|
77
|
+
ver_details=ver_details,
|
|
78
|
+
ca_cert=ca_cert,
|
|
79
|
+
proxy=proxy,
|
|
80
|
+
pac=pac,
|
|
81
|
+
grpc_proxy=grpc_proxy,
|
|
82
|
+
timeout=timeout,
|
|
83
|
+
)
|
|
64
84
|
|
|
65
85
|
def load_purls(self, json_file: Optional[str] = None, purls: Optional[List[str]] = None) -> Optional[dict]:
|
|
66
86
|
"""
|
|
@@ -222,9 +242,17 @@ class Components(ScanossBase):
|
|
|
222
242
|
self._close_file(output_file, file)
|
|
223
243
|
return success
|
|
224
244
|
|
|
225
|
-
def search_components(
|
|
226
|
-
|
|
227
|
-
|
|
245
|
+
def search_components(
|
|
246
|
+
self,
|
|
247
|
+
output_file: str = None,
|
|
248
|
+
json_file: str = None,
|
|
249
|
+
search: str = None,
|
|
250
|
+
vendor: str = None,
|
|
251
|
+
comp: str = None,
|
|
252
|
+
package: str = None,
|
|
253
|
+
limit: int = None,
|
|
254
|
+
offset: int = None,
|
|
255
|
+
) -> bool:
|
|
228
256
|
"""
|
|
229
257
|
Search for a component based on the given search criteria
|
|
230
258
|
|
|
@@ -245,16 +273,11 @@ class Components(ScanossBase):
|
|
|
245
273
|
if request is None:
|
|
246
274
|
return False
|
|
247
275
|
else: # Construct a query dictionary from parameters
|
|
248
|
-
request = {
|
|
249
|
-
"search": search,
|
|
250
|
-
"vendor": vendor,
|
|
251
|
-
"component": comp,
|
|
252
|
-
"package": package
|
|
253
|
-
}
|
|
276
|
+
request = {'search': search, 'vendor': vendor, 'component': comp, 'package': package}
|
|
254
277
|
if limit is not None and limit > 0:
|
|
255
|
-
request[
|
|
278
|
+
request['limit'] = limit
|
|
256
279
|
if offset is not None and offset > 0:
|
|
257
|
-
request[
|
|
280
|
+
request['offset'] = offset
|
|
258
281
|
|
|
259
282
|
file = self._open_file_or_sdtout(output_file)
|
|
260
283
|
if file is None:
|
|
@@ -269,8 +292,9 @@ class Components(ScanossBase):
|
|
|
269
292
|
self._close_file(output_file, file)
|
|
270
293
|
return success
|
|
271
294
|
|
|
272
|
-
def get_component_versions(
|
|
273
|
-
|
|
295
|
+
def get_component_versions(
|
|
296
|
+
self, output_file: str = None, json_file: str = None, purl: str = None, limit: int = None
|
|
297
|
+
) -> bool:
|
|
274
298
|
"""
|
|
275
299
|
Search for a component versions based on the given search criteria
|
|
276
300
|
|
|
@@ -287,11 +311,9 @@ class Components(ScanossBase):
|
|
|
287
311
|
if request is None:
|
|
288
312
|
return False
|
|
289
313
|
else: # Construct a query dictionary from parameters
|
|
290
|
-
request = {
|
|
291
|
-
"purl": purl
|
|
292
|
-
}
|
|
314
|
+
request = {'purl': purl}
|
|
293
315
|
if limit is not None and limit > 0:
|
|
294
|
-
request[
|
|
316
|
+
request['limit'] = limit
|
|
295
317
|
|
|
296
318
|
file = self._open_file_or_sdtout(output_file)
|
|
297
319
|
if file is None:
|
scanoss/csvoutput.py
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
2
|
+
SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2022, SCANOSS
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in
|
|
14
|
+
all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
22
|
+
THE SOFTWARE.
|
|
23
23
|
"""
|
|
24
|
+
|
|
24
25
|
import json
|
|
25
26
|
import os.path
|
|
26
27
|
import sys
|
|
@@ -59,21 +60,21 @@ class CsvOutput(ScanossBase):
|
|
|
59
60
|
file_details = data.get(f)
|
|
60
61
|
# print(f'File: {f}: {file_details}')
|
|
61
62
|
for d in file_details:
|
|
62
|
-
id_details = d.get(
|
|
63
|
+
id_details = d.get('id')
|
|
63
64
|
if not id_details or id_details == 'none':
|
|
64
65
|
continue
|
|
65
|
-
matched = d.get(
|
|
66
|
-
lines = d.get(
|
|
67
|
-
oss_lines = d.get(
|
|
66
|
+
matched = d.get('matched', '')
|
|
67
|
+
lines = d.get('lines', '').replace(',', ';') # swap comma with semicolon to help basic parsers
|
|
68
|
+
oss_lines = d.get('oss_lines', '').replace(',', ';')
|
|
68
69
|
detected = {}
|
|
69
70
|
if id_details == 'dependency':
|
|
70
|
-
dependencies = d.get(
|
|
71
|
+
dependencies = d.get('dependencies')
|
|
71
72
|
if not dependencies:
|
|
72
73
|
self.print_stderr(f'Warning: No Dependencies found for {f}: {file_details}')
|
|
73
74
|
continue
|
|
74
75
|
for deps in dependencies:
|
|
75
76
|
detected = {}
|
|
76
|
-
purl = deps.get(
|
|
77
|
+
purl = deps.get('purl')
|
|
77
78
|
if not purl:
|
|
78
79
|
self.print_stderr(f'Warning: No PURL found for {f}: {deps}')
|
|
79
80
|
continue
|
|
@@ -84,7 +85,7 @@ class CsvOutput(ScanossBase):
|
|
|
84
85
|
dc = []
|
|
85
86
|
if licenses:
|
|
86
87
|
for lic in licenses:
|
|
87
|
-
name = lic.get(
|
|
88
|
+
name = lic.get('name')
|
|
88
89
|
if name and name not in dc: # Only save the license name once
|
|
89
90
|
dc.append(name)
|
|
90
91
|
if not dc or len(dc) == 0:
|
|
@@ -92,17 +93,23 @@ class CsvOutput(ScanossBase):
|
|
|
92
93
|
else:
|
|
93
94
|
detected['licenses'] = ';'.join(dc)
|
|
94
95
|
# inventory_id,path,usage,detected_component,detected_license,detected_version,detected_latest,purl
|
|
95
|
-
csv_dict.append(
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
96
|
+
csv_dict.append(
|
|
97
|
+
{
|
|
98
|
+
'inventory_id': row_id,
|
|
99
|
+
'path': f,
|
|
100
|
+
'detected_usage': id_details,
|
|
101
|
+
'detected_component': detected.get('component'),
|
|
102
|
+
'detected_license': detected.get('licenses'),
|
|
103
|
+
'detected_version': detected.get('version'),
|
|
104
|
+
'detected_latest': detected.get('latest'),
|
|
105
|
+
'detected_purls': detected.get('purls'),
|
|
106
|
+
'detected_url': detected.get('url'),
|
|
107
|
+
'detected_path': detected.get('file', ''),
|
|
108
|
+
'detected_match': matched,
|
|
109
|
+
'detected_lines': lines,
|
|
110
|
+
'detected_oss_lines': oss_lines,
|
|
111
|
+
}
|
|
112
|
+
)
|
|
106
113
|
row_id = row_id + 1
|
|
107
114
|
else:
|
|
108
115
|
purls = d.get('purl')
|
|
@@ -123,25 +130,31 @@ class CsvOutput(ScanossBase):
|
|
|
123
130
|
dc = []
|
|
124
131
|
if licenses:
|
|
125
132
|
for lic in licenses:
|
|
126
|
-
name = lic.get(
|
|
133
|
+
name = lic.get('name')
|
|
127
134
|
if name and name not in dc: # Only save the license name once
|
|
128
|
-
dc.append(lic.get(
|
|
135
|
+
dc.append(lic.get('name'))
|
|
129
136
|
if not dc or len(dc) == 0:
|
|
130
137
|
detected['licenses'] = ''
|
|
131
138
|
else:
|
|
132
139
|
detected['licenses'] = ';'.join(dc)
|
|
133
140
|
# inventory_id,path,usage,detected_component,detected_license,detected_version,detected_latest,purl
|
|
134
|
-
csv_dict.append(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
csv_dict.append(
|
|
142
|
+
{
|
|
143
|
+
'inventory_id': row_id,
|
|
144
|
+
'path': f,
|
|
145
|
+
'detected_usage': id_details,
|
|
146
|
+
'detected_component': detected.get('component'),
|
|
147
|
+
'detected_license': detected.get('licenses'),
|
|
148
|
+
'detected_version': detected.get('version'),
|
|
149
|
+
'detected_latest': detected.get('latest'),
|
|
150
|
+
'detected_purls': detected.get('purls'),
|
|
151
|
+
'detected_url': detected.get('url'),
|
|
152
|
+
'detected_path': detected.get('file', ''),
|
|
153
|
+
'detected_match': matched,
|
|
154
|
+
'detected_lines': lines,
|
|
155
|
+
'detected_oss_lines': oss_lines,
|
|
156
|
+
}
|
|
157
|
+
)
|
|
145
158
|
row_id = row_id + 1
|
|
146
159
|
return csv_dict
|
|
147
160
|
|
|
@@ -174,16 +187,28 @@ class CsvOutput(ScanossBase):
|
|
|
174
187
|
self.print_stderr('ERROR: No CSV data returned for the JSON string provided.')
|
|
175
188
|
return False
|
|
176
189
|
# Header row/column details
|
|
177
|
-
fields = [
|
|
178
|
-
|
|
179
|
-
|
|
190
|
+
fields = [
|
|
191
|
+
'inventory_id',
|
|
192
|
+
'path',
|
|
193
|
+
'detected_usage',
|
|
194
|
+
'detected_component',
|
|
195
|
+
'detected_license',
|
|
196
|
+
'detected_version',
|
|
197
|
+
'detected_latest',
|
|
198
|
+
'detected_purls',
|
|
199
|
+
'detected_url',
|
|
200
|
+
'detected_match',
|
|
201
|
+
'detected_lines',
|
|
202
|
+
'detected_oss_lines',
|
|
203
|
+
'detected_path',
|
|
204
|
+
]
|
|
180
205
|
file = sys.stdout
|
|
181
206
|
if not output_file and self.output_file:
|
|
182
207
|
output_file = self.output_file
|
|
183
208
|
if output_file:
|
|
184
209
|
file = open(output_file, 'w')
|
|
185
210
|
writer = csv.DictWriter(file, fieldnames=fields)
|
|
186
|
-
writer.writeheader()
|
|
211
|
+
writer.writeheader() # writing headers (field names)
|
|
187
212
|
writer.writerows(csv_data) # writing data rows
|
|
188
213
|
if output_file:
|
|
189
214
|
file.close()
|
|
@@ -206,6 +231,8 @@ class CsvOutput(ScanossBase):
|
|
|
206
231
|
self.print_stderr(f'ERROR: Problem parsing input JSON: {e}')
|
|
207
232
|
return False
|
|
208
233
|
return self.produce_from_json(data, output_file)
|
|
234
|
+
|
|
235
|
+
|
|
209
236
|
#
|
|
210
237
|
# End of CsvOutput Class
|
|
211
238
|
#
|
scanoss/cyclonedx.py
CHANGED
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
"""
|
|
2
|
-
|
|
2
|
+
SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
Copyright (c) 2021, SCANOSS
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
The above copyright notice and this permission notice shall be included in
|
|
14
|
+
all copies or substantial portions of the Software.
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
22
|
+
THE SOFTWARE.
|
|
23
23
|
"""
|
|
24
|
+
|
|
24
25
|
import json
|
|
25
26
|
import os.path
|
|
26
27
|
import sys
|
|
@@ -64,17 +65,17 @@ class CycloneDx(ScanossBase):
|
|
|
64
65
|
file_details = data.get(f)
|
|
65
66
|
# print(f'File: {f}: {file_details}')
|
|
66
67
|
for d in file_details:
|
|
67
|
-
id_details = d.get(
|
|
68
|
+
id_details = d.get('id')
|
|
68
69
|
if not id_details or id_details == 'none':
|
|
69
70
|
continue
|
|
70
71
|
purl = None
|
|
71
72
|
if id_details == 'dependency':
|
|
72
|
-
dependencies = d.get(
|
|
73
|
+
dependencies = d.get('dependencies')
|
|
73
74
|
if not dependencies:
|
|
74
75
|
self.print_stderr(f'Warning: No Dependencies found for {f}: {file_details}')
|
|
75
76
|
continue
|
|
76
77
|
for deps in dependencies:
|
|
77
|
-
purl = deps.get(
|
|
78
|
+
purl = deps.get('purl')
|
|
78
79
|
if not purl:
|
|
79
80
|
self.print_stderr(f'Warning: No PURL found for {f}: {deps}')
|
|
80
81
|
continue
|
|
@@ -89,7 +90,7 @@ class CycloneDx(ScanossBase):
|
|
|
89
90
|
if licenses:
|
|
90
91
|
dc = []
|
|
91
92
|
for lic in licenses:
|
|
92
|
-
name = lic.get(
|
|
93
|
+
name = lic.get('name')
|
|
93
94
|
if name not in dc: # Only save the license name once
|
|
94
95
|
fdl.append({'id': name})
|
|
95
96
|
dc.append(name)
|
|
@@ -108,30 +109,33 @@ class CycloneDx(ScanossBase):
|
|
|
108
109
|
self.print_stderr(f'Warning: No PURL found for {f}: {file_details}')
|
|
109
110
|
continue
|
|
110
111
|
fd = {}
|
|
111
|
-
vulnerabilities = d.get(
|
|
112
|
+
vulnerabilities = d.get('vulnerabilities')
|
|
112
113
|
if vulnerabilities:
|
|
113
114
|
for vuln in vulnerabilities:
|
|
114
|
-
vuln_id = vuln.get(
|
|
115
|
+
vuln_id = vuln.get('ID')
|
|
115
116
|
if vuln_id == '':
|
|
116
|
-
vuln_id = vuln.get(
|
|
117
|
+
vuln_id = vuln.get('id')
|
|
117
118
|
if not vuln_id or vuln_id == '': # Skip empty ids
|
|
118
119
|
continue
|
|
119
|
-
vuln_cve = vuln.get(
|
|
120
|
+
vuln_cve = vuln.get('CVE', '')
|
|
120
121
|
if vuln_cve == '':
|
|
121
|
-
vuln_cve = vuln.get(
|
|
122
|
-
if vuln_id.upper().startswith(
|
|
123
|
-
fd['cpe'] = vuln_id
|
|
122
|
+
vuln_cve = vuln.get('cve', '')
|
|
123
|
+
if vuln_id.upper().startswith('CPE:'):
|
|
124
|
+
fd['cpe'] = vuln_id # Save the component CPE if we have one
|
|
124
125
|
if vuln_cve != '':
|
|
125
126
|
vuln_id = vuln_cve
|
|
126
127
|
vd = vdx.get(vuln_id) # Check if we've already encountered this vulnerability
|
|
127
128
|
if not vd:
|
|
128
129
|
vuln_source = vuln.get('source', '').lower()
|
|
129
|
-
vd = {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
vd = {
|
|
131
|
+
'cve': vuln_cve,
|
|
132
|
+
'source': 'NVD' if vuln_source == 'nvd' else 'GitHub Advisories',
|
|
133
|
+
'url': f'https://nvd.nist.gov/vuln/detail/{vuln_cve}'
|
|
134
|
+
if vuln_source == 'nvd'
|
|
135
|
+
else f'https://github.com/advisories/{vuln_id}',
|
|
136
|
+
'severity': self._sev_lookup(vuln.get('severity', 'unknown').lower()),
|
|
137
|
+
'affects': set(),
|
|
138
|
+
}
|
|
135
139
|
vd.get('affects').add(purl)
|
|
136
140
|
vdx[vuln_id] = vd
|
|
137
141
|
if cdx.get(purl):
|
|
@@ -143,7 +147,7 @@ class CycloneDx(ScanossBase):
|
|
|
143
147
|
fdl = []
|
|
144
148
|
if licenses:
|
|
145
149
|
for lic in licenses:
|
|
146
|
-
fdl.append({'id': lic.get(
|
|
150
|
+
fdl.append({'id': lic.get('name')})
|
|
147
151
|
fd['licenses'] = fdl
|
|
148
152
|
cdx[purl] = fd
|
|
149
153
|
# self.print_stderr(f'VD: {vdx}')
|
|
@@ -190,7 +194,7 @@ class CycloneDx(ScanossBase):
|
|
|
190
194
|
'serialNumber': f'urn:uuid:{uuid.uuid4()}',
|
|
191
195
|
'version': 1,
|
|
192
196
|
'metadata': {
|
|
193
|
-
'timestamp': datetime.datetime.now(datetime.timezone.utc).strftime(
|
|
197
|
+
'timestamp': datetime.datetime.now(datetime.timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ'),
|
|
194
198
|
'tools': [
|
|
195
199
|
{
|
|
196
200
|
'vendor': 'SCANOSS',
|
|
@@ -198,14 +202,10 @@ class CycloneDx(ScanossBase):
|
|
|
198
202
|
'version': __version__,
|
|
199
203
|
}
|
|
200
204
|
],
|
|
201
|
-
'component': {
|
|
202
|
-
'type': 'application',
|
|
203
|
-
'name': 'NOASSERTION',
|
|
204
|
-
'version': 'NOASSERTION'
|
|
205
|
-
}
|
|
205
|
+
'component': {'type': 'application', 'name': 'NOASSERTION', 'version': 'NOASSERTION'},
|
|
206
206
|
},
|
|
207
207
|
'components': [],
|
|
208
|
-
'vulnerabilities': []
|
|
208
|
+
'vulnerabilities': [],
|
|
209
209
|
}
|
|
210
210
|
for purl in cdx:
|
|
211
211
|
comp = cdx.get(purl)
|
|
@@ -230,7 +230,7 @@ class CycloneDx(ScanossBase):
|
|
|
230
230
|
'version': comp.get('version'),
|
|
231
231
|
'purl': purl,
|
|
232
232
|
'bom-ref': purl,
|
|
233
|
-
'licenses': lic_text
|
|
233
|
+
'licenses': lic_text,
|
|
234
234
|
}
|
|
235
235
|
cpe = comp.get('cpe', '')
|
|
236
236
|
if cpe and cpe != '':
|
|
@@ -250,7 +250,7 @@ class CycloneDx(ScanossBase):
|
|
|
250
250
|
'id': vuln_id,
|
|
251
251
|
'source': {'name': v_source, 'url': vulns.get('url')},
|
|
252
252
|
'ratings': [{'severity': vulns.get('severity', 'unknown')}],
|
|
253
|
-
'affects': affects
|
|
253
|
+
'affects': affects,
|
|
254
254
|
}
|
|
255
255
|
data['vulnerabilities'].append(vd)
|
|
256
256
|
# End for loop
|
|
@@ -298,8 +298,10 @@ class CycloneDx(ScanossBase):
|
|
|
298
298
|
'low': 'low',
|
|
299
299
|
'info': 'info',
|
|
300
300
|
'none': 'none',
|
|
301
|
-
'unknown': 'unknown'
|
|
302
|
-
|
|
301
|
+
'unknown': 'unknown',
|
|
302
|
+
}.get(value, 'unknown')
|
|
303
|
+
|
|
304
|
+
|
|
303
305
|
#
|
|
304
306
|
# End of CycloneDX Class
|
|
305
307
|
#
|
scanoss/data/build_date.txt
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
date:
|
|
1
|
+
date: 20250219134430, utime: 1739972670
|
scanoss/file_filters.py
CHANGED
|
@@ -61,9 +61,7 @@ DEFAULT_SKIPPED_DIRS = {
|
|
|
61
61
|
'__pypackages__',
|
|
62
62
|
}
|
|
63
63
|
# Folder endings to skip
|
|
64
|
-
DEFAULT_SKIPPED_DIR_EXT = {
|
|
65
|
-
'.egg-info'
|
|
66
|
-
}
|
|
64
|
+
DEFAULT_SKIPPED_DIR_EXT = {'.egg-info'}
|
|
67
65
|
# File extensions to skip
|
|
68
66
|
DEFAULT_SKIPPED_EXT = {
|
|
69
67
|
'.1',
|
|
@@ -236,18 +234,18 @@ class FileFilters(ScanossBase):
|
|
|
236
234
|
"""
|
|
237
235
|
|
|
238
236
|
def __init__(
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
237
|
+
self,
|
|
238
|
+
debug: bool = False,
|
|
239
|
+
trace: bool = False,
|
|
240
|
+
quiet: bool = False,
|
|
241
|
+
scanoss_settings: 'ScanossSettings | None' = None,
|
|
242
|
+
all_extensions: bool = False,
|
|
243
|
+
all_folders: bool = False,
|
|
244
|
+
hidden_files_folders: bool = False,
|
|
245
|
+
operation_type: str = 'scanning',
|
|
246
|
+
skip_size: int = 0,
|
|
247
|
+
skip_extensions=None,
|
|
248
|
+
skip_folders=None,
|
|
251
249
|
):
|
|
252
250
|
"""
|
|
253
251
|
Initialize scan filters based on default settings. Optionally append custom settings.
|