mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-02-16 07:30:16 +00:00
Revert "GP-1782: Software Bill of Materials (SBOM)"
This reverts commit c89f45d399
.
This commit is contained in:
parent
51efbf877f
commit
8598f28b23
@ -60,10 +60,10 @@ dependencies {
|
|||||||
// at the top of ghidra.file.formats.sevenzip.SevenZipCustomInitializer.
|
// at the top of ghidra.file.formats.sevenzip.SevenZipCustomInitializer.
|
||||||
// This gradle task can be removed when SevenZipCustomInitializer is no longer needed.
|
// This gradle task can be removed when SevenZipCustomInitializer is no longer needed.
|
||||||
String getSevenZipJarPath() {
|
String getSevenZipJarPath() {
|
||||||
def libs = getExternalRuntimeDependencies(project);
|
List<String> libs = getExternalRuntimeDependencies(project);
|
||||||
for (String path : libs.keySet()) {
|
for(String lib: libs) {
|
||||||
if (path.contains("sevenzipjbinding-all-platforms")) {
|
if (lib.contains("sevenzipjbinding-all-platforms")) {
|
||||||
return path;
|
return lib;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
@ -296,10 +296,6 @@ is complete.</p>
|
|||||||
<td valign="top"><b>licenses</b></td>
|
<td valign="top"><b>licenses</b></td>
|
||||||
<td valign="top">Contains licenses used by Ghidra.</td>
|
<td valign="top">Contains licenses used by Ghidra.</td>
|
||||||
</tr>
|
</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>
|
</table>
|
||||||
<p>(<a href="#top">Back to Top</a>)</p>
|
<p>(<a href="#top">Back to Top</a>)</p>
|
||||||
|
|
||||||
|
104
build.gradle
104
build.gradle
@ -196,28 +196,28 @@ def getCurrentDateTimeLong() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************************
|
/*********************************************************************************
|
||||||
* Returns a map of all the external library paths declared as dependencies for the
|
* Returns a list of all the external library paths declared as dependencies for the
|
||||||
* given project, mapped to their respective ExternalDependency objects.
|
* given project
|
||||||
*
|
*
|
||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
Map<String, ExternalDependency> getExternalRuntimeDependencies(Project project) {
|
List<String> getExternalRuntimeDependencies(Project project) {
|
||||||
def map = [:]
|
List<String> list = new ArrayList<String>()
|
||||||
|
|
||||||
if (project.configurations.find { it.name == 'api' }) {
|
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' }) {
|
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' }) {
|
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) {
|
List<String> getExternalRuntimeDependencies(Project project, Configuration configuration) {
|
||||||
def map = [:]
|
List<String> list = new ArrayList<>();
|
||||||
configuration.dependencies.each { dep ->
|
configuration.dependencies.each { dep ->
|
||||||
|
|
||||||
// if the dependency is an external jar
|
// 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 we found the path, then add it to the list
|
||||||
if (depPath) {
|
if (depPath) {
|
||||||
map.put(depPath, dep)
|
list.add(depPath)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return map;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -275,10 +275,10 @@ String generateLibraryDependencyMapping() {
|
|||||||
libsFile.withWriter { out ->
|
libsFile.withWriter { out ->
|
||||||
subprojects { p ->
|
subprojects { p ->
|
||||||
p.plugins.withType(JavaPlugin) {
|
p.plugins.withType(JavaPlugin) {
|
||||||
def libs = getExternalRuntimeDependencies(p);
|
List<String> libs = getExternalRuntimeDependencies(p);
|
||||||
if (libs != null) {
|
if (libs != null) {
|
||||||
out.println "Module: $p.name"
|
out.println "Module: $p.name"
|
||||||
libs.each { path, dep ->
|
libs.each { path ->
|
||||||
out.println "\t$path"
|
out.println "\t$path"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -288,81 +288,5 @@ String generateLibraryDependencyMapping() {
|
|||||||
return libsFile.absolutePath
|
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 {
|
task allSleighCompile {
|
||||||
}
|
}
|
||||||
|
@ -188,8 +188,8 @@ plugins.withType(JavaPlugin) {
|
|||||||
|
|
||||||
// External Libraries
|
// External Libraries
|
||||||
gradle.taskGraph.whenReady { taskGraph ->
|
gradle.taskGraph.whenReady { taskGraph ->
|
||||||
def libs = getExternalRuntimeDependencies(p)
|
List<String> externalPaths = getExternalRuntimeDependencies(p)
|
||||||
libs.each { path, dep ->
|
externalPaths.each { path ->
|
||||||
from (path) {
|
from (path) {
|
||||||
into {zipPath + "/lib" }
|
into {zipPath + "/lib" }
|
||||||
}
|
}
|
||||||
|
@ -226,43 +226,7 @@ task zipJavadocs(type: Zip) {
|
|||||||
description "Zips javadocs for Ghidra api. [gradle/root/distribution.gradle]"
|
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)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**********************************************************************************************
|
/**********************************************************************************************
|
||||||
*
|
*
|
||||||
@ -275,8 +239,6 @@ task assembleDistribution (type: Copy) {
|
|||||||
// Not sure why this is necessary, but without it, gradle thinks this task is "up to date"
|
// Not sure why this is necessary, but without it, gradle thinks this task is "up to date"
|
||||||
// every other time it is run even though in both cases the output directory has been removed
|
// every other time it is run even though in both cases the output directory has been removed
|
||||||
outputs.upToDateWhen {false}
|
outputs.upToDateWhen {false}
|
||||||
|
|
||||||
dependsOn generateSoftwareBillOfMaterials
|
|
||||||
|
|
||||||
group 'private'
|
group 'private'
|
||||||
description "Copies core files/folders to the distribution location."
|
description "Copies core files/folders to the distribution location."
|
||||||
@ -396,13 +358,6 @@ task assembleDistribution (type: Copy) {
|
|||||||
include "settings.gradle"
|
include "settings.gradle"
|
||||||
into "Ghidra"
|
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 groovy.io.FileType
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
@ -488,6 +436,13 @@ import java.time.OffsetDateTime
|
|||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.time.ZoneId
|
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) {
|
def updateSlaFilesTimestamp(String distributionDirectoryPath, int timeOffsetMinutes) {
|
||||||
logger.debug("updateSlaFilesTimestamp: distributionDirectoryPath = '$distributionDirectoryPath' and timeOffsetMinutes = '$timeOffsetMinutes',")
|
logger.debug("updateSlaFilesTimestamp: distributionDirectoryPath = '$distributionDirectoryPath' and timeOffsetMinutes = '$timeOffsetMinutes',")
|
||||||
|
|
||||||
|
@ -76,8 +76,8 @@ task zipExtensions (type: Zip) {
|
|||||||
/////////////////
|
/////////////////
|
||||||
gradle.taskGraph.whenReady { taskGraph ->
|
gradle.taskGraph.whenReady { taskGraph ->
|
||||||
if (project.plugins.withType(JavaPlugin)) {
|
if (project.plugins.withType(JavaPlugin)) {
|
||||||
def libs = getExternalRuntimeDependencies(p)
|
List<String> externalPaths = getExternalRuntimeDependencies(p)
|
||||||
libs.each { path, dep ->
|
externalPaths.each { path ->
|
||||||
from (path) {
|
from (path) {
|
||||||
into { getBaseProjectName(p) + "/lib" }
|
into { getBaseProjectName(p) + "/lib" }
|
||||||
}
|
}
|
||||||
|
@ -96,9 +96,9 @@ def Map<String, String> getModuleManifestIp(Project project) {
|
|||||||
*********************************************************************************/
|
*********************************************************************************/
|
||||||
def checkExternalLibsInMap(Map<String, String> map, Project project) {
|
def checkExternalLibsInMap(Map<String, String> map, Project project) {
|
||||||
if (project.plugins.withType(JavaPlugin)) {
|
if (project.plugins.withType(JavaPlugin)) {
|
||||||
def libs = getExternalRuntimeDependencies(project)
|
List<String> libs = getExternalRuntimeDependencies(project)
|
||||||
libs.each { path, dep ->
|
libs.each { lib ->
|
||||||
String libName = new File(path).getName() // get just the filename without the path
|
String libName = new File(lib).getName() // get just the filename without the path
|
||||||
String relativePath = "lib/"+libName;
|
String relativePath = "lib/"+libName;
|
||||||
assert map.containsKey(relativePath) : "No License specified for external library: "+relativePath+ " in module "+project.projectDir
|
assert map.containsKey(relativePath) : "No License specified for external library: "+relativePath+ " in module "+project.projectDir
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user