Revert "GP-1782: Software Bill of Materials (SBOM)"

This reverts commit c89f45d399.
This commit is contained in:
Ryan Kurtz 2022-03-23 12:33:02 -04:00
parent 51efbf877f
commit 8598f28b23
7 changed files with 32 additions and 157 deletions

View File

@ -60,10 +60,10 @@ dependencies {
// at the top of ghidra.file.formats.sevenzip.SevenZipCustomInitializer.
// This gradle task can be removed when SevenZipCustomInitializer is no longer needed.
String getSevenZipJarPath() {
def libs = getExternalRuntimeDependencies(project);
for (String path : libs.keySet()) {
if (path.contains("sevenzipjbinding-all-platforms")) {
return path;
List<String> libs = getExternalRuntimeDependencies(project);
for(String lib: libs) {
if (lib.contains("sevenzipjbinding-all-platforms")) {
return lib;
}
}
return null

View File

@ -296,10 +296,6 @@ is complete.</p>
<td valign="top"><b>licenses</b></td>
<td valign="top">Contains licenses used by Ghidra.</td>
</tr>
<tr>
<td valign="top"><b>bom.json</b></td>
<td valign="top">Software Bill of Materials (SBOM) in CycloneDX JSON format.</td>
</tr>
</table>
<p>(<a href="#top">Back to Top</a>)</p>

View File

@ -196,28 +196,28 @@ def getCurrentDateTimeLong() {
}
/*********************************************************************************
* Returns a map of all the external library paths declared as dependencies for the
* given project, mapped to their respective ExternalDependency objects.
* Returns a list of all the external library paths declared as dependencies for the
* given project
*
*********************************************************************************/
Map<String, ExternalDependency> getExternalRuntimeDependencies(Project project) {
def map = [:]
List<String> getExternalRuntimeDependencies(Project project) {
List<String> list = new ArrayList<String>()
if (project.configurations.find { it.name == 'api' }) {
map.putAll(getExternalRuntimeDependencies(project, project.configurations.api));
list.addAll(getExternalRuntimeDependencies(project, project.configurations.api));
}
if (project.configurations.find { it.name == 'implementation' }) {
map.putAll(getExternalRuntimeDependencies(project, project.configurations.implementation));
list.addAll(getExternalRuntimeDependencies(project, project.configurations.implementation));
}
if (project.configurations.find { it.name == 'runtimeOnly' }) {
map.putAll(getExternalRuntimeDependencies(project, project.configurations.runtimeOnly));
list.addAll(getExternalRuntimeDependencies(project, project.configurations.runtimeOnly));
}
return map
return list
}
Map<String, ExternalDependency> getExternalRuntimeDependencies(Project project, Configuration configuration) {
def map = [:]
List<String> getExternalRuntimeDependencies(Project project, Configuration configuration) {
List<String> list = new ArrayList<>();
configuration.dependencies.each { dep ->
// if the dependency is an external jar
@ -248,11 +248,11 @@ Map<String, ExternalDependency> getExternalRuntimeDependencies(Project project,
}
// if we found the path, then add it to the list
if (depPath) {
map.put(depPath, dep)
list.add(depPath)
}
}
}
return map;
return list;
}
@ -275,10 +275,10 @@ String generateLibraryDependencyMapping() {
libsFile.withWriter { out ->
subprojects { p ->
p.plugins.withType(JavaPlugin) {
def libs = getExternalRuntimeDependencies(p);
List<String> libs = getExternalRuntimeDependencies(p);
if (libs != null) {
out.println "Module: $p.name"
libs.each { path, dep ->
libs.each { path ->
out.println "\t$path"
}
}
@ -288,81 +288,5 @@ String generateLibraryDependencyMapping() {
return libsFile.absolutePath
}
/******************************************************************************************
*
* Generates a hash of the given file with the given hash algorithm.
*
******************************************************************************************/
import java.security.DigestInputStream
import java.security.MessageDigest
String generateHash(File file, String alg) {
file.withInputStream {
new DigestInputStream(it, MessageDigest.getInstance(alg)).withStream {
it.eachByte {}
it.messageDigest.digest().encodeHex() as String
}
}
}
/******************************************************************************************
*
* Creates a CycloneDX Software Bill of Materials (SBOM) for the given project and
* returns it as a map.
*
******************************************************************************************/
def generateSoftwareBillOfMaterials(Project p) {
// Get license info from the Module.manifest file (if it exists)
def licenses = [:]
def manifestFile = file("${p.projectDir}/Module.manifest")
if (manifestFile.exists()) {
manifestFile.readLines().each { line ->
line = line.trim()
if (line.startsWith("MODULE FILE LICENSE:")) {
// Expected line: "MODULE FILE LICENSE: relative_path/to/jar License Type"
def value = line.substring("MODULE FILE LICENSE:".length()).trim()
def libAndLicense = value.split(" ", 2)
if (libAndLicense.size() != 2) {
throw new GradleException("Error parsing " + manifestFile + ":\n\t" + line)
}
def libPath = libAndLicense[0].trim()
def libName = libPath.substring(libPath.lastIndexOf("/") + 1)
def license = libAndLicense[1].trim()
licenses[libName] = license
}
}
}
// SBOM header
def sbom = ["bomFormat" : "CycloneDX", "specVersion" : "1.4", "version" : 1]
// SBOM components
sbom.components = []
getExternalRuntimeDependencies(p).each { path, dep ->
def f = file(path)
def component = [:]
component.type = "library"
component.group = dep.group ?: ""
component.name = dep.name
component.version = dep.version ?: ""
component.properties = [["ghidra-module" : p.name]]
if (dep.group && dep.version) {
component.purl = "pkg:maven/${dep.group}/${dep.name}@${dep.version}"
}
component.hashes = []
["MD5", "SHA-1"].each { alg ->
component.hashes << ["alg" : alg, "content" : generateHash(f, alg)]
}
def license = licenses[f.name]
if (license) {
component.licenses = [["license" : ["name" : license]]]
}
sbom.components << component
}
return sbom
}
task allSleighCompile {
}

View File

@ -188,8 +188,8 @@ plugins.withType(JavaPlugin) {
// External Libraries
gradle.taskGraph.whenReady { taskGraph ->
def libs = getExternalRuntimeDependencies(p)
libs.each { path, dep ->
List<String> externalPaths = getExternalRuntimeDependencies(p)
externalPaths.each { path ->
from (path) {
into {zipPath + "/lib" }
}

View File

@ -226,43 +226,7 @@ task zipJavadocs(type: Zip) {
description "Zips javadocs for Ghidra api. [gradle/root/distribution.gradle]"
}
/******************************************************************************************
* TASK generateSoftwareBillOfMaterials
*
* Summary: Creates a file that lists the libraries used by each module.
******************************************************************************************/
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
task generateSoftwareBillOfMaterials {
doFirst {
// Create an SBOM map for each project.
// TODO: Write each SBOM to its project directory and use it as a replacement for
// the Module.manifest.
def projectSboms = []
subprojects { p ->
p.plugins.withType(JavaPlugin) {
projectSboms << generateSoftwareBillOfMaterials(p)
}
}
// Generate aggregated SBOM file for all of Ghidra
def sbom = ["bomFormat" : "CycloneDX", "specVersion" : "1.4", "version" : 1]
sbom.components = []
projectSboms.each { projectSbom ->
sbom.components += projectSbom.components
}
// Write SBOM to JSON file
def buildDir = file("$buildDir")
if (!buildDir.exists()) {
buildDir.mkdirs()
}
def sbomFile = file("$buildDir/bom.json")
sbomFile.write(JsonOutput.prettyPrint(JsonOutput.toJson(sbom)))
}
}
/**********************************************************************************************
*
@ -276,8 +240,6 @@ task assembleDistribution (type: Copy) {
// every other time it is run even though in both cases the output directory has been removed
outputs.upToDateWhen {false}
dependsOn generateSoftwareBillOfMaterials
group 'private'
description "Copies core files/folders to the distribution location."
destinationDir file(DISTRIBUTION_DIR.getPath() + "/" + ZIP_DIR_PREFIX)
@ -397,13 +359,6 @@ task assembleDistribution (type: Copy) {
into "Ghidra"
}
/////////////////////////////////////
// Software Bill of Materials (SBOM)
/////////////////////////////////////
from (ROOT_PROJECT_DIR + "/build") {
include "bom.json"
}
}
/*********************************************************************************
@ -473,13 +428,6 @@ task createExternalExtensions(type: Copy) {
}
/*********************************************************************************
* Update sla file timestamps to current time plus timeOffsetMinutes value.
*
* distributionDirectoryPath - Contains files/folders used by gradle zip task.
* timeOffsetMinutes - Number of minutes to increase sla file timestamp.
*
**********************************************************************************/
import groovy.io.FileType
import java.nio.file.Path
import java.nio.file.Files
@ -488,6 +436,13 @@ import java.time.OffsetDateTime
import java.util.concurrent.TimeUnit
import java.time.ZoneId
/*********************************************************************************
* Update sla file timestamps to current time plus timeOffsetMinutes value.
*
* distributionDirectoryPath - Contains files/folders used by gradle zip task.
* timeOffsetMinutes - Number of minutes to increase sla file timestamp.
*
**********************************************************************************/
def updateSlaFilesTimestamp(String distributionDirectoryPath, int timeOffsetMinutes) {
logger.debug("updateSlaFilesTimestamp: distributionDirectoryPath = '$distributionDirectoryPath' and timeOffsetMinutes = '$timeOffsetMinutes',")

View File

@ -76,8 +76,8 @@ task zipExtensions (type: Zip) {
/////////////////
gradle.taskGraph.whenReady { taskGraph ->
if (project.plugins.withType(JavaPlugin)) {
def libs = getExternalRuntimeDependencies(p)
libs.each { path, dep ->
List<String> externalPaths = getExternalRuntimeDependencies(p)
externalPaths.each { path ->
from (path) {
into { getBaseProjectName(p) + "/lib" }
}

View File

@ -96,9 +96,9 @@ def Map<String, String> getModuleManifestIp(Project project) {
*********************************************************************************/
def checkExternalLibsInMap(Map<String, String> map, Project project) {
if (project.plugins.withType(JavaPlugin)) {
def libs = getExternalRuntimeDependencies(project)
libs.each { path, dep ->
String libName = new File(path).getName() // get just the filename without the path
List<String> libs = getExternalRuntimeDependencies(project)
libs.each { lib ->
String libName = new File(lib).getName() // get just the filename without the path
String relativePath = "lib/"+libName;
assert map.containsKey(relativePath) : "No License specified for external library: "+relativePath+ " in module "+project.projectDir
}