SERVER-107852 SBOM rebuild to v8.0 (#39741)

GitOrigin-RevId: 24345414680712d91e0b500ded6ea8d2517804fa
This commit is contained in:
Jason Hills 2025-09-08 09:56:45 -04:00 committed by MongoDB Bot
parent 5e331a74af
commit d50b0cce55
35 changed files with 2841 additions and 648 deletions

View File

@ -11,6 +11,8 @@
!*.md !*.md
# TODO SERVER-106654 # TODO SERVER-106654
docs/logging.md docs/logging.md
# this file is automatically generated and conforms to formatting requirements
README.third_party.md
# Ignore all golden test output files # Ignore all golden test output files
jstests/*golden*/expected_output/* jstests/*golden*/expected_output/*

View File

@ -1,3 +1,5 @@
[DO NOT MODIFY THIS FILE MANUALLY. It is generated by src/third_party/tools/gen_thirdpartyreadme.py]: #
# MongoDB Third Party Dependencies # MongoDB Third Party Dependencies
MongoDB depends on third party libraries to implement some MongoDB depends on third party libraries to implement some
@ -19,113 +21,127 @@ not authored by MongoDB, and has a license which requires reproduction,
a notice will be included in a notice will be included in
`THIRD-PARTY-NOTICES`. `THIRD-PARTY-NOTICES`.
| Name | License | Vendored Version | Emits persisted data | Distributed in Release Binaries | | Name | License | Vendored Version | Emits persisted data | Distributed in Release Binaries |
| -------------------------- | -------------------------------------------------------------- | -------------------------------------------------- | :------------------: | :-----------------------------: | | ---------------------------------------------------- | --------------------------------- | ---------------------------------------- | -------------------- | ------------------------------- |
| [abseil-cpp] | Apache-2.0 | 20230802.1 | | ✗ | | [Abseil Common Libraries (C++)] | Apache-2.0 | 20230802.1 | | ✗ |
| [Aladdin MD5] | Zlib | Unknown | ✗ | ✗ | | [Asio C++ Library] | BSL-1.0 | 1.12.2 | | ✗ |
| [ASIO] | BSL-1.0 | 1.12.2 | | ✗ | | [benchmark] | Apache-2.0 | v1.5.2 | | |
| [benchmark] | Apache-2.0 | 1.5.2 | | | | [Boost C++ Libraries] | BSL-1.0 | 1.79.0 | | ✗ |
| [Boost] | BSL-1.0 | 1.79.0 | | ✗ | | [c-ares] | MIT | 1.27.0 | | ✗ |
| [c-ares] | MIT | 1.27.0 | | ✗ | | [CRoaring] | Apache-2.0 OR MIT | 2.1.2 | | ✗ |
| [CRoaring] | Apache-2.0/ MIT | 2.1.2.1 | | ✗ | | [Cyrus SASL] | BSD-Attribution-HPND-disclaimer | 2.1.28 | | |
| [Cyrus SASL] | BSD-Attribution-HPND-disclaimer | 2.1.28 | unknown | | | [fmt] | MIT | 7.1.3 | | ✗ |
| [double-conversion] | BSD 3-Clause | bf4607277fa7133825cb7899015374917cd06b8f | | ✗ | | [folly] | Apache-2.0 | v2025.04.21.00 | | ✗ |
| [fmt] | BSD-2-Clause | 7.1.3 | | ✗ | | [gperftools] | BSD-3-Clause | 2.9.1 | | ✗ |
| [GPerfTools] | BSD-3-Clause | 2.9.1 | | ✗ | | [gRPC (C++)] | Apache-2.0 | 1.59.5 | | ✗ |
| [gRPC] | Apache-2.0 | 1.59.2 | | ✗ | | [immer] | BSL-1.0 | 0.8.0 | | ✗ |
| [ICU4] | ICU | 57.1 | ✗ | ✗ | | [Intel® Decimal Floating-Point Math Library] | BSD-3-Clause | v2.0U1 | | ✗ |
| [immer] | BSL-1.0 | d98a68c + changes | | ✗ | | [International Components for Unicode C/C++ (ICU4C)] | Unicode-3.0 | 57.1 | ✗ | ✗ |
| [Intel Decimal FP Library] | BSD-3-Clause | 2.0 Update 1 | | ✗ | | [JSON Schema Store] | Apache-2.0 | 6847cfc3a17a04a7664474212db50c627e1e3408 | | |
| [JSON-Schema-Test-Suite] | MIT | 728066f9c5 | | | | [JSON-Schema-Test-Suite] | MIT | 728066f9c5c258ba3b1804a22a5b998f2ec77ec0 | | |
| [libstemmer] | BSD-3-Clause | Unknown | ✗ | ✗ | | [libmongocrypt] | Apache-2.0 | 1.8.4 | ✗ | ✗ |
| [librdkafka] | BSD-2-Clause | 2.0.2 | | | | [librdkafka - The Apache Kafka C/C++ library] | BSD-2-Clause | 2.0.2 | | ✗ |
| [libmongocrypt] | Apache-2.0 | 1.8.4 | ✗ | ✗ | | [LibTomCrypt] | Unlicense | 1.18.2 | ✗ | ✗ |
| [linenoise] | BSD-3-Clause | 6cdc775 + changes | | ✗ | | [libunwind] | MIT | v1.8.1 | | ✗ |
| [mongo-c-driver] | Apache-2.0 | 1.27.6 | ✗ | ✗ | | [linenoise] | BSD-2-Clause | 6cdc775807e57b2c3fd64bd207814f8ee1fe35f3 | | ✗ |
| [Mozilla Firefox] | MPL-2.0 | 128.11.0esr | unknown | ✗ | | [MongoDB C Driver] | Apache-2.0 | 1.27.6 | ✗ | ✗ |
| [MurmurHash3] | Public Domain | a6bd3ce + changes | ✗ | ✗ | | [Mozilla Firefox ESR] | MPL-2.0 | 128.11.0esr | | ✗ |
| [ocspbuilder] | MIT | 0.10.2 | | | | [MurmurHash3] | Public Domain | a6bd3ce7be8ad147ea820a7cf6229a975c0c96bb | | ✗ |
| [ocspresponder] | Apache-2.0 | 0.5.0 | | | | [nlohmann/json] | MIT | 3.10.5 | | |
| [pcre2] | BSD-3-Clause | 10.40 | | ✗ | | [PCRE2 - Perl-Compatible Regular Expressions] | BSD-3-Clause WITH PCRE2-exception | 10.40 | | ✗ |
| [protobuf] | BSD-3-Clause | 4.25.0 | | ✗ | | [Protobuf] | BSD-3-Clause | v4.25.0 | | ✗ |
| [re2] | BSD-3-Clause | 2021-09-01 | | ✗ | | [pypi/asn1crypto] | MIT | 1.5.1 | | |
| [S2] | Apache-2.0 | c872048da5d1 + changes | ✗ | ✗ | | [pypi/concurrencytest] | GPL-3.0-or-later | 0.1.2 | | |
| [SafeInt] | MIT | 3.0.26 | | | | [pypi/discover] | BSD-3-Clause | 0.4.0 | | |
| [schemastore.org] | Apache-2.0 | 6847cfc3a1 | | | | [pypi/extras] | MIT | 0.0.3 | | |
| [scons] | MIT | 4.9.1 | | | | [pypi/ocspbuilder] | MIT | 0.10.2 | | |
| [Snappy] | BSD-3-Clause | 1.1.10 | ✗ | ✗ | | [pypi/ocspresponder] | Apache-2.0 | 0.5.0 | | |
| [TCMalloc] | Apache-2.0 | 093ba93 + changes | | ✗ | | [pypi/oscrypto] | MIT | 1.3.0 | | |
| [timelib] | MIT | 2022.10 | | ✗ | | [pypi/python-subunit] | (Apache-2.0 OR BSD-3-Clause) | 0.0.16 | | |
| [TomCrypt] | Public Domain | 1.18.2 | ✗ | ✗ | | [pypi/testscenarios] | BSD-3-Clause | 0.4 | | |
| [Unicode] | Unicode-DFS-2015 | 8.0.0 | ✗ | ✗ | | [pypi/testtools] | MIT | 0.9.34 | | |
| [libunwind/libunwind] | MIT | v1.8.1 | | ✗ | | [re2] | BSD-3-Clause | 2023-11-01 | | ✗ |
| [lz4] | BSD-2-Clause | 1.9.3 | | ✗ | | [S2 Geometry Library] | Apache-2.0 | c872048da5d1 | ✗ | ✗ |
| [Valgrind] | BSD-4-Clause<sup>\[<a href="#note_vg" id="ref_vg">1</a>]</sup> | 3.17.0 | | ✗ | | [SafeInt] | MIT | 3.0.26 | | ✗ |
| [wiredtiger] | | <sup>\[<a href="#note_wt" id="ref_wt">2</a>]</sup> | ✗ | ✗ | | [SCons - a Software Construction tool] | MIT | 4.9.1 | | |
| [xxHash] | BSD-2-Clause | 0.8.0 | | ✗ | | [snappy] | BSD-3-Clause | 1.1.10 | ✗ | ✗ |
| [yaml-cpp] | MIT | 0.6.3 | | ✗ | | [Snowball Stemming Algorithms (libstemmer)] | BSD-3-Clause | 7b264ffa0f767c579d052fd8142558dc8264d795 | ✗ | ✗ |
| [Zlib] | Zlib | 1.3 | ✗ | ✗ | | [tcmalloc] | Apache-2.0 | 093ba93c1bd6dca03b0a8334f06d01b019244291 | | ✗ |
| [Zstandard] | BSD-3-Clause | 1.5.5 | ✗ | ✗ | | [timelib] | MIT | 2022.10 | | ✗ |
| [zydis] | MIT | 4d4fe4c293c5438f32688b14b29017ae3f48369e | | ✗ | | [Unicode Character Database] | Unicode-DFS-2016 | 8.0.0 | ✗ | ✗ |
| [valgrind.h] | BSD-4-Clause | 3.17.0 | | ✗ |
| [WiredTiger] | GPL-2.0-only OR GPL-3.0-only | mongodb-8.0.12 | ✗ | ✗ |
| [yaml-cpp] | MIT | 0.6.3 | | ✗ |
| [zlib] | Zlib | 1.3.1 | ✗ | ✗ |
| [Zstandard (zstd)] | BSD-3-Clause OR GPL-2.0-only | 1.5.5 | ✗ | ✗ |
[abseil-cpp]: https://github.com/abseil/abseil-cpp [Abseil Common Libraries (C++)]: https://github.com/abseil/abseil-cpp
[ASIO]: https://github.com/chriskohlhoff/asio [Asio C++ Library]: https://github.com/chriskohlhoff/asio
[benchmark]: https://github.com/google/benchmark [Boost C++ Libraries]: http://www.boost.org/
[Boost]: http://www.boost.org/
[CRoaring]: https://github.com/RoaringBitmap/CRoaring [CRoaring]: https://github.com/RoaringBitmap/CRoaring
[Cyrus SASL]: https://www.cyrusimap.org/sasl/ [Cyrus SASL]: https://www.cyrusimap.org/sasl/
[double-conversion]: https://github.com/google/double-conversion "transitive dependency of MozJS" [Intel® Decimal Floating-Point Math Library]: https://software.intel.com/en-us/articles/intel-decimal-floating-point-math-library
[fmt]: http://fmtlib.net/ [International Components for Unicode C/C++ (ICU4C)]: http://site.icu-project.org/download/
[GPerfTools]: https://github.com/gperftools/gperftools [JSON Schema Store]: https://www.schemastore.org/json/
[gRPC]: https://github.com/grpc/grpc
[ICU4]: http://site.icu-project.org/download/
[immer]: https://github.com/arximboldi/immer
[Intel Decimal FP Library]: https://software.intel.com/en-us/articles/intel-decimal-floating-point-math-library
[JSON-Schema-Test-Suite]: https://github.com/json-schema-org/JSON-Schema-Test-Suite [JSON-Schema-Test-Suite]: https://github.com/json-schema-org/JSON-Schema-Test-Suite
[libstemmer]: https://github.com/snowballstem/snowball [LibTomCrypt]: https://github.com/libtom/libtomcrypt/releases
[librdkafka]: https://github.com/confluentinc/librdkafka [MongoDB C Driver]: https://github.com/mongodb/mongo-c-driver
[libmongocrypt]: https://github.com/mongodb/libmongocrypt [Mozilla Firefox ESR]: https://www.mozilla.org/en-US/security/known-vulnerabilities/firefox-esr
[linenoise]: https://github.com/antirez/linenoise
[lz4]: https://github.com/lz4/lz4
[mongo-c-driver]: https://github.com/mongodb/mongo-c-driver
[Mozilla Firefox]: https://www.mozilla.org/en-US/security/known-vulnerabilities/firefox-esr
[MurmurHash3]: https://github.com/aappleby/smhasher/blob/a6bd3ce/ [MurmurHash3]: https://github.com/aappleby/smhasher/blob/a6bd3ce/
[ocspbuilder]: https://github.com/wbond/ocspbuilder [PCRE2 - Perl-Compatible Regular Expressions]: http://www.pcre.org/
[ocspresponder]: https://github.com/threema-ch/ocspresponder [Protobuf]: https://github.com/protocolbuffers/protobuf
[pcre2]: http://www.pcre.org/ [S2 Geometry Library]: https://github.com/google/s2geometry
[protobuf]: https://github.com/protocolbuffers/protobuf [SCons - a Software Construction tool]: https://github.com/SCons/scons
[S2]: https://github.com/google/s2geometry
[SafeInt]: https://github.com/dcleblanc/SafeInt [SafeInt]: https://github.com/dcleblanc/SafeInt
[schemastore.org]: https://www.schemastore.org/json/ [Snowball Stemming Algorithms (libstemmer)]: https://github.com/snowballstem/snowball
[scons]: https://github.com/SCons/scons [Unicode Character Database]: http://www.unicode.org/versions/enumeratedversions.html
[Snappy]: https://github.com/google/snappy/releases [WiredTiger]: https://source.wiredtiger.com/
[TCMalloc]: https://github.com/google/tcmalloc [Zstandard (zstd)]: https://github.com/facebook/zstd
[benchmark]: https://github.com/google/benchmark
[c-ares]: https://c-ares.org/
[fmt]: http://fmtlib.net/
[folly]: https://github.com/facebook/folly
[gRPC (C++)]: https://github.com/grpc/grpc
[gperftools]: https://github.com/gperftools/gperftools
[immer]: https://github.com/arximboldi/immer
[libmongocrypt]: https://github.com/mongodb/libmongocrypt
[librdkafka - The Apache Kafka C/C++ library]: https://github.com/confluentinc/librdkafka
[libunwind]: http://www.github.com/libunwind/libunwind
[linenoise]: https://github.com/antirez/linenoise
[nlohmann/json]: https://github.com/nlohmann/json
[pypi/asn1crypto]: https://github.com/wbond/asn1crypto
[pypi/concurrencytest]: https://pypi.org/project/concurrencytest/
[pypi/discover]: https://pypi.org/project/discover/
[pypi/extras]: https://github.com/testing-cabal/extras
[pypi/ocspbuilder]: https://github.com/wbond/ocspbuilder
[pypi/ocspresponder]: https://github.com/threema-ch/ocspresponder
[pypi/oscrypto]: https://github.com/wbond/oscrypto
[pypi/python-subunit]: https://github.com/testing-cabal/subunit
[pypi/testscenarios]: https://pypi.org/project/testscenarios/
[pypi/testtools]: https://github.com/testing-cabal/testtools
[re2]: https://github.com/google/re2
[snappy]: https://github.com/google/snappy/releases
[tcmalloc]: https://github.com/google/tcmalloc
[timelib]: https://github.com/derickr/timelib [timelib]: https://github.com/derickr/timelib
[TomCrypt]: https://github.com/libtom/libtomcrypt/releases [valgrind.h]: http://valgrind.org/downloads/current.html
[Unicode]: http://www.unicode.org/versions/enumeratedversions.html
[libunwind]: http://www.nongnu.org/libunwind/
[Valgrind]: http://valgrind.org/downloads/current.html
[wiredtiger]: https://github.com/wiredtiger/wiredtiger
[xxHash]: https://github.com/Cyan4973/xxHash
[yaml-cpp]: https://github.com/jbeder/yaml-cpp/releases [yaml-cpp]: https://github.com/jbeder/yaml-cpp/releases
[Zlib]: https://zlib.net/ [zlib]: https://zlib.net/
[Zstandard]: https://github.com/facebook/zstd
[zydis]: https://github.com/zyantific/zydis
## WiredTiger Vendored Test Libraries ## WiredTiger Vendored Test Libraries
The following Python libraries are transitively included by WiredTiger, The following libraries are transitively included by WiredTiger,
and are used by that component for testing. They don't appear in and are used by that component for testing. They don't appear in
released binary artifacts. released binary artifacts.
| Name | | Name |
| :-------------- | | -------------------------- |
| concurrencytest | | nlohmann/json@3.10.5 |
| discover | | pypi/concurrencytest@0.1.2 |
| extras | | pypi/discover@0.4.0 |
| python-subunit | | pypi/extras@0.0.3 |
| testscenarios | | pypi/python-subunit@0.0.16 |
| testtools | | pypi/testscenarios@0.4 |
| pypi/testtools@0.9.34 |
## Dynamically Linked Libraries ## Dynamically Linked Libraries

View File

@ -177,6 +177,10 @@ py_binary(
"jsonschema", "jsonschema",
group = "build-metrics", group = "build-metrics",
), ),
dependency(
"license-expression",
group = "lint",
),
], ],
) )

View File

@ -2,8 +2,10 @@ import argparse
import json import json
import os import os
import sys import sys
from typing import List
import jsonschema import jsonschema
from license_expression import get_spdx_licensing
from referencing import Registry, Resource from referencing import Registry, Resource
BOM_SCHEMA_LOCATION = os.path.join("buildscripts", "tests", "sbom_linter", "bom-1.5.schema.json") BOM_SCHEMA_LOCATION = os.path.join("buildscripts", "tests", "sbom_linter", "bom-1.5.schema.json")
@ -21,14 +23,56 @@ SKIP_FILE_CHECKING = False
# Error messages used for matching in testing # Error messages used for matching in testing
UNDEFINED_THIRD_PARTY_ERROR = ( UNDEFINED_THIRD_PARTY_ERROR = (
"The following files in src/third_party do not have components defined in the sbom:") "The following files in src/third_party do not have components defined in the sbom:")
FORMATTING_ERROR = "file has incorrect formatting, re-run `buildscripts/sbom_linter.py` with the `--format` option to fix this." FORMATTING_ERROR = "File has incorrect formatting, re-run `buildscripts/sbom_linter.py` with the `--format` option to fix this."
MISSING_PURL_CPE_ERROR = "component must include a 'purl' or 'cpe' field." MISSING_PURL_CPE_ERROR = "Component must include a 'purl' or 'cpe' field."
MISSING_EVIDENCE_ERROR = ( MISSING_EVIDENCE_ERROR = (
"component must include an 'evidence.occurrences' field when the scope is required.") "Component must include an 'evidence.occurrences' field when the scope is required.")
MISSING_TEAM_ERROR = "component must include a 'internal:team_responsible' property." MISSING_TEAM_ERROR = "Component must include a 'internal:team_responsible' property."
SCHEMA_MATCH_FAILURE = "File did not match the CycloneDX schema"
MISSING_VERSION_IN_SBOM_COMPONENT_ERROR = "Component must include a version."
MISSING_VERSION_IN_IMPORT_FILE_ERROR = "Missing version in the import file: "
MISSING_LICENSE_IN_SBOM_COMPONENT_ERROR = "Component must include a license."
COULD_NOT_FIND_OR_READ_SCRIPT_FILE_ERROR = "Could not find or read the import script file"
VERSION_MISMATCH_ERROR = "Version mismatch: "
def get_schema(): # A class for managing error messages for components
class ErrorManager:
def __init__(self, input_file: str):
self.input_file: str = input_file
self.component_name: str = ""
self.errors: List[str] = []
def update_component_attribute(self, component_name: str) -> None:
self.component_name = component_name
def append(self, message: str) -> None:
self.errors.append(message)
def append_full_error_message(self, message: str) -> None:
if self.component_name == "":
self.errors.append(f"Input-file:{self.input_file} Error: {message}")
else:
self.errors.append(
f"Input-file:{self.input_file} Component:{self.component_name} Error: {message}")
def print_errors(self) -> None:
if self.errors:
print("\n".join(self.errors), file=sys.stderr)
def zero_error(self) -> bool:
return bool(not self.errors)
def find_message_in_errors(self, message: str) -> bool:
message_found = False
for error in self.errors:
if message in error:
message_found = True
break
return message_found
def get_schema() -> dict:
with open(BOM_SCHEMA_LOCATION, "r") as schema_data: with open(BOM_SCHEMA_LOCATION, "r") as schema_data:
return json.load(schema_data) return json.load(schema_data)
@ -41,86 +85,202 @@ def local_schema_registry():
return Registry().with_resources([(SPDX_SCHEMA_REF, spdx_schema)]) return Registry().with_resources([(SPDX_SCHEMA_REF, spdx_schema)])
# The script_path is a file which may contain a line where two tokens script_version_key and
# the version string are separated by a separtor value of "=" and some optional spaces.
# There is an "end of line" delimiter at the end of the line which needs to be stripped.
def get_script_version(script_path: str, script_version_key: str,
error_manager: ErrorManager) -> str:
result = ""
try:
file = open(script_path, "r")
except OSError:
error_manager.append_full_error_message(COULD_NOT_FIND_OR_READ_SCRIPT_FILE_ERROR)
return result
with file:
for line in file:
# Remove possible spaces, string delimiters and an "end of line" delimiter.
tokens = line.rstrip().replace('"', "").replace(" ", "").split("=")
if (len(tokens) > 1) and (tokens[0] == script_version_key):
result = tokens[1]
break
return result
# A version string sometimes contains an extra prefix like "v1.2" instead of "1.2"
# This function strips that extra prefix.
def strip_extra_prefixes(string_with_prefix: str) -> str:
def remove_prefix(text, prefix):
if text.startswith(prefix):
return text[len(prefix):]
return text
string_with_prefix = remove_prefix(string_with_prefix, "mongo/")
string_with_prefix = remove_prefix(string_with_prefix, "v")
return string_with_prefix
def validate_license(component: dict, error_manager: ErrorManager) -> None:
if "licenses" not in component:
error_manager.append_full_error_message(MISSING_LICENSE_IN_SBOM_COMPONENT_ERROR)
return
valid_license = False
for component_license in component["licenses"]:
if "expression" in component_license:
expression = component_license.get("expression")
elif "license" in component_license:
if "id" in component_license["license"]:
# Should be a valid SPDX license ID
expression = component_license["license"].get("id")
elif "name" in component_license["license"]:
# If SPDX does not define the license used, the name field may be used to provide the license name
valid_license = True
if not valid_license:
licensing_validate = get_spdx_licensing().validate(expression, validate=True)
# ExpressionInfo(
# original_expression='',
# normalized_expression='',
# errors=[],
# invalid_symbols=[]
#)
valid_license = not licensing_validate.errors or not licensing_validate.invalid_symbols
if not valid_license:
error_manager.append_full_error_message(licensing_validate)
return
def validate_evidence(component: dict, third_party_libs: set, error_manager: ErrorManager) -> None:
if component["scope"] == "required":
if "evidence" not in component or "occurrences" not in component["evidence"]:
error_manager.append_full_error_message(MISSING_EVIDENCE_ERROR)
return
validate_location(component, third_party_libs, error_manager)
def validate_properties(component: dict, error_manager: ErrorManager) -> None:
has_team_responsible_property = False or component["scope"] == "excluded"
script_path = ""
if "properties" in component:
for prop in component["properties"]:
if prop["name"] == "internal:team_responsible":
has_team_responsible_property = True
elif prop["name"] == "import_script_path" and component["scope"] == "required":
script_path = prop["value"]
if not has_team_responsible_property:
error_manager.append_full_error_message(MISSING_TEAM_ERROR)
if not component.get("version"):
error_manager.append_full_error_message(MISSING_VERSION_IN_SBOM_COMPONENT_ERROR)
return
comp_version = component["version"]
# If the version is unknown or the script path property is absent, the version
# check is not possible (these are valid options and no error is generated).
if comp_version == "Unknown" or script_path == "":
return
# Include the .pedigree.descendants[0] version for version matching
if "pedigree" in component and "descendants" in component[
"pedigree"] and "version" in component["pedigree"]["descendants"][0]:
comp_pedigree_version = component["pedigree"]["descendants"][0]["version"]
else:
comp_pedigree_version = ""
# At this point a version is attempted to be read from the import script file
script_version = get_script_version(script_path, "VERSION",
error_manager) or get_script_version(
script_path, "REVISION", error_manager)
if script_version == "":
error_manager.append_full_error_message(MISSING_VERSION_IN_IMPORT_FILE_ERROR + script_path)
elif strip_extra_prefixes(script_version) != strip_extra_prefixes(comp_version) and \
strip_extra_prefixes(script_version) != strip_extra_prefixes(comp_pedigree_version):
error_manager.append_full_error_message(
VERSION_MISMATCH_ERROR +
f"\nscript version:{script_version}\nsbom component version:{comp_version}\nsbom component pedigree version:{comp_pedigree_version}"
)
def validate_component(component: dict, third_party_libs: set, error_manager: ErrorManager) -> None:
error_manager.update_component_attribute(component["name"])
if "scope" not in component:
error_manager.append_full_error_message("component must include a scope.")
else:
validate_evidence(component, third_party_libs, error_manager)
validate_properties(component, error_manager)
validate_license(component, error_manager)
if "purl" not in component and "cpe" not in component:
error_manager.append_full_error_message(MISSING_PURL_CPE_ERROR)
error_manager.update_component_attribute("")
def validate_location(component: dict, third_party_libs: set, error_manager: ErrorManager) -> None:
if "evidence" in component and "occurrences" in component["evidence"]:
occurrences = component["evidence"]["occurrences"]
for occurrence in occurrences:
if "location" in occurrence:
location = occurrence["location"]
if not os.path.exists(
location) and not SKIP_FILE_CHECKING and component["scope"] == "required":
error_manager.append_full_error_message("location does not exist in repo.")
if location.startswith(THIRD_PARTY_LOCATION_PREFIX):
lib = location.removeprefix(THIRD_PARTY_LOCATION_PREFIX)
if lib in third_party_libs:
third_party_libs.remove(lib)
elif component["scope"] == "required":
error_manager.append_full_error_message(
"'evidence.occurrences' field must include at least one location.")
def lint_sbom(input_file: str, output_file: str, third_party_libs: set, def lint_sbom(input_file: str, output_file: str, third_party_libs: set,
should_format: bool) -> list: should_format: bool) -> ErrorManager:
with open(input_file, "r", encoding="utf-8") as sbom_file: with open(input_file, "r", encoding="utf-8") as sbom_file:
sbom_text = sbom_file.read() sbom_text = sbom_file.read()
errors = [] error_manager = ErrorManager(input_file)
try: try:
sbom = json.loads(sbom_text) sbom = json.loads(sbom_text)
except Exception as ex: except Exception as ex:
errors.append(f"Failed to parse {input_file}: {str(ex)}") error_manager.append(f"Failed to parse {input_file}: {str(ex)}")
return errors return error_manager
try: try:
schema = get_schema() schema = get_schema()
jsonschema.validators.validator_for(schema)(schema, jsonschema.validators.validator_for(schema)(schema,
registry=local_schema_registry()).validate(sbom) registry=local_schema_registry()).validate(sbom)
except jsonschema.ValidationError as error: except jsonschema.ValidationError as error:
errors.append(f"{input_file} file did not match the CycloneDX schema") error_manager.append(f"{SCHEMA_MATCH_FAILURE} {input_file}")
errors.append(error.message) error_manager.append(error.message)
return errors return error_manager
errors = []
components = sbom["components"] components = sbom["components"]
for component in components: for component in components:
name = component["name"] validate_component(component, third_party_libs, error_manager)
def add_component_error(name: str, message: str):
errors.append(f"Error in component {name}: {message}")
if "scope" not in component:
add_component_error(name, "component must include a scope.")
elif component["scope"] != "optional":
if "evidence" in component and "occurrences" in component["evidence"]:
occurrences = component["evidence"]["occurrences"]
if not occurrences:
add_component_error(
name, "'evidence.occurrences' field must include at least one location.")
for occurrence in occurrences:
location = occurrence["location"]
if not os.path.exists(location) and not SKIP_FILE_CHECKING:
add_component_error(name, "location does not exist in repo.")
if location.startswith(THIRD_PARTY_LOCATION_PREFIX):
lib = location[len(THIRD_PARTY_LOCATION_PREFIX):]
if lib in third_party_libs:
third_party_libs.remove(lib)
else:
add_component_error(name, MISSING_EVIDENCE_ERROR)
has_team_responsible_property = False
if "properties" in component:
for prop in component["properties"]:
if prop["name"] == "internal:team_responsible":
has_team_responsible_property = True
break
if not has_team_responsible_property:
add_component_error(name, MISSING_TEAM_ERROR)
if "purl" not in component and "cpe" not in component:
add_component_error(name, MISSING_PURL_CPE_ERROR)
if third_party_libs: if third_party_libs:
errors.append(UNDEFINED_THIRD_PARTY_ERROR) error_manager.append(UNDEFINED_THIRD_PARTY_ERROR)
for lib in third_party_libs: for lib in third_party_libs:
errors.append(f" {lib}") error_manager.append(f" {lib}")
formatted_sbom = json.dumps(sbom, indent=2) + "\n" formatted_sbom = json.dumps(sbom, indent=2) + "\n"
if formatted_sbom != sbom_text: if formatted_sbom != sbom_text:
errors.append(f"{input_file} {FORMATTING_ERROR}") error_manager.append(f"{input_file} {FORMATTING_ERROR}")
if should_format: if should_format:
with open(output_file, "w", encoding="utf-8") as sbom_file: with open(output_file, "w", encoding="utf-8") as sbom_file:
sbom_file.write(formatted_sbom) sbom_file.write(formatted_sbom)
return errors return error_manager
def main() -> int: def main() -> int:
os.chdir(os.environ.get("BUILD_WORKSPACE_DIRECTORY", "."))
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument( parser.add_argument(
"--format", "--format",
@ -139,23 +299,15 @@ def main() -> int:
should_format = args.format should_format = args.format
input_file = args.input_file input_file = args.input_file
output_file = args.output_file output_file = args.output_file
third_party_libs = { third_party_libs = set(
path path for path in os.listdir(THIRD_PARTY_DIR)
for path in os.listdir(THIRD_PARTY_DIR) if not os.path.isfile(os.path.join(THIRD_PARTY_DIR, path)))
if not os.path.isfile(os.path.join(THIRD_PARTY_DIR, path))
}
# the only files in this dir that are not third party libs # the only files in this dir that are not third party libs
third_party_libs.remove("scripts") third_party_libs.remove("scripts")
# wiredtiger will not be included in the sbom since it is considered part of the server error_manager = lint_sbom(input_file, output_file, third_party_libs, should_format)
third_party_libs.remove("wiredtiger") error_manager.print_errors()
# the only files in the sasl dir are BUILD files to setup the sasl library in Windows
third_party_libs.remove("sasl")
errors = lint_sbom(input_file, output_file, third_party_libs, should_format)
if errors: return 0 if error_manager.zero_error() else 1
print("\n".join(errors), file=sys.stderr)
return 1 if errors else 0
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -0,0 +1,10 @@
#!/bin/bash
# This script downloads and imports protobuf
set -euo pipefail
IFS=$'\n\t'
set -vx
NAME=protobuf
VERSION="mongo/v4.25.0"

View File

@ -0,0 +1,63 @@
#!/bin/bash
# This script creates a copy of sources for librdkafka and librdkafka++.
# This script currently only works on Linux x86_64 and aarch64 platforms.
set -euo pipefail
IFS=$'\n\t'
if [ "$#" -ne 0 ]; then
echo "This script does not take any arguments"
exit 1
fi
# Create a temporary directory to clone and configure librdkafka
TEMP_DIR=$(mktemp -d /tmp/librdkafka.XXXXXX)
# Setup some directory variables
DEST_DIR=$(git rev-parse --show-toplevel)/src/third_party/librdkafka
DIST_DIR=$DEST_DIR/dist
PLATFORM_DIR=$DIST_DIR/platform
# Clean the output directories
rm -rf $DIST_DIR
rm -rf $PLATFORM_DIR
rm -rf $TEMP_DIR/*
pushd $TEMP_DIR
# Clone the v2.0.2 branch of librdkafka.
git clone --depth 1 --branch v2.0.2 https://github.com/confluentinc/librdkafka.git
pushd librdkafka
echo "Generating config.h"
# Run configure to generate config.h, and move it into a platform specific directory.
./configure --source-deps-only
platformName=linux_$(uname -m)
# Copy the config.h into a platform specific directory
mkdir -p $PLATFORM_DIR/$platformName/include
mv config.h $PLATFORM_DIR/$platformName/include
# Remove un-used files
rm -rf CHANGELOG.md CODE_OF_CONDUCT.md CONFIGURATION.md CONTRIBUTING.md INTRODUCTION.md \
README.md README.win32 STATISTICS.md config.log.old dev-conf.sh examples/ \
CMakeLists.txt lds-gen.py mklove/ packaging/ service.yml tests/ vcpkg.json win32/ \
Makefile Makefile.config config.cache configure.self configure debian mainpage.doxy Doxyfile \
src/CMakeLists.txt src/Makefile src/generate_proto.sh src/librdkafka_cgrp_synch.png src/statistics_schema.json \
src-cpp/CMakeLists.txt src-cpp/Makefile src-cpp/README.md config.log
pushd src
# Replace all instances of the string "LZ4" and "XXH" with "KLZ4" and "KXXH" in the C source code.
# This is to avoid symbol conflicts with the LZ4 and XXH source that is used by
# third_party/mozjs.
sed -i 's/LZ4/KLZ4/g' *
sed -i 's/XXH/KXXH/g' *
popd
mkdir -p $DIST_DIR
cp -r * $DIST_DIR
popd
popd

View File

@ -0,0 +1,64 @@
#!/bin/bash
# This script creates a copy of sources for librdkafka and librdkafka++.
# This script currently only works on Linux x86_64 and aarch64 platforms.
set -euo pipefail
IFS=$'\n\t'
if [ "$#" -ne 0 ]; then
echo "This script does not take any arguments"
exit 1
fi
# Create a temporary directory to clone and configure librdkafka
TEMP_DIR=$(mktemp -d /tmp/librdkafka.XXXXXX)
# Setup some directory variables
DEST_DIR=$(git rev-parse --show-toplevel)/src/third_party/librdkafka
DIST_DIR=$DEST_DIR/dist
PLATFORM_DIR=$DIST_DIR/platform
VERSION="2.0.2"
# Clean the output directories
rm -rf $DIST_DIR
rm -rf $PLATFORM_DIR
rm -rf $TEMP_DIR/*
pushd $TEMP_DIR
# Clone the v2.0.2 branch of librdkafka.
git clone --depth 1 --branch v2.0.2 https://github.com/confluentinc/librdkafka.git
pushd librdkafka
echo "Generating config.h"
# Run configure to generate config.h, and move it into a platform specific directory.
./configure --source-deps-only
platformName=linux_$(uname -m)
# Copy the config.h into a platform specific directory
mkdir -p $PLATFORM_DIR/$platformName/include
mv config.h $PLATFORM_DIR/$platformName/include
# Remove un-used files
rm -rf CHANGELOG.md CODE_OF_CONDUCT.md CONFIGURATION.md CONTRIBUTING.md INTRODUCTION.md \
README.md README.win32 STATISTICS.md config.log.old dev-conf.sh examples/ \
CMakeLists.txt lds-gen.py mklove/ packaging/ service.yml tests/ vcpkg.json win32/ \
Makefile Makefile.config config.cache configure.self configure debian mainpage.doxy Doxyfile \
src/CMakeLists.txt src/Makefile src/generate_proto.sh src/librdkafka_cgrp_synch.png src/statistics_schema.json \
src-cpp/CMakeLists.txt src-cpp/Makefile src-cpp/README.md config.log
pushd src
# Replace all instances of the string "LZ4" and "XXH" with "KLZ4" and "KXXH" in the C source code.
# This is to avoid symbol conflicts with the LZ4 and XXH source that is used by
# third_party/mozjs.
sed -i 's/LZ4/KLZ4/g' *
sed -i 's/XXH/KXXH/g' *
popd
mkdir -p $DIST_DIR
cp -r * $DIST_DIR
popd
popd

View File

@ -0,0 +1,64 @@
#!/bin/bash
# This script creates a copy of sources for librdkafka and librdkafka++.
# This script currently only works on Linux x86_64 and aarch64 platforms.
set -euo pipefail
IFS=$'\n\t'
if [ "$#" -ne 0 ]; then
echo "This script does not take any arguments"
exit 1
fi
# Create a temporary directory to clone and configure librdkafka
TEMP_DIR=$(mktemp -d /tmp/librdkafka.XXXXXX)
# Setup some directory variables
DEST_DIR=$(git rev-parse --show-toplevel)/src/third_party/librdkafka
DIST_DIR=$DEST_DIR/dist
PLATFORM_DIR=$DIST_DIR/platform
VERSION = "wrong version"
# Clean the output directories
rm -rf $DIST_DIR
rm -rf $PLATFORM_DIR
rm -rf $TEMP_DIR/*
pushd $TEMP_DIR
# Clone the v2.0.2 branch of librdkafka.
git clone --depth 1 --branch v2.0.2 https://github.com/confluentinc/librdkafka.git
pushd librdkafka
echo "Generating config.h"
# Run configure to generate config.h, and move it into a platform specific directory.
./configure --source-deps-only
platformName=linux_$(uname -m)
# Copy the config.h into a platform specific directory
mkdir -p $PLATFORM_DIR/$platformName/include
mv config.h $PLATFORM_DIR/$platformName/include
# Remove un-used files
rm -rf CHANGELOG.md CODE_OF_CONDUCT.md CONFIGURATION.md CONTRIBUTING.md INTRODUCTION.md \
README.md README.win32 STATISTICS.md config.log.old dev-conf.sh examples/ \
CMakeLists.txt lds-gen.py mklove/ packaging/ service.yml tests/ vcpkg.json win32/ \
Makefile Makefile.config config.cache configure.self configure debian mainpage.doxy Doxyfile \
src/CMakeLists.txt src/Makefile src/generate_proto.sh src/librdkafka_cgrp_synch.png src/statistics_schema.json \
src-cpp/CMakeLists.txt src-cpp/Makefile src-cpp/README.md config.log
pushd src
# Replace all instances of the string "LZ4" and "XXH" with "KLZ4" and "KXXH" in the C source code.
# This is to avoid symbol conflicts with the LZ4 and XXH source that is used by
# third_party/mozjs.
sed -i 's/LZ4/KLZ4/g' *
sed -i 's/XXH/KXXH/g' *
popd
mkdir -p $DIST_DIR
cp -r * $DIST_DIR
popd
popd

View File

@ -0,0 +1,42 @@
{
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "kafka",
"version": "",
"scope": "required",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"cpe": "test_cpe",
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/kafka_missing_version_import.sh"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/librdkafka"
}
]
}
}
]
}

View File

@ -0,0 +1,41 @@
{
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"version": "v2.0.2",
"scope": "required",
"cpe": "test_cpe",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/kafka_valid_import.sh"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/librdkafka"
}
]
}
}
]
}

View File

@ -2,11 +2,11 @@
"properties": [ "properties": [
{ {
"name": "comment", "name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.6/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details." "value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
} }
], ],
"bomFormat": "CycloneDX", "bomFormat": "CycloneDX",
"specVersion": "1.6", "specVersion": "1.5",
"version": 1, "version": 1,
"components": [ "components": [
@ -14,7 +14,13 @@
{ {
"type": "library", "type": "library",
"name": "kafka", "name": "kafka",
"version": "2.0.2",
"scope": "required", "scope": "required",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"cpe": "test_cpe", "cpe": "test_cpe",
"properties": [ "properties": [
{ {
@ -33,7 +39,15 @@
{ {
"type": "library", "type": "library",
"name": "protobuf", "name": "protobuf",
"version": "v4.25.0",
"scope": "required", "scope": "required",
"licenses": [
{
"license": {
"id": "BSD-3-Clause"
}
}
],
"purl": "test_purl", "purl": "test_purl",
"properties": [ "properties": [
{ {
@ -54,7 +68,15 @@
{ {
"type": "library", "type": "library",
"name": "unicode", "name": "unicode",
"version": "8.0",
"scope": "optional", "scope": "optional",
"licenses": [
{
"license": {
"id": "Unicode-DFS-2016"
}
}
],
"purl": "test_purl", "purl": "test_purl",
"properties": [ "properties": [
{ {

View File

@ -0,0 +1,43 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "kafka",
"version": "v2.0.2",
"licenses": [
{
"expression": "xBSD-3-Clause"
}
],
"scope": "required",
"cpe": "test_cpe",
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/kafka_valid_import.sh"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/librdkafka"
}
]
}
}
]
}

View File

@ -0,0 +1,43 @@
{
"$schema": "http://cyclonedx.org/schema/bom-1.5.schema.json",
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "kafka",
"version": "v2.0.2",
"licenses": [
{
"expression": "xBSD-3-Clause"
}
],
"scope": "required",
"cpe": "test_cpe",
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/kafka_valid_import.sh"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/librdkafka"
}
]
}
}
]
}

View File

@ -2,11 +2,11 @@
"properties": [ "properties": [
{ {
"name": "comment", "name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.6/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details." "value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
} }
], ],
"bomFormat": "CycloneDX", "bomFormat": "CycloneDX",
"specVersion": "1.6", "specVersion": "1.5",
"version": 1, "version": 1,
"components": [ "components": [
{ {
@ -14,6 +14,11 @@
"name": "kafka", "name": "kafka",
"scope": "required", "scope": "required",
"cpe": "test_cpe", "cpe": "test_cpe",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"properties": [ "properties": [
{ {
"name": "internal:team_responsible", "name": "internal:team_responsible",

View File

@ -0,0 +1,74 @@
{
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "kafka",
"version": "v2.0.2",
"scope": "required",
"cpe": "test_cpe",
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/kafka_valid_import.sh"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/librdkafka"
}
]
}
},
{
"type": "library",
"name": "protobuf",
"version": "v4.25.0",
"scope": "required",
"purl": "test_purl",
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/import_script_with_mongo_prefix_version.sh"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/protobuf"
}
]
}
},
{
"type": "library",
"name": "unicode",
"version": "8.0",
"scope": "optional",
"purl": "test_purl",
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
}
]
}
]
}

View File

@ -2,17 +2,22 @@
"properties": [ "properties": [
{ {
"name": "comment", "name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.6/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details." "value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
} }
], ],
"bomFormat": "CycloneDX", "bomFormat": "CycloneDX",
"specVersion": "1.6", "specVersion": "1.5",
"version": 1, "version": 1,
"components": [ "components": [
{ {
"type": "library", "type": "library",
"name": "kafka", "name": "kafka",
"scope": "required", "scope": "required",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"cpe": "test_cpe", "cpe": "test_cpe",
"properties": [ "properties": [
{ {

View File

@ -2,17 +2,22 @@
"properties": [ "properties": [
{ {
"name": "comment", "name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.6/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details." "value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
} }
], ],
"bomFormat": "CycloneDX", "bomFormat": "CycloneDX",
"specVersion": "1.6", "specVersion": "1.5",
"version": 1, "version": 1,
"components": [ "components": [
{ {
"type": "library", "type": "library",
"name": "kafka", "name": "kafka",
"scope": "required", "scope": "required",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"cpe": "test_cpe", "cpe": "test_cpe",
"evidence": { "evidence": {
"occurrences": [ "occurrences": [

View File

@ -0,0 +1,37 @@
{
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "kafka",
"scope": "required",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"cpe": "test_cpe",
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/librdkafka"
}
]
}
}
]
}

View File

@ -0,0 +1,51 @@
{
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"bom-ref": "pkg:github/aappleby/smhasher@a6bd3ce7be8ad147ea820a7cf6229a975c0c96bb",
"supplier": {
"name": "Austin Appleby"
},
"author": "Austin Appleby",
"group": "aappleby",
"name": "MurmurHash3",
"version": "a6bd3ce7be8ad147ea820a7cf6229a975c0c96bb",
"licenses": [
{
"license": {
"name": "Public Domain"
}
}
],
"copyright": "MurmurHash3 was written by Austin Appleby, and is placed in the public domain. The author hereby disclaims copyright to this source code.",
"purl": "pkg:github/aappleby/smhasher@a6bd3ce7be8ad147ea820a7cf6229a975c0c96bb",
"properties": [
{
"name": "internal:team_responsible",
"value": "Storage Execution"
},
{
"name": "info_link",
"value": "https://github.com/aappleby/smhasher/blob/a6bd3ce/"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/murmurhash3"
}
]
},
"scope": "required"
}
]
}

View File

@ -0,0 +1,51 @@
{
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "kafka",
"version": "v2.0.0",
"scope": "required",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"cpe": "test_cpe",
"pedigree": {
"descendants": [
{
"type": "library",
"name": "kafka-fork",
"version": "v2.0.2"
}
]
},
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/kafka_valid_import.sh"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/kafka"
}
]
}
}
]
}

View File

@ -0,0 +1,42 @@
{
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "kafka",
"version": "2.0.2",
"scope": "required",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"cpe": "test_cpe",
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/kafka_nonexisting_import.sh"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/librdkafka"
}
]
}
}
]
}

View File

@ -0,0 +1,42 @@
{
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "kafka",
"version": "2.0.2",
"scope": "required",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"cpe": "test_cpe",
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/kafka_missing_version_import.sh"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/librdkafka"
}
]
}
}
]
}

View File

@ -0,0 +1,42 @@
{
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"name": "kafka",
"version": "v4.25.0",
"scope": "required",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"cpe": "test_cpe",
"properties": [
{
"name": "internal:team_responsible",
"value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/kafka_wrong_version_import.sh"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/librdkafka"
}
]
}
}
]
}

View File

@ -0,0 +1,51 @@
{
"properties": [
{
"name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
}
],
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"version": 1,
"components": [
{
"type": "library",
"bom-ref": "pkg:github/aappleby/smhasher@a6bd3ce7be8ad147ea820a7cf6229a975c0c96bb",
"supplier": {
"name": "Austin Appleby"
},
"author": "Austin Appleby",
"group": "aappleby",
"name": "MurmurHash3",
"version": "a6bd3ce7be8ad147ea820a7cf6229a975c0c96bb",
"licenses": [
{
"license": {
"name": "Public Domain"
}
}
],
"copyright": "MurmurHash3 was written by Austin Appleby, and is placed in the public domain. The author hereby disclaims copyright to this source code.",
"purl": "pkg:github/aappleby/smhasher@a6bd3ce7be8ad147ea820a7cf6229a975c0c96bb",
"properties": [
{
"name": "internal:team_responsible",
"value": "Storage Execution"
},
{
"name": "info_link",
"value": "https://github.com/aappleby/smhasher/blob/a6bd3ce/"
}
],
"evidence": {
"occurrences": [
{
"location": "src/third_party/murmurhash3"
}
]
},
"scope": "required"
}
]
}

View File

@ -2,22 +2,32 @@
"properties": [ "properties": [
{ {
"name": "comment", "name": "comment",
"value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.6/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details." "value": "SBOM for MDB server product; this file should comply with the format specified here: https://cyclonedx.org/docs/1.5/json/#components_items_publisher; This file is still in development; see https://jira.mongodb.org/browse/DEVPROD-2623 for details."
} }
], ],
"bomFormat": "CycloneDX", "bomFormat": "CycloneDX",
"specVersion": "1.6", "specVersion": "1.5",
"version": 1, "version": 1,
"components": [ "components": [
{ {
"type": "library", "type": "library",
"name": "kafka", "name": "kafka",
"version": "v2.0.2",
"licenses": [
{
"expression": "BSD-3-Clause"
}
],
"scope": "required", "scope": "required",
"cpe": "test_cpe", "cpe": "test_cpe",
"properties": [ "properties": [
{ {
"name": "internal:team_responsible", "name": "internal:team_responsible",
"value": "server_security" "value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/kafka_valid_import.sh"
} }
], ],
"evidence": { "evidence": {
@ -31,12 +41,24 @@
{ {
"type": "library", "type": "library",
"name": "protobuf", "name": "protobuf",
"version": "v4.25.0",
"scope": "required", "scope": "required",
"licenses": [
{
"license": {
"id": "BSD-3-Clause"
}
}
],
"purl": "test_purl", "purl": "test_purl",
"properties": [ "properties": [
{ {
"name": "internal:team_responsible", "name": "internal:team_responsible",
"value": "server_security" "value": "server_security"
},
{
"name": "import_script_path",
"value": "buildscripts/tests/sbom_linter/inputs/import_script_with_mongo_prefix_version.sh"
} }
], ],
"evidence": { "evidence": {
@ -50,6 +72,14 @@
{ {
"type": "library", "type": "library",
"name": "unicode", "name": "unicode",
"version": "8.0",
"licenses": [
{
"license": {
"id": "Unicode-DFS-2016"
}
}
],
"scope": "optional", "scope": "optional",
"purl": "test_purl", "purl": "test_purl",
"properties": [ "properties": [

View File

@ -26,51 +26,126 @@ class TestSbom(unittest.TestCase):
def tearDown(self): def tearDown(self):
shutil.rmtree(self.output_dir) shutil.rmtree(self.output_dir)
def assert_message_in_errors(self, errors: list, message: str): def assert_message_in_errors(self, error_manager: sbom_linter.ErrorManager, message: str):
contained_message = False if not error_manager.find_message_in_errors(message):
for error in errors: error_manager.print_errors()
if message in error:
contained_message = True
break
if not contained_message:
self.fail(f"Could not find error message matching: {message}") self.fail(f"Could not find error message matching: {message}")
def test_valid_sbom(self): def test_valid_sbom(self):
test_file = os.path.join(self.input_dir, "valid_sbom.json") test_file = os.path.join(self.input_dir, "valid_sbom.json")
third_party_libs = {"librdkafka", "protobuf"} third_party_libs = {"librdkafka", "protobuf"}
errors = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, True) error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, True)
self.assertFalse(errors) if not error_manager.zero_error():
error_manager.print_errors()
self.assertTrue(error_manager.zero_error())
def test_undefined_dep(self): def test_undefined_dep(self):
test_file = os.path.join(self.input_dir, "valid_sbom.json") test_file = os.path.join(self.input_dir, "valid_sbom.json")
third_party_libs = {"librdkafka", "protobuf", "extra_dep"} third_party_libs = {"librdkafka", "protobuf", "extra_dep"}
errors = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False) error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
self.assert_message_in_errors(errors, sbom_linter.UNDEFINED_THIRD_PARTY_ERROR) self.assert_message_in_errors(error_manager, sbom_linter.UNDEFINED_THIRD_PARTY_ERROR)
def test_missing_purl_or_cpe(self): def test_missing_purl_or_cpe(self):
test_file = os.path.join(self.input_dir, "sbom_missing_purl.json") test_file = os.path.join(self.input_dir, "sbom_missing_purl.json")
third_party_libs = {"librdkafka", "protobuf"} third_party_libs = {"librdkafka", "protobuf"}
errors = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False) error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
self.assert_message_in_errors(errors, sbom_linter.MISSING_PURL_CPE_ERROR) self.assert_message_in_errors(error_manager, sbom_linter.MISSING_PURL_CPE_ERROR)
def test_missing_evidence(self): def test_missing_evidence(self):
test_file = os.path.join(self.input_dir, "sbom_missing_evidence.json") test_file = os.path.join(self.input_dir, "sbom_missing_evidence.json")
third_party_libs = {"librdkafka", "protobuf"} third_party_libs = {"librdkafka", "protobuf"}
errors = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False) error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
self.assert_message_in_errors(errors, sbom_linter.MISSING_EVIDENCE_ERROR) self.assert_message_in_errors(error_manager, sbom_linter.MISSING_EVIDENCE_ERROR)
def test_missing_team_responsible(self): def test_missing_team_responsible(self):
test_file = os.path.join(self.input_dir, "sbom_missing_team.json") test_file = os.path.join(self.input_dir, "sbom_missing_team.json")
third_party_libs = {"librdkafka", "protobuf"} third_party_libs = {"librdkafka", "protobuf"}
errors = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False) error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
self.assert_message_in_errors(errors, sbom_linter.MISSING_TEAM_ERROR) self.assert_message_in_errors(error_manager, sbom_linter.MISSING_TEAM_ERROR)
def test_format(self): def test_format(self):
test_file = os.path.join(self.input_dir, "sbom_invalid_format.json") test_file = os.path.join(self.input_dir, "sbom_invalid_format.json")
output_file = os.path.join(self.output_dir, "new_valid_sbom1.json") output_file = os.path.join(self.output_dir, "new_valid_sbom1.json")
third_party_libs = {"librdkafka", "protobuf"} third_party_libs = {"librdkafka", "protobuf"}
errors = sbom_linter.lint_sbom(test_file, output_file, third_party_libs, True) error_manager = sbom_linter.lint_sbom(test_file, output_file, third_party_libs, True)
self.assert_message_in_errors(errors, sbom_linter.FORMATTING_ERROR) self.assert_message_in_errors(error_manager, sbom_linter.FORMATTING_ERROR)
errors = sbom_linter.lint_sbom(output_file, output_file, third_party_libs, False) error_manager = sbom_linter.lint_sbom(output_file, output_file, third_party_libs, False)
self.assertFalse(errors) self.assertTrue(error_manager.zero_error())
def test_missing_version(self):
test_file = os.path.join(self.input_dir, "sbom_missing_version.json")
third_party_libs = {"librdkafka"}
error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
self.assert_message_in_errors(
error_manager, sbom_linter.MISSING_VERSION_IN_SBOM_COMPONENT_ERROR
)
def test_missing_version_in_import_file(self):
test_file = os.path.join(self.input_dir, "sbom_script_missing_version.json")
third_party_libs = {"librdkafka"}
error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
self.assert_message_in_errors(
error_manager, sbom_linter.MISSING_VERSION_IN_IMPORT_FILE_ERROR
)
def test_missing_import_file(self):
test_file = os.path.join(self.input_dir, "sbom_script_file_missing.json")
third_party_libs = {"librdkafka"}
error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
self.assert_message_in_errors(
error_manager, sbom_linter.COULD_NOT_FIND_OR_READ_SCRIPT_FILE_ERROR
)
def test_version_mismatch(self):
test_file = os.path.join(self.input_dir, "sbom_version_mismatch.json")
third_party_libs = {"librdkafka"}
error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
self.assert_message_in_errors(error_manager, sbom_linter.VERSION_MISMATCH_ERROR)
def test_pedigree_version_match(self):
test_file = os.path.join(self.input_dir, "sbom_pedigree_version_match.json")
third_party_libs = {"kafka"}
error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
if not error_manager.zero_error():
error_manager.print_errors()
self.assertTrue(error_manager.zero_error())
def test_schema_match_failure(self):
test_file = os.path.join(self.input_dir, "sbom_component_name_missing.json")
third_party_libs = {"librdkafka"}
error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
self.assert_message_in_errors(error_manager, sbom_linter.SCHEMA_MATCH_FAILURE)
def test_component_empty_version(self):
test_file = os.path.join(self.input_dir, "sbom_component_empty_version.json")
third_party_libs = {"librdkafka"}
error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
self.assert_message_in_errors(
error_manager, sbom_linter.MISSING_VERSION_IN_SBOM_COMPONENT_ERROR
)
def test_missing_license(self):
test_file = os.path.join(self.input_dir, "sbom_missing_license.json")
third_party_libs = {"librdkafka"}
error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
self.assert_message_in_errors(
error_manager, sbom_linter.MISSING_LICENSE_IN_SBOM_COMPONENT_ERROR
)
def test_invalid_license_expression(self):
test_file = os.path.join(self.input_dir, "sbom_invalid_license_expression.json")
third_party_libs = {"librdkafka"}
error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
#print(error_manager.errors)
self.assert_message_in_errors(
error_manager, "ExpressionInfo"
)
def test_named_license(self):
test_file = os.path.join(self.input_dir, "sbom_named_license.json")
third_party_libs = {"murmurhash3"}
error_manager = sbom_linter.lint_sbom(test_file, test_file, third_party_libs, False)
if not error_manager.zero_error():
error_manager.print_errors()
self.assertTrue(error_manager.zero_error())

38
poetry.lock generated
View File

@ -96,6 +96,24 @@ files = [
docs = ["furo", "jaraco.packaging (>=9.3)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] docs = ["furo", "jaraco.packaging (>=9.3)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
testing = ["jaraco.test", "pytest (!=8.0.*)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)"] testing = ["jaraco.test", "pytest (!=8.0.*)", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)"]
[[package]]
name = "boolean-py"
version = "5.0"
description = "Define boolean algebras, create and parse boolean expressions and create custom boolean DSL."
optional = false
python-versions = "*"
groups = ["lint"]
files = [
{file = "boolean_py-5.0-py3-none-any.whl", hash = "sha256:ef28a70bd43115208441b53a045d1549e2f0ec6e3d08a9d142cbc41c1938e8d9"},
{file = "boolean_py-5.0.tar.gz", hash = "sha256:60cbc4bad079753721d32649545505362c754e121570ada4658b852a3a318d95"},
]
[package.extras]
dev = ["build", "twine"]
docs = ["Sphinx (>=3.3.1)", "doc8 (>=0.8.1)", "sphinx-rtd-theme (>=0.5.0)", "sphinxcontrib-apidoc (>=0.3.0)"]
linting = ["black", "isort", "pycodestyle"]
testing = ["pytest (>=6,!=7.0.0)", "pytest-xdist (>=2)"]
[[package]] [[package]]
name = "boto3" name = "boto3"
version = "1.34.40" version = "1.34.40"
@ -1481,6 +1499,24 @@ six = ">=1.7"
Twisted = "*" Twisted = "*"
"zope.interface" = "*" "zope.interface" = "*"
[[package]]
name = "license-expression"
version = "30.4.4"
description = "license-expression is a comprehensive utility library to parse, compare, simplify and normalize license expressions (such as SPDX license expressions) using boolean logic."
optional = false
python-versions = ">=3.9"
groups = ["lint"]
files = [
{file = "license_expression-30.4.4-py3-none-any.whl", hash = "sha256:421788fdcadb41f049d2dc934ce666626265aeccefddd25e162a26f23bcbf8a4"},
{file = "license_expression-30.4.4.tar.gz", hash = "sha256:73448f0aacd8d0808895bdc4b2c8e01a8d67646e4188f887375398c761f340fd"},
]
[package.dependencies]
"boolean.py" = ">=4.0"
[package.extras]
dev = ["Sphinx (>=5.0.2)", "doc8 (>=0.11.2)", "pytest (>=7.0.1)", "pytest-xdist (>=2)", "ruff", "sphinx-autobuild", "sphinx-copybutton", "sphinx-reredirects (>=0.1.2)", "sphinx-rtd-dark-mode (>=1.3.0)", "sphinx-rtd-theme (>=1.0.0)", "sphinxcontrib-apidoc (>=0.4.0)", "twine"]
[[package]] [[package]]
name = "lxml" name = "lxml"
version = "5.1.0" version = "5.1.0"
@ -4387,4 +4423,4 @@ oldcrypt = []
[metadata] [metadata]
lock-version = "2.1" lock-version = "2.1"
python-versions = ">=3.10,<4.0" python-versions = ">=3.10,<4.0"
content-hash = "5fc2b0d9fc4f626f9dbc326ae8acfa8798c6b005726762c588999f4e4a986228" content-hash = "3d68e8c7f9cd0f11850efa26c1a30e1d2273e8afa1857f802639543bf140e8c8"

View File

@ -121,6 +121,7 @@ tqdm = "*"
colorama = "^0.4.6" colorama = "^0.4.6"
evergreen-lint = "^0.1.10" evergreen-lint = "^0.1.10"
types-retry = "^0.9.9.4" types-retry = "^0.9.9.4"
license-expression = "^30.4.4"
[tool.poetry.group.platform.dependencies] [tool.poetry.group.platform.dependencies]
pypiwin32 = { version = ">=223", markers = "sys_platform == 'win32'" } pypiwin32 = { version = ">=223", markers = "sys_platform == 'win32'" }

1916
sbom.json

File diff suppressed because it is too large Load Diff

View File

@ -5,7 +5,8 @@ set -vxeuo pipefail
FMT_GIT_URL="https://github.com/mongodb-forks/fmt.git" FMT_GIT_URL="https://github.com/mongodb-forks/fmt.git"
FMT_GIT_REV=7.1.3 VERSION=7.1.3
FMT_GIT_REV=$VERSION
FMT_GIT_DIR=$(mktemp -d /tmp/import-fmt.XXXXXX) FMT_GIT_DIR=$(mktemp -d /tmp/import-fmt.XXXXXX)
trap "rm -rf $FMT_GIT_DIR" EXIT trap "rm -rf $FMT_GIT_DIR" EXIT

View File

@ -18,7 +18,7 @@ if grep -q Microsoft /proc/version; then
fi fi
NAME=libbson NAME=libbson
REVISION=1.27.6 VERSION=1.27.6
if grep -q Microsoft /proc/version; then if grep -q Microsoft /proc/version; then
SRC_ROOT=$(wslpath -u $(powershell.exe -Command "Get-ChildItem Env:TEMP | Get-Content | Write-Host")) SRC_ROOT=$(wslpath -u $(powershell.exe -Command "Get-ChildItem Env:TEMP | Get-Content | Write-Host"))
@ -43,7 +43,7 @@ if [ ! -d $SRC ]; then
$GIT_EXE clone https://github.com/mongodb/mongo-c-driver $CLONE_DEST $GIT_EXE clone https://github.com/mongodb/mongo-c-driver $CLONE_DEST
pushd $SRC pushd $SRC
$GIT_EXE checkout $REVISION $GIT_EXE checkout $VERSION
popd popd
fi fi

View File

@ -18,7 +18,7 @@ if grep -q Microsoft /proc/version; then
fi fi
NAME=libmongocrypt NAME=libmongocrypt
REVISION=1.8.4 VERSION=1.8.4
if grep -q Microsoft /proc/version; then if grep -q Microsoft /proc/version; then
SRC_ROOT=$(wslpath -u $(powershell.exe -Command "Get-ChildItem Env:TEMP | Get-Content | Write-Host")) SRC_ROOT=$(wslpath -u $(powershell.exe -Command "Get-ChildItem Env:TEMP | Get-Content | Write-Host"))
@ -43,7 +43,7 @@ if [ ! -d $SRC ]; then
$GIT_EXE clone https://github.com/mongodb/libmongocrypt $CLONE_DEST $GIT_EXE clone https://github.com/mongodb/libmongocrypt $CLONE_DEST
pushd $SRC pushd $SRC
$GIT_EXE checkout $REVISION $GIT_EXE checkout $VERSION
popd popd
fi fi

View File

@ -18,6 +18,7 @@ TEMP_DIR=$(mktemp -d /tmp/librdkafka.XXXXXX)
DEST_DIR=$(git rev-parse --show-toplevel)/src/third_party/librdkafka DEST_DIR=$(git rev-parse --show-toplevel)/src/third_party/librdkafka
DIST_DIR=$DEST_DIR/dist DIST_DIR=$DEST_DIR/dist
PLATFORM_DIR=$DIST_DIR/platform PLATFORM_DIR=$DIST_DIR/platform
VERSION="2.0.2"
# Clean the output directories # Clean the output directories
rm -rf $DIST_DIR rm -rf $DIST_DIR
@ -27,7 +28,7 @@ rm -rf $TEMP_DIR/*
pushd $TEMP_DIR pushd $TEMP_DIR
# Clone the v2.0.2 branch of librdkafka. # Clone the v2.0.2 branch of librdkafka.
git clone --depth 1 --branch v2.0.2 https://github.com/confluentinc/librdkafka.git git clone --depth 1 --branch v$VERSION https://github.com/confluentinc/librdkafka.git
pushd librdkafka pushd librdkafka

View File

@ -25,7 +25,7 @@ $component_links
## WiredTiger Vendored Test Libraries ## WiredTiger Vendored Test Libraries
The following Python libraries are transitively included by WiredTiger, The following libraries are transitively included by WiredTiger,
and are used by that component for testing. They don't appear in and are used by that component for testing. They don't appear in
released binary artifacts. released binary artifacts.

View File

@ -65,22 +65,29 @@ def sbom_to_component_chart(sbom: dict) -> list[list[str]]:
name = component["name"] name = component["name"]
license_string = [] license_string = []
for lic in component["licenses"]: for lic in component["licenses"]:
for key in ["id", "name"]: if "license" in lic:
if key in lic["license"]: for key in ["id", "name"]:
license_string.append(lic["license"][key]) if key in lic["license"]:
license_string.append(lic["license"][key])
elif "expression" in lic:
license_string.append(lic["expression"])
license_string = ", ".join(license_string) license_string = ", ".join(license_string)
version = component["version"] version = component["version"]
emits_persisted_data = "unknown" if component["scope"] == "excluded":
for prop in component["properties"]: emits_persisted_data = ""
k, v = prop["name"], prop["value"] else:
if k == "emits_persisted_data": emits_persisted_data = "unknown"
emits_persisted_data = ("", "")[v == "true"] if "properties" in component:
for prop in component["properties"]:
k, v = prop["name"], prop["value"]
if k == "emits_persisted_data":
emits_persisted_data = ("", "")[v == "true"]
distributed_in_release_binaries = ("", "")[component["scope"] == "required"] distributed_in_release_binaries = ("", "")[component["scope"] == "required"]
row = [ row = [
item.replace("|", "") item.replace("|", "")
for item in [ for item in [
f"[{name}]", f"[{name}]".strip(),
license_string, license_string,
version, version,
emits_persisted_data, emits_persisted_data,
@ -123,7 +130,7 @@ def sbom_to_wiredtiger_chart(sbom: dict) -> list[list[str]]:
locations = get_component_locations(component) locations = get_component_locations(component)
for location in locations: for location in locations:
if location.startswith("src/third_party/wiredtiger/"): if location.startswith("src/third_party/wiredtiger/"):
bisect.insort(wiredtiger_chart, [component["name"].replace("|", "")]) bisect.insort(wiredtiger_chart, ([component["name"].replace("|", "")+"@"+component["version"]]))
return wiredtiger_chart return wiredtiger_chart
@ -139,19 +146,22 @@ def check_component_validity(component) -> None:
def get_component_info_link(component) -> str: def get_component_info_link(component) -> str:
name = component["name"] name = component["name"]
links = [] links = []
for prop in component["properties"]: if "properties" in component:
k, v = prop["name"], prop["value"] for prop in component["properties"]:
if k == "info_link": k, v = prop["name"], prop["value"]
links.append(v) if k == "info_link":
if len(links) != 1: links.append(v)
logging.warning("Warning: Expected 1 info_link for %s. Got %d:", name, len(links)) if len(links) != 1:
if len(links) > 1: logging.warning("Warning: Expected 1 info_link for %s. Got %d:", name, len(links))
logging.warning(" ".join(links)) if len(links) > 1:
logging.warning("Using first link only.") logging.warning(" ".join(links))
else: logging.warning("Using first link only.")
logging.warning("Falling back to `purl` value: %s", component["purl"]) else:
links.append(component["purl"]) logging.warning("Falling back to `purl` value: %s", component["purl"])
return links[0] links.append(component["purl"])
return links[0]
else:
return ""
def get_component_locations(component) -> list[str]: def get_component_locations(component) -> list[str]: