diff --git a/cmake/3rdparty_info.cmake b/cmake/3rdparty_info.cmake new file mode 100644 index 00000000000..4de1fd20380 --- /dev/null +++ b/cmake/3rdparty_info.cmake @@ -0,0 +1,37 @@ +# This file is used for SBOM generation. + +# It consists of the list of 3rd party products +# which can be compiled together with MariaDB server +# and their licenses, copyright notices, and CPE prefixes +# this is the vendor:product part of CPE identifier from +# https://nvd.nist.gov/products/cpe + +# We use both git submodules, and CMake external projects +# dependencies (as well we zlib, which is part of the code) +# so the information is here for all these types + +SET("zlib.license" "Zlib") +SET("zlib.copyright" "Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler") +SET("zlib.cpe-prefix" "zlib:zlib") +SET("minizip.license" "Zlib") +SET("minizip.copyright" "Copyright (C) 1995-2024 Jean-loup Gailly and Mark Adler") +SET("minizip.cpe-prefix" "zlib:zlib") +SET("fmt.license" "MIT") +SET("fmt.copyright" "Copyright (C) 2012 - present, Victor Zverovich") +SET("fmt.cpe-prefix" "fmt:fmt") +SET("pcre2.license" "BSD-3-Clause") +SET("pcre2.cpe-prefix" "pcre:pcre2") +SET("wolfssl.license" "GPL-2.0") +SET("wolfssl.copyright" "Copyright (C) 2006-2024 wolfSSL Inc.") +SET("wolfssl.cpe-prefix" "wolfssl:wolfssl") +SET("boost.license" "BSL-1.0") +SET("boost.cpe-prefix" "boost:boost") +SET("mariadb-connector-c.license" "LGPL-2.1") +SET("mariadb-connector-c.cpe-prefix" "mariadb:connector\\\\/c") +SET("rocksdb.license" "GPL-2.0") +SET("wsrep-lib.license" "GPL-2.0") +SET("wsrep-api.license" "GPL-2.0") +SET("mariadb-columnstore-engine.license" "GPL-2.0") +SET("libmarias3.license" "LGPL-2.1") +SET("thrift.license" "Apache-2.0") +SET("thrift.cpe-prefix" "apache:thrift") diff --git a/cmake/generate_sbom.cmake b/cmake/generate_sbom.cmake index e00a5c9b3a2..a0fbc99756e 100644 --- a/cmake/generate_sbom.cmake +++ b/cmake/generate_sbom.cmake @@ -36,30 +36,23 @@ ENDMACRO() # Get CPE ID ( https://en.wikipedia.org/wiki/Common_Platform_Enumeration ) # for given project name and version -# Only "known" CPEs are handled here, e.g currently no CPE for rocksdb +# CPE prefix are stored with other auxilliary info in the 3rdparty_info.cmake +# file FUNCTION(SBOM_GET_CPE name version var) - SET(cpe_prefix_map - "zlib" "zlib:zlib" - "mariadb-connector-c" "mariadb:connector\\\\/c" - "wolfssl" "wolfssl:wolfssl" - "minizip" "zlib:zlib" - "pcre2" "pcre:pcre2" - "fmt" "fmt:fmt" - "boost" "boost:boost" - "thrift" "apache:thrift" - ) - LIST(FIND cpe_prefix_map "${name}" idx_cpe_mapping) - # Version needs to have at least one dot character in it. - # Otherwise, we assume it is a git hash, and do not generate CPE - STRING(FIND "${version}" "." idx_version_dot) - IF((idx_cpe_mapping GREATER -1) AND (idx_version_dot GREATER -1)) - MATH(EXPR next_idx "${idx_cpe_mapping}+1") - LIST(GET cpe_prefix_map ${next_idx} cpe_name_and_vendor) - STRING(REGEX REPLACE "[^0-9\\.]" "" cleaned_version "${version}") - SET(${var} "cpe:2.3:a:${cpe_name_and_vendor}:${cleaned_version}:*:*:*:*:*:*:*" PARENT_SCOPE) - ELSE() - SET(${var} "" PARENT_SCOPE) + SET(${var} "" PARENT_SCOPE) + STRING(FIND "${version}" "." dot_idx) + IF(${dot_idx} EQUAL -1) + # Version does not have dot inside. + # mostly likely it is just a git hash + RETURN() ENDIF() + SET(cpe_name_and_vendor "${${repo_name_lower}.cpe-prefix}") + IF(NOT cpe_name_and_vendor) + RETURN() + ENDIF() + + STRING(REGEX REPLACE "[^0-9\\.]" "" cleaned_version "${version}") + SET(${var} "cpe:2.3:a:${cpe_name_and_vendor}:${cleaned_version}:*:*:*:*:*:*:*" PARENT_SCOPE) ENDFUNCTION() # Add dependency on CMake ExternalProject. @@ -97,8 +90,8 @@ ENDMACRO() # Perhaps it can always be "MariaDB", but security team recommendation is different # more towards "author" FUNCTION (sbom_get_supplier repo_name repo_user varname) - IF("${repo_name_SUPPLIER}") - SET(${varname} "${repo_name_SUPPLIER}" PARENT_SCOPE) + IF("${${repo_name}_SUPPLIER}") + SET(${varname} "${${repo_name}_SUPPLIER}" PARENT_SCOPE) ELSEIF (repo_name MATCHES "zlib|minizip") # stuff that is checked into out repos SET(${varname} "MariaDB" PARENT_SCOPE) @@ -230,6 +223,7 @@ FUNCTION(GENERATE_SBOM) \"ref\": \"${CPACK_PACKAGE_NAME}\", \"dependsOn\": [" ) + INCLUDE(3rdparty_info) SET(first ON) FOREACH(dep ${ALL_THIRD_PARTY}) # Extract the part after the last "/" from URL @@ -277,6 +271,14 @@ FUNCTION(GENERATE_SBOM) IF(cpe) SET(cpe "\n \"cpe\": \"${cpe}\",") ENDIF() + SET(license "${${repo_name_lower}.license}") + IF(NOT license) + MESSAGE(FATAL_ERROR "no license for 3rd party dependency ${repo_name_lower}.") + ENDIF() + SET(copyright "${${repo_name_lower}.copyright}") + IF(NOT copyright) + SET(copyright NOASSERTION) + ENDIF() STRING(APPEND sbom_components " { \"bom-ref\": \"${bom_ref}\", @@ -286,7 +288,15 @@ FUNCTION(GENERATE_SBOM) \"purl\": \"${purl}\",${cpe} \"supplier\": { \"name\": \"${supplier}\" - } + }, + \"licenses\": [ + { + \"license\": { + \"id\": \"${license}\" + } + } + ], + \"copyright\": \"${copyright}\" }") STRING(APPEND sbom_dependencies " \"${bom_ref}\"") @@ -302,5 +312,6 @@ FUNCTION(GENERATE_SBOM) IF(NOT DEFINED CPACK_PACKAGE_VERSION) SET(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") ENDIF() + STRING(TIMESTAMP CURRENT_YEAR "%Y") configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/sbom.json.in ${CMAKE_BINARY_DIR}/sbom.json) ENDFUNCTION() diff --git a/cmake/sbom.json.in b/cmake/sbom.json.in index c596915c452..71545b85f7f 100644 --- a/cmake/sbom.json.in +++ b/cmake/sbom.json.in @@ -20,7 +20,15 @@ ] }, "purl": "pkg:github/@GITHUB_REPO_USER@/@GITHUB_REPO_NAME@@@GIT_REV_SHORT@", - "cpe": "cpe:2.3:a:mariadb:mariadb:@CPACK_PACKAGE_VERSION@:*:*:*:*:*:*" + "cpe": "cpe:2.3:a:mariadb:mariadb:@CPACK_PACKAGE_VERSION@:*:*:*:*:*:*", + "licenses": [ + { + "license": { + "id": "GPL-2.0" + } + } + ], + "copyright": "Copyright (C) @CURRENT_YEAR@ MariaDB plc, MariaDB Foundation and others" }, "authors": [ {