Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -75,24 +75,32 @@ public Content provideStack() throws IOException {
// create a temp file for storing the dependency tree in
var tmpFile = Files.createTempFile("TRUSTIFY_DA_dot_graph_", null);
// the tree command will build the project and create the dependency tree in the temp file
var mvnTreeCmd =
buildMvnCommandArgs(
"org.apache.maven.plugins:maven-dependency-plugin:3.6.0:tree",
"-Dverbose",
"-DoutputType=text",
String.format("-DoutputFile=%s", tmpFile.toString()),
"-f",
manifest.toString(),
"--batch-mode",
"-q");
var mvnTreeCmdArgs =
new ArrayList<>(
List.of(
"org.apache.maven.plugins:maven-dependency-plugin:3.6.0:tree",
"-Dscope=compile",
"-Dverbose",
"-DoutputType=text",
String.format("-DoutputFile=%s", tmpFile.toString()),
"-f",
manifest.toString(),
"--batch-mode",
"-q"));
// if we have dependencies marked as ignored, exclude them from the tree command
var ignored =
getDependencies(manifest).stream()
.filter(d -> d.ignored)
.map(DependencyAggregator::toPurl)
.map(DependencyAggregator::toPurlWithoutVersion)
.map(PackageURL::getCoordinates)
.collect(Collectors.toList());

if (!ignored.isEmpty()) {
mvnTreeCmdArgs.add("-Dexcludes=" + String.join(",", ignored));
}

// execute the tree command
var mvnTreeCmd = buildMvnCommandArgs(mvnTreeCmdArgs.toArray(String[]::new));
Operations.runProcess(manifest.getParent(), mvnTreeCmd.toArray(String[]::new), mvnEnvs);
if (debugLoggingIsNeeded()) {
String stackAnalysisDependencyTree = Files.readString(tmpFile);
Expand All @@ -110,6 +118,7 @@ public Content provideStack() throws IOException {

private Sbom buildSbomFromTextFormat(Path textFormatFile) throws IOException {
var sbom = SbomFactory.newInstance(Sbom.BelongingCondition.PURL, "sensitive");
sbom.setCoordinateBasedMatching();
List<String> lines = Files.readAllLines(textFormatFile);
var root = lines.get(0);
var rootPurl = parseDep(root);
Expand Down Expand Up @@ -408,6 +417,15 @@ public PackageURL toPurl() {
}
}

/** Creates a PackageURL without version for coordinate-based matching. */
public PackageURL toPurlWithoutVersion() {
try {
return new PackageURL(Type.MAVEN.getType(), groupId, artifactId, null, null, null);
} catch (MalformedPackageURLException e) {
throw new IllegalArgumentException("Unable to parse PackageURL", e);
}
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/io/github/guacsec/trustifyda/sbom/CycloneDXSbom.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,31 @@ private BiPredicate<Collection<?>, Component> getBelongingConditionByPurl() {
collection.contains(componentToPurl(component).getCoordinates());
}

/**
* Creates a coordinate-based belonging condition that matches by groupId:artifactId only,
* ignoring version. Used for handling dependencies with unresolved version properties.
*/
private BiPredicate<Collection<?>, Component> getBelongingConditionByCoordinatesOnly() {
return (collection, component) -> {
PackageURL componentPurl = componentToPurl(component);
String componentCoords = componentPurl.getNamespace() + ":" + componentPurl.getName();

return collection.stream()
.filter(String.class::isInstance)
.map(String.class::cast)
.anyMatch(
ignoredPurlCoords -> {
try {
PackageURL ignoredPurl = new PackageURL(ignoredPurlCoords);
String ignoredCoords = ignoredPurl.getNamespace() + ":" + ignoredPurl.getName();
return componentCoords.equals(ignoredCoords);
} catch (MalformedPackageURLException e) {
return false;
}
});
};
}

public Sbom addRoot(PackageURL rootRef) {
this.root = rootRef;
Component rootComponent = newRootComponent(rootRef);
Expand Down Expand Up @@ -280,6 +305,11 @@ public void setBelongingCriteriaBinaryAlgorithm(BelongingCondition belongingCond
}
}

@Override
public void setCoordinateBasedMatching() {
belongingCriteriaBinaryAlgorithm = getBelongingConditionByCoordinatesOnly();
}

@Override
public boolean checkIfPackageInsideDependsOnList(PackageURL component, String name) {
boolean result = false;
Expand Down
2 changes: 2 additions & 0 deletions src/main/java/io/github/guacsec/trustifyda/sbom/Sbom.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public interface Sbom {

public void setBelongingCriteriaBinaryAlgorithm(BelongingCondition belongingCondition);

public void setCoordinateBasedMatching();

public boolean checkIfPackageInsideDependsOnList(PackageURL component, String name);

void removeRootComponent();
Expand Down
Loading