fosslight-source 2.3.9__tar.gz → 2.3.10__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.
Files changed (33) hide show
  1. {fosslight_source-2.3.9/src/fosslight_source.egg-info → fosslight_source-2.3.10}/PKG-INFO +2 -1
  2. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/pyproject.toml +2 -1
  3. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/_help.py +2 -0
  4. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/_kb_client.py +28 -1
  5. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/cli.py +2 -2
  6. {fosslight_source-2.3.9 → fosslight_source-2.3.10/src/fosslight_source.egg-info}/PKG-INFO +2 -1
  7. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source.egg-info/SOURCES.txt +1 -0
  8. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source.egg-info/requires.txt +1 -0
  9. fosslight_source-2.3.10/tests/test_kb_ssl.py +52 -0
  10. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/LICENSE +0 -0
  11. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/MANIFEST.in +0 -0
  12. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/README.md +0 -0
  13. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/setup.cfg +0 -0
  14. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/__init__.py +0 -0
  15. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/_license_matched.py +0 -0
  16. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/_merge.py +0 -0
  17. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/_parsing_scancode_file_item.py +0 -0
  18. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/_parsing_scanoss_file.py +0 -0
  19. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/_scan_item.py +0 -0
  20. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/_scancode_ignore_binaries.py +0 -0
  21. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/run_manifest_extractor.py +0 -0
  22. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/run_scancode.py +0 -0
  23. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/run_scanoss.py +0 -0
  24. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source/run_spdx_extractor.py +0 -0
  25. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source.egg-info/dependency_links.txt +0 -0
  26. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source.egg-info/entry_points.txt +0 -0
  27. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/src/fosslight_source.egg-info/top_level.txt +0 -0
  28. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/tests/test_manifest_android_bp.py +0 -0
  29. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/tests/test_manifest_composer.py +0 -0
  30. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/tests/test_manifest_pyproject.py +0 -0
  31. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/tests/test_manifest_recommended_scenarios.py +0 -0
  32. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/tests/test_parsing_unknown_spdx.py +0 -0
  33. {fosslight_source-2.3.9 → fosslight_source-2.3.10}/tests/test_tox.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fosslight_source
3
- Version: 2.3.9
3
+ Version: 2.3.10
4
4
  Summary: FOSSLight Source Scanner
5
5
  Author: LG Electronics
6
6
  License-Expression: Apache-2.0
@@ -32,6 +32,7 @@ Requires-Dist: normality==2.6.1
32
32
  Requires-Dist: psycopg2-binary>=2.9.10; python_version >= "3.13"
33
33
  Requires-Dist: tomli; python_version < "3.11"
34
34
  Requires-Dist: tqdm
35
+ Requires-Dist: truststore
35
36
  Dynamic: license-file
36
37
 
37
38
  <!--
@@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta"
7
7
 
8
8
  [project]
9
9
  name = "fosslight_source"
10
- version = "2.3.9"
10
+ version = "2.3.10"
11
11
  description = "FOSSLight Source Scanner"
12
12
  readme = "README.md"
13
13
  license = "Apache-2.0"
@@ -43,6 +43,7 @@ dependencies = [
43
43
  "psycopg2-binary>=2.9.10; python_version >= '3.13'",
44
44
  "tomli; python_version < '3.11'",
45
45
  "tqdm",
46
+ "truststore",
46
47
  ]
47
48
 
48
49
  [project.optional-dependencies]
@@ -45,6 +45,8 @@ _HELP_MESSAGE_SOURCE_SCANNER = f"""
45
45
  --hide_progress Hide the progress bar during scanning
46
46
  --kb_url <url> KB API URL (priority: parameter > KB_URL env > default)
47
47
  --kb_token <token> KB bearer token (priority: parameter > KB_TOKEN env)
48
+ HTTPS uses the OS certificate store. Set KB_SSL_VERIFY=false
49
+ only if certificate verification must be skipped.
48
50
 
49
51
  💡 Examples
50
52
  ────────────────────────────────────────────────────────────────────
@@ -5,6 +5,8 @@
5
5
 
6
6
  import json
7
7
  import logging
8
+ import os
9
+ import ssl
8
10
  import time
9
11
  import urllib.error
10
12
  import urllib.request
@@ -19,6 +21,31 @@ _SCAN_JOB_POLL_MAX_INTERVAL_SEC = 10.0
19
21
  _SCAN_JOB_REQUEST_TIMEOUT_SEC = 30
20
22
  _SCAN_JOB_MIN_WAIT_SEC = 300
21
23
  _SCAN_JOB_PER_HASH_SEC = 35
24
+ _KB_SSL_VERIFY_FALSE = {"0", "false", "no", "off"}
25
+ _logged_insecure_kb_ssl = False
26
+
27
+
28
+ def kb_ssl_verify_enabled() -> bool:
29
+ raw = os.environ.get("KB_SSL_VERIFY", "true")
30
+ return raw.strip().lower() not in _KB_SSL_VERIFY_FALSE
31
+
32
+
33
+ def create_kb_ssl_context() -> ssl.SSLContext:
34
+ """TLS context for KB HTTPS. Uses the OS trust store (Windows store, like the browser)."""
35
+ global _logged_insecure_kb_ssl
36
+ if not kb_ssl_verify_enabled():
37
+ if not _logged_insecure_kb_ssl:
38
+ logger.warning("KB TLS certificate verification is disabled (KB_SSL_VERIFY)")
39
+ _logged_insecure_kb_ssl = True
40
+ ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
41
+ ctx.check_hostname = False
42
+ ctx.verify_mode = ssl.CERT_NONE
43
+ return ctx
44
+ try:
45
+ import truststore
46
+ return truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
47
+ except ImportError:
48
+ return ssl.create_default_context()
22
49
 
23
50
 
24
51
  def _kb_request(
@@ -40,7 +67,7 @@ def _kb_request(
40
67
  if kb_token:
41
68
  request.add_header("Authorization", f"Bearer {kb_token}")
42
69
 
43
- with urllib.request.urlopen(request, timeout=timeout) as response:
70
+ with urllib.request.urlopen(request, timeout=timeout, context=create_kb_ssl_context()) as response:
44
71
  body = response.read().decode()
45
72
  return json.loads(body) if body else {}
46
73
 
@@ -30,7 +30,7 @@ import argparse
30
30
  from .run_spdx_extractor import get_spdx_downloads
31
31
  from .run_manifest_extractor import get_manifest_licenses
32
32
  from ._scan_item import SourceItem, resolve_kb_config, is_notice_file, is_manifest_file
33
- from ._kb_client import fetch_origin_urls_via_scan_job
33
+ from ._kb_client import create_kb_ssl_context, fetch_origin_urls_via_scan_job
34
34
  from fosslight_util.cover import dump_result_log
35
35
  from fosslight_util.time import current_timestamp_utc, format_running_time, timestamp_for_filename
36
36
  from fosslight_util.oss_item import ScannerItem
@@ -295,7 +295,7 @@ def check_kb_server_reachable(kb_url: str, kb_token: str = "") -> bool:
295
295
  request = urllib.request.Request(f"{kb_url}health", method='GET')
296
296
  if kb_token:
297
297
  request.add_header('Authorization', f'Bearer {kb_token}')
298
- with urllib.request.urlopen(request, timeout=10) as response:
298
+ with urllib.request.urlopen(request, timeout=10, context=create_kb_ssl_context()) as response:
299
299
  logger.debug(f"KB server is reachable. Response status: {response.status}")
300
300
  return True
301
301
  except urllib.error.HTTPError:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fosslight_source
3
- Version: 2.3.9
3
+ Version: 2.3.10
4
4
  Summary: FOSSLight Source Scanner
5
5
  Author: LG Electronics
6
6
  License-Expression: Apache-2.0
@@ -32,6 +32,7 @@ Requires-Dist: normality==2.6.1
32
32
  Requires-Dist: psycopg2-binary>=2.9.10; python_version >= "3.13"
33
33
  Requires-Dist: tomli; python_version < "3.11"
34
34
  Requires-Dist: tqdm
35
+ Requires-Dist: truststore
35
36
  Dynamic: license-file
36
37
 
37
38
  <!--
@@ -22,6 +22,7 @@ src/fosslight_source.egg-info/dependency_links.txt
22
22
  src/fosslight_source.egg-info/entry_points.txt
23
23
  src/fosslight_source.egg-info/requires.txt
24
24
  src/fosslight_source.egg-info/top_level.txt
25
+ tests/test_kb_ssl.py
25
26
  tests/test_manifest_android_bp.py
26
27
  tests/test_manifest_composer.py
27
28
  tests/test_manifest_pyproject.py
@@ -11,6 +11,7 @@ lxml>=6.0.1
11
11
  fingerprints==1.2.3
12
12
  normality==2.6.1
13
13
  tqdm
14
+ truststore
14
15
 
15
16
  [:platform_system == "Darwin" and platform_machine == "x86_64"]
16
17
  cryptography<49
@@ -0,0 +1,52 @@
1
+ # Copyright (c) 2026 LG Electronics Inc.
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ """Tests for KB HTTPS SSL context selection."""
4
+
5
+ import ssl
6
+ from unittest.mock import patch
7
+
8
+ from fosslight_source._kb_client import create_kb_ssl_context, kb_ssl_verify_enabled
9
+
10
+
11
+ def test_kb_ssl_verify_enabled_default(monkeypatch):
12
+ monkeypatch.delenv("KB_SSL_VERIFY", raising=False)
13
+ assert kb_ssl_verify_enabled() is True
14
+
15
+
16
+ def test_kb_ssl_verify_disabled_values(monkeypatch):
17
+ for value in ("false", "0", "no", "OFF"):
18
+ monkeypatch.setenv("KB_SSL_VERIFY", value)
19
+ assert kb_ssl_verify_enabled() is False
20
+
21
+
22
+ def test_create_kb_ssl_context_insecure(monkeypatch):
23
+ monkeypatch.setenv("KB_SSL_VERIFY", "false")
24
+ ctx = create_kb_ssl_context()
25
+ assert ctx.verify_mode == ssl.CERT_NONE
26
+ assert ctx.check_hostname is False
27
+
28
+
29
+ def test_create_kb_ssl_context_uses_truststore_when_verify_on(monkeypatch):
30
+ monkeypatch.setenv("KB_SSL_VERIFY", "true")
31
+ ctx = create_kb_ssl_context()
32
+ assert ctx.verify_mode != ssl.CERT_NONE
33
+ assert ctx.check_hostname is True
34
+
35
+
36
+ def test_kb_request_passes_ssl_context():
37
+ from fosslight_source._kb_client import _kb_request
38
+
39
+ class _Resp:
40
+ def read(self):
41
+ return b"{}"
42
+
43
+ def __enter__(self):
44
+ return self
45
+
46
+ def __exit__(self, *args):
47
+ return False
48
+
49
+ with patch("fosslight_source._kb_client.urllib.request.urlopen", return_value=_Resp()) as urlopen:
50
+ _kb_request("https://kb.example/", "health")
51
+ assert urlopen.call_args.kwargs["context"] is not None
52
+ assert isinstance(urlopen.call_args.kwargs["context"], ssl.SSLContext)