scanoss 1.20.4__tar.gz → 1.20.6__tar.gz
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.
- {scanoss-1.20.4/src/scanoss.egg-info → scanoss-1.20.6}/PKG-INFO +3 -2
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/__init__.py +1 -1
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/cli.py +41 -2
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/components.py +5 -3
- scanoss-1.20.6/src/scanoss/data/build_date.txt +1 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/scanner.py +25 -20
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/scanossapi.py +29 -7
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/scanossgrpc.py +117 -58
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/spdxlite.py +281 -30
- {scanoss-1.20.4 → scanoss-1.20.6/src/scanoss.egg-info}/PKG-INFO +3 -2
- scanoss-1.20.4/src/scanoss/data/build_date.txt +0 -1
- {scanoss-1.20.4 → scanoss-1.20.6}/LICENSE +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/PACKAGE.md +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/README.md +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/pyproject.toml +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/setup.cfg +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/protoc_gen_swagger/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/protoc_gen_swagger/options/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/protoc_gen_swagger/options/annotations_pb2.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/protoc_gen_swagger/options/annotations_pb2_grpc.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/protoc_gen_swagger/options/openapiv2_pb2.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/protoc_gen_swagger/options/openapiv2_pb2_grpc.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/common/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/common/v2/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/common/v2/scanoss_common_pb2.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/common/v2/scanoss_common_pb2_grpc.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/components/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/components/v2/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/components/v2/scanoss_components_pb2.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/components/v2/scanoss_components_pb2_grpc.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/cryptography/v2/scanoss_cryptography_pb2_grpc.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/dependencies/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/dependencies/v2/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/dependencies/v2/scanoss_dependencies_pb2_grpc.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/provenance/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/provenance/v2/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/provenance/v2/scanoss_provenance_pb2.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/provenance/v2/scanoss_provenance_pb2_grpc.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/scanning/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/scanning/v2/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/scanning/v2/scanoss_scanning_pb2.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/scanning/v2/scanoss_scanning_pb2_grpc.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/semgrep/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/semgrep/v2/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/semgrep/v2/scanoss_semgrep_pb2.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/semgrep/v2/scanoss_semgrep_pb2_grpc.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/vulnerabilities/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/vulnerabilities/v2/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/api/vulnerabilities/v2/scanoss_vulnerabilities_pb2_grpc.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/csvoutput.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/cyclonedx.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/data/scanoss-settings-schema.json +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/data/spdx-exceptions.json +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/data/spdx-licenses.json +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/file_filters.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/filecount.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/inspection/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/inspection/copyleft.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/inspection/policy_check.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/inspection/undeclared_component.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/inspection/utils/license_utils.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/results.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/scancodedeps.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/scanoss_settings.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/scanossbase.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/scanpostprocessor.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/scantype.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/threadeddependencies.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/threadedscanning.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/utils/__init__.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/utils/file.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss/winnowing.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss.egg-info/SOURCES.txt +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss.egg-info/dependency_links.txt +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss.egg-info/entry_points.txt +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss.egg-info/requires.txt +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/src/scanoss.egg-info/top_level.txt +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/tests/test_csv_output.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/tests/test_file_filters.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/tests/test_policy_inspect.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/tests/test_scan_post_processor.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/tests/test_spdxlite.py +0 -0
- {scanoss-1.20.4 → scanoss-1.20.6}/tests/test_winnowing.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: scanoss
|
|
3
|
-
Version: 1.20.
|
|
3
|
+
Version: 1.20.6
|
|
4
4
|
Summary: Simple Python library to leverage the SCANOSS APIs
|
|
5
5
|
Home-page: https://scanoss.com
|
|
6
6
|
Author: SCANOSS
|
|
@@ -31,6 +31,7 @@ Requires-Dist: pathspec
|
|
|
31
31
|
Requires-Dist: jsonschema
|
|
32
32
|
Provides-Extra: fast-winnowing
|
|
33
33
|
Requires-Dist: scanoss_winnowing>=0.5.0; extra == "fast-winnowing"
|
|
34
|
+
Dynamic: license-file
|
|
34
35
|
|
|
35
36
|
# SCANOSS Python Package
|
|
36
37
|
The SCANOSS python package provides a simple easy to consume library for interacting with SCANOSS APIs/Engine.
|
|
@@ -28,6 +28,7 @@ import sys
|
|
|
28
28
|
from pathlib import Path
|
|
29
29
|
|
|
30
30
|
import pypac
|
|
31
|
+
from typing import List
|
|
31
32
|
|
|
32
33
|
from . import __version__
|
|
33
34
|
from .components import Components
|
|
@@ -50,6 +51,7 @@ DEFAULT_TIMEOUT = 180
|
|
|
50
51
|
MIN_TIMEOUT_VALUE = 5
|
|
51
52
|
DEFAULT_RETRY = 5
|
|
52
53
|
PYTHON3_OR_LATER = 3
|
|
54
|
+
HEADER_PARTS_COUNT = 2
|
|
53
55
|
|
|
54
56
|
def print_stderr(*args, **kwargs):
|
|
55
57
|
"""
|
|
@@ -567,6 +569,12 @@ def setup_args() -> None: # noqa: PLR0915
|
|
|
567
569
|
help='GRPC Proxy URL to use for connections (optional). '
|
|
568
570
|
'Can also use the environment variable "grcp_proxy=<ip>:<port>"',
|
|
569
571
|
)
|
|
572
|
+
p.add_argument(
|
|
573
|
+
'--header','-hdr',
|
|
574
|
+
action='append', # This allows multiple -H flags
|
|
575
|
+
type=str,
|
|
576
|
+
help='Headers to be sent on request (e.g., -hdr "Name: Value") - can be used multiple times'
|
|
577
|
+
)
|
|
570
578
|
|
|
571
579
|
# Help/Trace command options
|
|
572
580
|
for p in [
|
|
@@ -605,7 +613,6 @@ def setup_args() -> None: # noqa: PLR0915
|
|
|
605
613
|
sys.exit(1)
|
|
606
614
|
args.func(parser, args) # Execute the function associated with the sub-command
|
|
607
615
|
|
|
608
|
-
|
|
609
616
|
def ver(*_):
|
|
610
617
|
"""
|
|
611
618
|
Run the "ver" sub-command
|
|
@@ -903,6 +910,7 @@ def scan(parser, args): # noqa: PLR0912, PLR0915
|
|
|
903
910
|
strip_hpsm_ids=args.strip_hpsm,
|
|
904
911
|
strip_snippet_ids=args.strip_snippet,
|
|
905
912
|
scan_settings=scan_settings,
|
|
913
|
+
req_headers= process_req_headers(args.header),
|
|
906
914
|
)
|
|
907
915
|
if args.wfp:
|
|
908
916
|
if not scanner.is_file_or_snippet_scan():
|
|
@@ -1228,6 +1236,7 @@ def comp_crypto(parser, args):
|
|
|
1228
1236
|
print_stderr(f'Error: Certificate file does not exist: {args.ca_cert}.')
|
|
1229
1237
|
sys.exit(1)
|
|
1230
1238
|
pac_file = get_pac_file(args.pac)
|
|
1239
|
+
|
|
1231
1240
|
comps = Components(
|
|
1232
1241
|
debug=args.debug,
|
|
1233
1242
|
trace=args.trace,
|
|
@@ -1239,6 +1248,7 @@ def comp_crypto(parser, args):
|
|
|
1239
1248
|
grpc_proxy=args.grpc_proxy,
|
|
1240
1249
|
pac=pac_file,
|
|
1241
1250
|
timeout=args.timeout,
|
|
1251
|
+
req_headers= process_req_headers(args.header),
|
|
1242
1252
|
)
|
|
1243
1253
|
if not comps.get_crypto_details(args.input, args.purl, args.output):
|
|
1244
1254
|
sys.exit(1)
|
|
@@ -1273,6 +1283,7 @@ def comp_vulns(parser, args):
|
|
|
1273
1283
|
grpc_proxy=args.grpc_proxy,
|
|
1274
1284
|
pac=pac_file,
|
|
1275
1285
|
timeout=args.timeout,
|
|
1286
|
+
req_headers=process_req_headers(args.header),
|
|
1276
1287
|
)
|
|
1277
1288
|
if not comps.get_vulnerabilities(args.input, args.purl, args.output):
|
|
1278
1289
|
sys.exit(1)
|
|
@@ -1307,6 +1318,7 @@ def comp_semgrep(parser, args):
|
|
|
1307
1318
|
grpc_proxy=args.grpc_proxy,
|
|
1308
1319
|
pac=pac_file,
|
|
1309
1320
|
timeout=args.timeout,
|
|
1321
|
+
req_headers=process_req_headers(args.header),
|
|
1310
1322
|
)
|
|
1311
1323
|
if not comps.get_semgrep_details(args.input, args.purl, args.output):
|
|
1312
1324
|
sys.exit(1)
|
|
@@ -1344,6 +1356,7 @@ def comp_search(parser, args):
|
|
|
1344
1356
|
grpc_proxy=args.grpc_proxy,
|
|
1345
1357
|
pac=pac_file,
|
|
1346
1358
|
timeout=args.timeout,
|
|
1359
|
+
req_headers=process_req_headers(args.header),
|
|
1347
1360
|
)
|
|
1348
1361
|
if not comps.search_components(
|
|
1349
1362
|
args.output,
|
|
@@ -1388,6 +1401,7 @@ def comp_versions(parser, args):
|
|
|
1388
1401
|
grpc_proxy=args.grpc_proxy,
|
|
1389
1402
|
pac=pac_file,
|
|
1390
1403
|
timeout=args.timeout,
|
|
1404
|
+
req_headers=process_req_headers(args.header),
|
|
1391
1405
|
)
|
|
1392
1406
|
if not comps.get_component_versions(args.output, json_file=args.input, purl=args.purl, limit=args.limit):
|
|
1393
1407
|
sys.exit(1)
|
|
@@ -1412,7 +1426,7 @@ def comp_provenance(parser, args):
|
|
|
1412
1426
|
pac_file = get_pac_file(args.pac)
|
|
1413
1427
|
comps = Components(debug=args.debug, trace=args.trace, quiet=args.quiet, grpc_url=args.api2url, api_key=args.key,
|
|
1414
1428
|
ca_cert=args.ca_cert, proxy=args.proxy, grpc_proxy=args.grpc_proxy, pac=pac_file,
|
|
1415
|
-
timeout=args.timeout)
|
|
1429
|
+
timeout=args.timeout, req_headers=process_req_headers(args.header))
|
|
1416
1430
|
if not comps.get_provenance_details(args.input, args.purl, args.output):
|
|
1417
1431
|
sys.exit(1)
|
|
1418
1432
|
|
|
@@ -1456,6 +1470,31 @@ def results(parser, args):
|
|
|
1456
1470
|
results.apply_filters().present()
|
|
1457
1471
|
|
|
1458
1472
|
|
|
1473
|
+
def process_req_headers(headers_array: List[str]) -> dict:
|
|
1474
|
+
"""
|
|
1475
|
+
Process a list of header strings in the format "Name: Value" into a dictionary.
|
|
1476
|
+
|
|
1477
|
+
Args:
|
|
1478
|
+
headers_array (list): List of header strings from command line args
|
|
1479
|
+
|
|
1480
|
+
Returns:
|
|
1481
|
+
dict: Dictionary of header name-value pairs
|
|
1482
|
+
"""
|
|
1483
|
+
# Check if headers_array is empty
|
|
1484
|
+
if not headers_array:
|
|
1485
|
+
# Array is empty
|
|
1486
|
+
return {}
|
|
1487
|
+
|
|
1488
|
+
dict_headers = {}
|
|
1489
|
+
for header_str in headers_array:
|
|
1490
|
+
# Split each "Name: Value" header
|
|
1491
|
+
parts = header_str.split(":", 1)
|
|
1492
|
+
if len(parts) == HEADER_PARTS_COUNT:
|
|
1493
|
+
name = parts[0].strip()
|
|
1494
|
+
value = parts[1].strip()
|
|
1495
|
+
dict_headers[name] = value
|
|
1496
|
+
return dict_headers
|
|
1497
|
+
|
|
1459
1498
|
def main():
|
|
1460
1499
|
"""
|
|
1461
1500
|
Run the ScanOSS CLI
|
|
@@ -25,7 +25,7 @@ SPDX-License-Identifier: MIT
|
|
|
25
25
|
import json
|
|
26
26
|
import os
|
|
27
27
|
import sys
|
|
28
|
-
from typing import
|
|
28
|
+
from typing import List, Optional, TextIO
|
|
29
29
|
|
|
30
30
|
from pypac.parser import PACFile
|
|
31
31
|
|
|
@@ -39,7 +39,7 @@ class Components(ScanossBase):
|
|
|
39
39
|
Class for Component functionality
|
|
40
40
|
"""
|
|
41
41
|
|
|
42
|
-
def __init__(
|
|
42
|
+
def __init__( # noqa: PLR0913, PLR0915
|
|
43
43
|
self,
|
|
44
44
|
debug: bool = False,
|
|
45
45
|
trace: bool = False,
|
|
@@ -51,6 +51,7 @@ class Components(ScanossBase):
|
|
|
51
51
|
grpc_proxy: str = None,
|
|
52
52
|
ca_cert: str = None,
|
|
53
53
|
pac: PACFile = None,
|
|
54
|
+
req_headers: dict = None,
|
|
54
55
|
):
|
|
55
56
|
"""
|
|
56
57
|
Handle all component style requests
|
|
@@ -80,6 +81,7 @@ class Components(ScanossBase):
|
|
|
80
81
|
pac=pac,
|
|
81
82
|
grpc_proxy=grpc_proxy,
|
|
82
83
|
timeout=timeout,
|
|
84
|
+
req_headers=req_headers,
|
|
83
85
|
)
|
|
84
86
|
|
|
85
87
|
def load_purls(self, json_file: Optional[str] = None, purls: Optional[List[str]] = None) -> Optional[dict]:
|
|
@@ -242,7 +244,7 @@ class Components(ScanossBase):
|
|
|
242
244
|
self._close_file(output_file, file)
|
|
243
245
|
return success
|
|
244
246
|
|
|
245
|
-
def search_components(
|
|
247
|
+
def search_components( # noqa: PLR0913, PLR0915
|
|
246
248
|
self,
|
|
247
249
|
output_file: str = None,
|
|
248
250
|
json_file: str = None,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
date: 20250320002157, utime: 1742430117
|
|
@@ -69,7 +69,7 @@ class Scanner(ScanossBase):
|
|
|
69
69
|
Handle the scanning of files, snippets and dependencies
|
|
70
70
|
"""
|
|
71
71
|
|
|
72
|
-
def __init__(
|
|
72
|
+
def __init__( # noqa: PLR0913, PLR0915
|
|
73
73
|
self,
|
|
74
74
|
wfp: str = None,
|
|
75
75
|
scan_output: str = None,
|
|
@@ -106,6 +106,7 @@ class Scanner(ScanossBase):
|
|
|
106
106
|
strip_snippet_ids=None,
|
|
107
107
|
skip_md5_ids=None,
|
|
108
108
|
scan_settings: 'ScanossSettings | None' = None,
|
|
109
|
+
req_headers: dict = None,
|
|
109
110
|
):
|
|
110
111
|
"""
|
|
111
112
|
Initialise scanning class, including Winnowing, ScanossApi, ThreadedScanning
|
|
@@ -129,6 +130,7 @@ class Scanner(ScanossBase):
|
|
|
129
130
|
self.skip_folders = skip_folders
|
|
130
131
|
self.skip_size = skip_size
|
|
131
132
|
self.skip_extensions = skip_extensions
|
|
133
|
+
self.req_headers = req_headers
|
|
132
134
|
ver_details = Scanner.version_details()
|
|
133
135
|
|
|
134
136
|
self.winnowing = Winnowing(
|
|
@@ -156,6 +158,7 @@ class Scanner(ScanossBase):
|
|
|
156
158
|
ca_cert=ca_cert,
|
|
157
159
|
pac=pac,
|
|
158
160
|
retry=retry,
|
|
161
|
+
req_headers= self.req_headers,
|
|
159
162
|
)
|
|
160
163
|
sc_deps = ScancodeDeps(debug=debug, quiet=quiet, trace=trace, timeout=sc_timeout, sc_command=sc_command)
|
|
161
164
|
grpc_api = ScanossGrpc(
|
|
@@ -169,6 +172,7 @@ class Scanner(ScanossBase):
|
|
|
169
172
|
proxy=proxy,
|
|
170
173
|
pac=pac,
|
|
171
174
|
grpc_proxy=grpc_proxy,
|
|
175
|
+
req_headers=self.req_headers,
|
|
172
176
|
)
|
|
173
177
|
self.threaded_deps = ThreadedDependencies(sc_deps, grpc_api, debug=debug, quiet=quiet, trace=trace)
|
|
174
178
|
self.nb_threads = nb_threads
|
|
@@ -302,7 +306,7 @@ class Scanner(ScanossBase):
|
|
|
302
306
|
|
|
303
307
|
success = True
|
|
304
308
|
if not scan_dir:
|
|
305
|
-
raise Exception(
|
|
309
|
+
raise Exception('ERROR: Please specify a folder to scan')
|
|
306
310
|
if not os.path.exists(scan_dir) or not os.path.isdir(scan_dir):
|
|
307
311
|
raise Exception(f'ERROR: Specified folder does not exist or is not a folder: {scan_dir}')
|
|
308
312
|
if not self.is_file_or_snippet_scan() and not self.is_dependency_scan():
|
|
@@ -386,7 +390,8 @@ class Scanner(ScanossBase):
|
|
|
386
390
|
file_count += 1
|
|
387
391
|
if self.threaded_scan:
|
|
388
392
|
wfp_size = len(wfp.encode('utf-8'))
|
|
389
|
-
# If the WFP is bigger than the max post size and we already have something stored in the scan block,
|
|
393
|
+
# If the WFP is bigger than the max post size and we already have something stored in the scan block,
|
|
394
|
+
# add it to the queue
|
|
390
395
|
if scan_block != '' and (wfp_size + scan_size) >= self.max_post_size:
|
|
391
396
|
self.threaded_scan.queue_add(scan_block)
|
|
392
397
|
queue_size += 1
|
|
@@ -436,7 +441,7 @@ class Scanner(ScanossBase):
|
|
|
436
441
|
self.threaded_scan.update_bar(create=True, file_count=file_count)
|
|
437
442
|
if not scan_started:
|
|
438
443
|
if not self.threaded_scan.run(wait=False): # Run the scan but do not wait for it to complete
|
|
439
|
-
self.print_stderr(
|
|
444
|
+
self.print_stderr('Warning: Some errors encounted while scanning. Results might be incomplete.')
|
|
440
445
|
success = False
|
|
441
446
|
return success
|
|
442
447
|
|
|
@@ -457,14 +462,14 @@ class Scanner(ScanossBase):
|
|
|
457
462
|
dep_responses = None
|
|
458
463
|
if self.is_file_or_snippet_scan():
|
|
459
464
|
if not self.threaded_scan.complete(): # Wait for the scans to complete
|
|
460
|
-
self.print_stderr(
|
|
465
|
+
self.print_stderr('Warning: Scanning analysis ran into some trouble.')
|
|
461
466
|
success = False
|
|
462
467
|
self.threaded_scan.complete_bar()
|
|
463
468
|
scan_responses = self.threaded_scan.responses
|
|
464
469
|
if self.is_dependency_scan():
|
|
465
470
|
self.print_msg('Retrieving dependency data...')
|
|
466
471
|
if not self.threaded_deps.complete():
|
|
467
|
-
self.print_stderr(
|
|
472
|
+
self.print_stderr('Warning: Dependency analysis ran into some trouble.')
|
|
468
473
|
success = False
|
|
469
474
|
dep_responses = self.threaded_deps.responses
|
|
470
475
|
|
|
@@ -546,7 +551,7 @@ class Scanner(ScanossBase):
|
|
|
546
551
|
"""
|
|
547
552
|
success = True
|
|
548
553
|
if not file:
|
|
549
|
-
raise Exception(
|
|
554
|
+
raise Exception('ERROR: Please specify a file to scan')
|
|
550
555
|
if not os.path.exists(file) or not os.path.isfile(file):
|
|
551
556
|
raise Exception(f'ERROR: Specified file does not exist or is not a file: {file}')
|
|
552
557
|
if not self.is_file_or_snippet_scan() and not self.is_dependency_scan():
|
|
@@ -583,7 +588,7 @@ class Scanner(ScanossBase):
|
|
|
583
588
|
"""
|
|
584
589
|
success = True
|
|
585
590
|
if not file:
|
|
586
|
-
raise Exception(
|
|
591
|
+
raise Exception('ERROR: Please specify a file to scan')
|
|
587
592
|
if not os.path.exists(file) or not os.path.isfile(file):
|
|
588
593
|
raise Exception(f'ERROR: Specified files does not exist or is not a file: {file}')
|
|
589
594
|
self.print_debug(f'Fingerprinting {file}...')
|
|
@@ -608,7 +613,7 @@ class Scanner(ScanossBase):
|
|
|
608
613
|
"""
|
|
609
614
|
success = True
|
|
610
615
|
if not files:
|
|
611
|
-
raise Exception(
|
|
616
|
+
raise Exception('ERROR: Please provide a non-empty list of filenames to scan')
|
|
612
617
|
|
|
613
618
|
file_filters = FileFilters(
|
|
614
619
|
debug=self.debug,
|
|
@@ -671,7 +676,7 @@ class Scanner(ScanossBase):
|
|
|
671
676
|
scan_started = True
|
|
672
677
|
if not self.threaded_scan.run(wait=False):
|
|
673
678
|
self.print_stderr(
|
|
674
|
-
|
|
679
|
+
'Warning: Some errors encounted while scanning. Results might be incomplete.'
|
|
675
680
|
)
|
|
676
681
|
success = False
|
|
677
682
|
|
|
@@ -704,12 +709,12 @@ class Scanner(ScanossBase):
|
|
|
704
709
|
"""
|
|
705
710
|
success = True
|
|
706
711
|
if not files:
|
|
707
|
-
raise Exception(
|
|
712
|
+
raise Exception('ERROR: Please specify a list of files to scan')
|
|
708
713
|
if not self.is_file_or_snippet_scan():
|
|
709
714
|
raise Exception(f'ERROR: file or snippet scan options have to be set to scan files: {files}')
|
|
710
715
|
if self.is_dependency_scan() or deps_file:
|
|
711
716
|
raise Exception(
|
|
712
|
-
|
|
717
|
+
'ERROR: The dependency scan option is currently not supported when scanning a list of files'
|
|
713
718
|
)
|
|
714
719
|
if self.scan_output:
|
|
715
720
|
self.print_msg(f'Writing results to {self.scan_output}...')
|
|
@@ -731,9 +736,9 @@ class Scanner(ScanossBase):
|
|
|
731
736
|
"""
|
|
732
737
|
success = True
|
|
733
738
|
if not filename:
|
|
734
|
-
raise Exception(
|
|
739
|
+
raise Exception('ERROR: Please specify a filename to scan')
|
|
735
740
|
if not contents:
|
|
736
|
-
raise Exception(
|
|
741
|
+
raise Exception('ERROR: Please specify a file contents to scan')
|
|
737
742
|
|
|
738
743
|
self.print_debug(f'Fingerprinting {filename}...')
|
|
739
744
|
wfp = self.winnowing.wfp_for_contents(filename, False, contents)
|
|
@@ -924,7 +929,7 @@ class Scanner(ScanossBase):
|
|
|
924
929
|
scan_started = True
|
|
925
930
|
if not self.threaded_scan.run(wait=False):
|
|
926
931
|
self.print_stderr(
|
|
927
|
-
|
|
932
|
+
'Warning: Some errors uncounted while scanning. Results might be incomplete.'
|
|
928
933
|
)
|
|
929
934
|
success = False
|
|
930
935
|
# End for loop
|
|
@@ -948,7 +953,7 @@ class Scanner(ScanossBase):
|
|
|
948
953
|
"""
|
|
949
954
|
success = True
|
|
950
955
|
if not wfp:
|
|
951
|
-
raise Exception(
|
|
956
|
+
raise Exception('ERROR: Please specify a WFP to scan')
|
|
952
957
|
raw_output = '{\n'
|
|
953
958
|
scan_resp = self.scanoss_api.scan(wfp)
|
|
954
959
|
if scan_resp is not None:
|
|
@@ -984,9 +989,9 @@ class Scanner(ScanossBase):
|
|
|
984
989
|
:return:
|
|
985
990
|
"""
|
|
986
991
|
if not filename:
|
|
987
|
-
raise Exception(
|
|
992
|
+
raise Exception('ERROR: Please specify a filename to scan')
|
|
988
993
|
if not contents:
|
|
989
|
-
raise Exception(
|
|
994
|
+
raise Exception('ERROR: Please specify a file contents to scan')
|
|
990
995
|
|
|
991
996
|
self.print_debug(f'Fingerprinting {filename}...')
|
|
992
997
|
wfp = self.winnowing.wfp_for_contents(filename, False, contents)
|
|
@@ -1005,7 +1010,7 @@ class Scanner(ScanossBase):
|
|
|
1005
1010
|
Fingerprint the specified file
|
|
1006
1011
|
"""
|
|
1007
1012
|
if not scan_file:
|
|
1008
|
-
raise Exception(
|
|
1013
|
+
raise Exception('ERROR: Please specify a file to fingerprint')
|
|
1009
1014
|
if not os.path.exists(scan_file) or not os.path.isfile(scan_file):
|
|
1010
1015
|
raise Exception(f'ERROR: Specified file does not exist or is not a file: {scan_file}')
|
|
1011
1016
|
|
|
@@ -1026,7 +1031,7 @@ class Scanner(ScanossBase):
|
|
|
1026
1031
|
Fingerprint the specified folder producing fingerprints
|
|
1027
1032
|
"""
|
|
1028
1033
|
if not scan_dir:
|
|
1029
|
-
raise Exception(
|
|
1034
|
+
raise Exception('ERROR: Please specify a folder to fingerprint')
|
|
1030
1035
|
if not os.path.exists(scan_dir) or not os.path.isdir(scan_dir):
|
|
1031
1036
|
raise Exception(f'ERROR: Specified folder does not exist or is not a folder: {scan_dir}')
|
|
1032
1037
|
file_filters = FileFilters(
|
|
@@ -52,7 +52,7 @@ class ScanossApi(ScanossBase):
|
|
|
52
52
|
Currently support posting scan requests to the SCANOSS streaming API
|
|
53
53
|
"""
|
|
54
54
|
|
|
55
|
-
def __init__(
|
|
55
|
+
def __init__( # noqa: PLR0913, PLR0915
|
|
56
56
|
self,
|
|
57
57
|
scan_format: str = None,
|
|
58
58
|
flags: str = None,
|
|
@@ -68,6 +68,7 @@ class ScanossApi(ScanossBase):
|
|
|
68
68
|
ca_cert: str = None,
|
|
69
69
|
pac: PACFile = None,
|
|
70
70
|
retry: int = 5,
|
|
71
|
+
req_headers: dict = None,
|
|
71
72
|
):
|
|
72
73
|
"""
|
|
73
74
|
Initialise the SCANOSS API
|
|
@@ -86,17 +87,17 @@ class ScanossApi(ScanossBase):
|
|
|
86
87
|
HTTPS_PROXY='http://<ip>:<port>'
|
|
87
88
|
"""
|
|
88
89
|
super().__init__(debug, trace, quiet)
|
|
89
|
-
self.url = url
|
|
90
|
-
self.api_key = api_key
|
|
91
|
-
if self.api_key and not url and not os.environ.get('SCANOSS_SCAN_URL'):
|
|
92
|
-
self.url = DEFAULT_URL2 # API key specific and no alternative URL, so use the default premium
|
|
90
|
+
self.url = url
|
|
91
|
+
self.api_key = api_key
|
|
93
92
|
self.sbom = None
|
|
94
93
|
self.scan_format = scan_format if scan_format else 'plain'
|
|
95
94
|
self.flags = flags
|
|
96
95
|
self.timeout = timeout if timeout > 5 else 180
|
|
97
96
|
self.retry_limit = retry if retry >= 0 else 5
|
|
98
97
|
self.ignore_cert_errors = ignore_cert_errors
|
|
98
|
+
self.req_headers = req_headers if req_headers else {}
|
|
99
99
|
self.headers = {}
|
|
100
|
+
|
|
100
101
|
if ver_details:
|
|
101
102
|
self.headers['x-scanoss-client'] = ver_details
|
|
102
103
|
if self.api_key:
|
|
@@ -104,17 +105,24 @@ class ScanossApi(ScanossBase):
|
|
|
104
105
|
self.headers['x-api-key'] = self.api_key
|
|
105
106
|
self.headers['User-Agent'] = f'scanoss-py/{__version__}'
|
|
106
107
|
self.headers['user-agent'] = f'scanoss-py/{__version__}'
|
|
108
|
+
self.load_generic_headers()
|
|
109
|
+
|
|
110
|
+
self.url = url if url else SCANOSS_SCAN_URL
|
|
111
|
+
self.api_key = api_key if api_key else SCANOSS_API_KEY
|
|
112
|
+
if self.api_key and not url and not os.environ.get('SCANOSS_SCAN_URL'):
|
|
113
|
+
self.url = DEFAULT_URL2 # API key specific and no alternative URL, so use the default premium
|
|
114
|
+
|
|
107
115
|
if self.trace:
|
|
108
116
|
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
|
|
109
117
|
http_client.HTTPConnection.debuglevel = 1
|
|
110
118
|
if pac and not proxy: # Setup PAC session if requested (and no proxy has been explicitly set)
|
|
111
|
-
self.print_debug(
|
|
119
|
+
self.print_debug('Setting up PAC session...')
|
|
112
120
|
self.session = PACSession(pac=pac)
|
|
113
121
|
else:
|
|
114
122
|
self.session = requests.sessions.Session()
|
|
115
123
|
self.verify = None
|
|
116
124
|
if self.ignore_cert_errors:
|
|
117
|
-
self.print_debug(
|
|
125
|
+
self.print_debug('Ignoring cert errors...')
|
|
118
126
|
urllib3.disable_warnings(InsecureRequestWarning)
|
|
119
127
|
self.verify = False
|
|
120
128
|
self.session.verify = False
|
|
@@ -261,6 +269,20 @@ class ScanossApi(ScanossBase):
|
|
|
261
269
|
self.sbom = sbom
|
|
262
270
|
return self
|
|
263
271
|
|
|
272
|
+
def load_generic_headers(self):
|
|
273
|
+
"""
|
|
274
|
+
Adds custom headers from req_headers to the headers collection.
|
|
275
|
+
|
|
276
|
+
If x-api-key is present and no URL is configured (directly or via
|
|
277
|
+
environment), sets URL to the premium endpoint (DEFAULT_URL2).
|
|
278
|
+
"""
|
|
279
|
+
if self.req_headers: # Load generic headers
|
|
280
|
+
for key, value in self.req_headers.items():
|
|
281
|
+
if key == 'x-api-key': # Set premium URL if x-api-key header is set
|
|
282
|
+
if not self.url and not os.environ.get('SCANOSS_SCAN_URL'):
|
|
283
|
+
self.url = DEFAULT_URL2 # API key specific and no alternative URL, so use the default premium
|
|
284
|
+
self.api_key = value
|
|
285
|
+
self.headers[key] = value
|
|
264
286
|
|
|
265
287
|
#
|
|
266
288
|
# End of ScanossApi Class
|