mirror of
https://gitlab.com/buildroot.org/buildroot.git
synced 2026-08-01 21:23:51 -09:00
utils/generate-cyclonedx: generate externalReferences with source-distribution
BSI TR-03183-2 5.4.2 [1] lists source code URIs under "Additional data fields for each component", and as such "MUST additionally be provided, if it exists". If a http or https source download URI is available from show-info, extract it and include it as an externalReference of type "source-distribution" in the CycloneDX output. [1] https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03183/BSI-TR-03183-2_v2_1_0.pdf?__blob=publicationFile&v=5 Signed-off-by: Martin Willi <martin@strongswan.org> Acked-by: Thomas Perale <thomas.perale@mind.be> Signed-off-by: Arnout Vandecappelle <arnout@rnout.be>
This commit is contained in:
committed by
Arnout Vandecappelle
parent
cc41cc3fcd
commit
e4f0fb126d
@@ -140,3 +140,29 @@ class TestGenerateCycloneDX(unittest.TestCase):
|
|||||||
|
|
||||||
foo_deps = next(d for d in result["dependencies"] if d["ref"] == "package-foo")
|
foo_deps = next(d for d in result["dependencies"] if d["ref"] == "package-foo")
|
||||||
self.assertEqual(foo_deps["dependsOn"], ["package-bar", "skeleton-baz"])
|
self.assertEqual(foo_deps["dependsOn"], ["package-bar", "skeleton-baz"])
|
||||||
|
|
||||||
|
def test_external_references(self):
|
||||||
|
info = self._make_show_info()
|
||||||
|
info["package-foo"]["downloads"] = [
|
||||||
|
{
|
||||||
|
"source": "foo-1.2.tar.gz",
|
||||||
|
"uris": [
|
||||||
|
"https+https://sources.buildroot.net/foo",
|
||||||
|
"http|https+https://mirror.example.org/foo",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
result = self._run_script(show_info=info)
|
||||||
|
foo = self._find_component(result, "package-foo")
|
||||||
|
|
||||||
|
self.assertIn("externalReferences", foo)
|
||||||
|
self.assertEqual(
|
||||||
|
foo["externalReferences"],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "source-distribution",
|
||||||
|
"url": "https://mirror.example.org/foo/foo-1.2.tar.gz",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import gzip
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from typing import Iterator
|
||||||
|
import urllib.parse
|
||||||
import urllib.request
|
import urllib.request
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
@@ -261,6 +263,50 @@ def cyclonedx_patches(patch_list: list[str]):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def parse_uris(uris: list[str]) -> Iterator[tuple[list[str], str]]:
|
||||||
|
"""Parse download URIs into (schemes, url) tuples.
|
||||||
|
|
||||||
|
Splits the Buildroot URI format "scheme[|scheme]+url" and yields all
|
||||||
|
Buildroot schemes with the stripped URL, excluding
|
||||||
|
sources.buildroot.net mirrors.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
uris (list): Array of URI strings from the show-info output.
|
||||||
|
Yields:
|
||||||
|
tuple[list[str], str]: (schemes, url) for each usable URI.
|
||||||
|
"""
|
||||||
|
for uri in uris:
|
||||||
|
scheme, _, stripped_uri = uri.partition("+")
|
||||||
|
if stripped_uri:
|
||||||
|
parsed = urllib.parse.urlparse(stripped_uri)
|
||||||
|
if parsed.hostname != "sources.buildroot.net":
|
||||||
|
yield scheme.split("|"), stripped_uri
|
||||||
|
|
||||||
|
|
||||||
|
def cyclonedx_external_refs(comp):
|
||||||
|
"""Create CycloneDX external references for a component.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
comp (dict): The component information from the show-info output.
|
||||||
|
Returns:
|
||||||
|
dict: External reference information in CycloneDX format, or empty dict
|
||||||
|
"""
|
||||||
|
SOURCE_DIST_SCHEMES = {"http", "https"}
|
||||||
|
|
||||||
|
refs = []
|
||||||
|
for download in comp.get("downloads", []):
|
||||||
|
source = download.get("source")
|
||||||
|
for schemes, uri in parse_uris(download.get("uris", [])):
|
||||||
|
if set(schemes) & SOURCE_DIST_SCHEMES and source:
|
||||||
|
refs.append({
|
||||||
|
"type": "source-distribution",
|
||||||
|
"url": f"{uri}/{source}",
|
||||||
|
})
|
||||||
|
if refs:
|
||||||
|
return {"externalReferences": refs}
|
||||||
|
return {}
|
||||||
|
|
||||||
|
|
||||||
def cyclonedx_component(name, comp):
|
def cyclonedx_component(name, comp):
|
||||||
"""Translate a component from the show-info output, to a component entry in CycloneDX format.
|
"""Translate a component from the show-info output, to a component entry in CycloneDX format.
|
||||||
|
|
||||||
@@ -284,6 +330,7 @@ def cyclonedx_component(name, comp):
|
|||||||
**({
|
**({
|
||||||
"cpe": comp["cpe-id"],
|
"cpe": comp["cpe-id"],
|
||||||
} if "cpe-id" in comp else {}),
|
} if "cpe-id" in comp else {}),
|
||||||
|
**cyclonedx_external_refs(comp),
|
||||||
**(cyclonedx_patches(comp["patches"]) if comp.get("patches") else {}),
|
**(cyclonedx_patches(comp["patches"]) if comp.get("patches") else {}),
|
||||||
"properties": [{
|
"properties": [{
|
||||||
"name": "BR_TYPE",
|
"name": "BR_TYPE",
|
||||||
|
|||||||
Reference in New Issue
Block a user