added attempt to resolve system scoped dependency with test cases

This commit is contained in:
Jeremy Long
2017-05-14 07:45:55 -04:00
parent 555b1dc1cc
commit e218b8ad70
10 changed files with 228 additions and 5 deletions

View File

@@ -0,0 +1,66 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2017 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.exception;
/**
* An exception used when a dependency could not be found.
*
* @author Jeremy Long
*/
public class DependencyNotFoundException extends Exception {
/**
* The serial version uid.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new DependencyNotFoundException.
*/
public DependencyNotFoundException() {
super();
}
/**
* Creates a new DependencyNotFoundException.
*
* @param msg a message for the exception.
*/
public DependencyNotFoundException(String msg) {
super(msg);
}
/**
* Creates a new DependencyNotFoundException.
*
* @param ex the cause of the exception.
*/
public DependencyNotFoundException(Throwable ex) {
super(ex);
}
/**
* Creates a new DependencyNotFoundException.
*
* @param msg a message for the exception.
* @param ex the cause of the exception.
*/
public DependencyNotFoundException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -0,0 +1,19 @@
#
# This file is part of dependency-check-maven.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Copyright (c) 2017 Jeremy Long. All Rights Reserved.
#
invoker.goals = install ${project.groupId}:${project.artifactId}:${project.version}:check -e -Dformat=JSON

View File

@@ -0,0 +1,30 @@
/*
* This file is part of dependency-check-maven.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2017 Jeremy Long. All Rights Reserved.
*/
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import java.nio.charset.Charset;
import groovy.json.JsonSlurper;
def slurper = new JsonSlurper()
def json = slurper.parse(new File(basedir, "target/dependency-check-report.json"), "UTF-8")
assert json instanceof Map
assert json.analysis.dependencies instanceof List
assert json.analysis.dependencies.size()==1
return true;

View File

@@ -0,0 +1,17 @@
/*
* This file is part of dependency-check-maven.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2017 Jeremy Long. All Rights Reserved.
*/

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
This file is part of dependency-check-maven.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Copyright (c) 2017 Jeremy Long. All Rights Reserved.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.owasp.test</groupId>
<artifactId>test-system-scope</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<scope>system</scope>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.8</version>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
</project>

View File

@@ -55,6 +55,7 @@ import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Identifier;
import org.owasp.dependencycheck.dependency.Vulnerability;
import org.owasp.dependencycheck.exception.DependencyNotFoundException;
import org.owasp.dependencycheck.exception.ExceptionCollection;
import org.owasp.dependencycheck.exception.ReportException;
import org.owasp.dependencycheck.reporting.ReportGenerator;
@@ -643,16 +644,45 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
}
exCol = collectDependencies(engine, project, dependencyNode.getChildren(), buildingRequest);
try {
final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact());
final Artifact result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact();
if (result.isResolved() && result.getFile() != null) {
final List<Dependency> deps = engine.scan(result.getFile().getAbsoluteFile(),
boolean isResolved = false;
File artifactFile = null;
String artifactId = null;
String groupId = null;
String version = null;
if (org.apache.maven.artifact.Artifact.SCOPE_SYSTEM.equals(dependencyNode.getArtifact().getScope())) {
for (org.apache.maven.model.Dependency d : project.getDependencies()) {
Artifact a = dependencyNode.getArtifact();
if (d.getSystemPath() != null && artifactsMatch(d, a)) {
artifactFile = new File(d.getSystemPath());
isResolved = artifactFile.isFile();
groupId = a.getGroupId();
artifactId = a.getArtifactId();
version = a.getVersion();
break;
}
}
if (!isResolved) {
getLog().error("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString());
exCol.addException(new DependencyNotFoundException("Unable to resolve system scoped dependency: " + dependencyNode.toNodeString()));
}
} else {
final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact());
final Artifact result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact();
isResolved = result.isResolved();
artifactFile = result.getFile();
groupId = result.getGroupId();
artifactId = result.getArtifactId();
version = result.getVersion();
}
if (isResolved && artifactFile != null) {
final List<Dependency> deps = engine.scan(artifactFile.getAbsoluteFile(),
project.getName() + ":" + dependencyNode.getArtifact().getScope());
if (deps != null) {
if (deps.size() == 1) {
final Dependency d = deps.get(0);
if (d != null) {
final MavenArtifact ma = new MavenArtifact(result.getGroupId(), result.getArtifactId(), result.getVersion());
final MavenArtifact ma = new MavenArtifact(groupId, artifactId, version);
d.addAsEvidence("pom", ma, Confidence.HIGHEST);
if (getLog().isDebugEnabled()) {
getLog().debug(String.format("Adding project reference %s on dependency %s",
@@ -690,6 +720,33 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
return exCol;
}
/**
* Determines if the groupId, artifactId, and version of the Maven
* dependency and artifact match.
*
* @param d the Maven dependency
* @param a the Maven artifact
* @return true if the groupId, artifactId, and version match
*/
private static boolean artifactsMatch(org.apache.maven.model.Dependency d, Artifact a) {
return (isEqualOrNull(a.getArtifactId(), d.getArtifactId()))
&& (isEqualOrNull(a.getGroupId(), d.getGroupId()))
&& (isEqualOrNull(a.getVersion(), d.getVersion()));
}
/**
* Compares two strings for equality; if both strings are null they are
* considered equal.
*
* @param left the first string to compare
* @param right the second string to compare
* @return true if the strings are equal or if they are both null; otherwise
* false.
*/
private static boolean isEqualOrNull(String left, String right) {
return (left != null && left.equals(right)) || (left == null && right == null);
}
/**
* @return Returns a new ProjectBuildingRequest populated from the current
* session and the current project remote repositories, used to resolve