mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-03-28 20:02:16 +01:00
updates to resolve issue #215
This commit is contained in:
@@ -32,9 +32,12 @@ import org.owasp.dependencycheck.Engine;
|
|||||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
||||||
|
import org.owasp.dependencycheck.data.update.exception.UpdateException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Identifier;
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
import org.owasp.dependencycheck.dependency.Vulnerability;
|
import org.owasp.dependencycheck.dependency.Vulnerability;
|
||||||
|
import org.owasp.dependencycheck.exception.ExceptionCollection;
|
||||||
|
import org.owasp.dependencycheck.exception.ReportException;
|
||||||
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
||||||
import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
|
import org.owasp.dependencycheck.reporting.ReportGenerator.Format;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
@@ -806,52 +809,67 @@ public class Check extends Update {
|
|||||||
engine = new Engine(Check.class.getClassLoader());
|
engine = new Engine(Check.class.getClassLoader());
|
||||||
if (isUpdateOnly()) {
|
if (isUpdateOnly()) {
|
||||||
log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN);
|
log("Deprecated 'UpdateOnly' property set; please use the UpdateTask instead", Project.MSG_WARN);
|
||||||
engine.doUpdates();
|
|
||||||
} else {
|
|
||||||
try {
|
try {
|
||||||
for (Resource resource : path) {
|
engine.doUpdates();
|
||||||
final FileProvider provider = resource.as(FileProvider.class);
|
} catch (UpdateException ex) {
|
||||||
if (provider != null) {
|
if (this.isFailOnError()) {
|
||||||
final File file = provider.getFile();
|
throw new BuildException(ex);
|
||||||
if (file != null && file.exists()) {
|
}
|
||||||
engine.scan(file);
|
log(ex.getMessage(), Project.MSG_ERR);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (Resource resource : path) {
|
||||||
|
final FileProvider provider = resource.as(FileProvider.class);
|
||||||
|
if (provider != null) {
|
||||||
|
final File file = provider.getFile();
|
||||||
|
if (file != null && file.exists()) {
|
||||||
|
engine.scan(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
engine.analyzeDependencies();
|
engine.analyzeDependencies();
|
||||||
DatabaseProperties prop = null;
|
} catch (ExceptionCollection ex) {
|
||||||
CveDB cve = null;
|
if (this.isFailOnError()) {
|
||||||
try {
|
throw new BuildException(ex);
|
||||||
cve = new CveDB();
|
|
||||||
cve.open();
|
|
||||||
prop = cve.getDatabaseProperties();
|
|
||||||
} catch (DatabaseException ex) {
|
|
||||||
log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG);
|
|
||||||
} finally {
|
|
||||||
if (cve != null) {
|
|
||||||
cve.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop);
|
}
|
||||||
reporter.generateReports(reportOutputDirectory, reportFormat);
|
DatabaseProperties prop = null;
|
||||||
|
CveDB cve = null;
|
||||||
|
try {
|
||||||
|
cve = new CveDB();
|
||||||
|
cve.open();
|
||||||
|
prop = cve.getDatabaseProperties();
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG);
|
||||||
|
} finally {
|
||||||
|
if (cve != null) {
|
||||||
|
cve.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop);
|
||||||
|
reporter.generateReports(reportOutputDirectory, reportFormat);
|
||||||
|
|
||||||
if (this.failBuildOnCVSS <= 10) {
|
if (this.failBuildOnCVSS <= 10) {
|
||||||
checkForFailure(engine.getDependencies());
|
checkForFailure(engine.getDependencies());
|
||||||
}
|
}
|
||||||
if (this.showSummary) {
|
if (this.showSummary) {
|
||||||
showSummary(engine.getDependencies());
|
showSummary(engine.getDependencies());
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
log("Unable to generate dependency-check report", ex, Project.MSG_DEBUG);
|
|
||||||
throw new BuildException("Unable to generate dependency-check report", ex);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
log("An exception occurred; unable to continue task", ex, Project.MSG_DEBUG);
|
|
||||||
throw new BuildException("An exception occurred; unable to continue task", ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (DatabaseException ex) {
|
} catch (DatabaseException ex) {
|
||||||
log("Unable to connect to the dependency-check database; analysis has stopped", ex, Project.MSG_ERR);
|
final String msg = "Unable to connect to the dependency-check database; analysis has stopped";
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new BuildException(msg, ex);
|
||||||
|
}
|
||||||
|
log(msg, ex, Project.MSG_ERR);
|
||||||
|
} catch (ReportException ex) {
|
||||||
|
final String msg = "Unable to generate the dependency-check report";
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new BuildException(msg, ex);
|
||||||
|
}
|
||||||
|
log(msg, ex, Project.MSG_ERR);
|
||||||
} finally {
|
} finally {
|
||||||
Settings.cleanup(true);
|
Settings.cleanup(true);
|
||||||
if (engine != null) {
|
if (engine != null) {
|
||||||
|
|||||||
@@ -71,6 +71,30 @@ public class Purge extends Task {
|
|||||||
this.dataDirectory = dataDirectory;
|
this.dataDirectory = dataDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if dependency-check should fail the build if an exception
|
||||||
|
* occurs.
|
||||||
|
*/
|
||||||
|
private boolean failOnError = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value of failOnError
|
||||||
|
*
|
||||||
|
* @return the value of failOnError
|
||||||
|
*/
|
||||||
|
public boolean isFailOnError() {
|
||||||
|
return failOnError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of failOnError
|
||||||
|
*
|
||||||
|
* @param failOnError new value of failOnError
|
||||||
|
*/
|
||||||
|
public void setFailOnError(boolean failOnError) {
|
||||||
|
this.failOnError = failOnError;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws BuildException {
|
public void execute() throws BuildException {
|
||||||
populateSettings();
|
populateSettings();
|
||||||
@@ -81,30 +105,49 @@ public class Purge extends Task {
|
|||||||
if (db.delete()) {
|
if (db.delete()) {
|
||||||
log("Database file purged; local copy of the NVD has been removed", Project.MSG_INFO);
|
log("Database file purged; local copy of the NVD has been removed", Project.MSG_INFO);
|
||||||
} else {
|
} else {
|
||||||
log(String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath()), Project.MSG_ERR);
|
final String msg = String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath());
|
||||||
|
if (this.failOnError) {
|
||||||
|
throw new BuildException(msg);
|
||||||
|
}
|
||||||
|
log(msg, Project.MSG_ERR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log(String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath()), Project.MSG_ERR);
|
final String msg = String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath());
|
||||||
|
if (this.failOnError) {
|
||||||
|
throw new BuildException(msg);
|
||||||
|
}
|
||||||
|
log(msg, Project.MSG_ERR);
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
log("Unable to delete the database", Project.MSG_ERR);
|
final String msg = "Unable to delete the database";
|
||||||
|
if (this.failOnError) {
|
||||||
|
throw new BuildException(msg);
|
||||||
|
}
|
||||||
|
log(msg, Project.MSG_ERR);
|
||||||
} finally {
|
} finally {
|
||||||
Settings.cleanup(true);
|
Settings.cleanup(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
|
* Takes the properties supplied and updates the dependency-check settings.
|
||||||
* required to change the proxy server, port, and connection timeout.
|
* Additionally, this sets the system properties required to change the
|
||||||
|
* proxy server, port, and connection timeout.
|
||||||
|
*
|
||||||
|
* @throws BuildException thrown if the properties file cannot be read.
|
||||||
*/
|
*/
|
||||||
protected void populateSettings() {
|
protected void populateSettings() throws BuildException {
|
||||||
Settings.initialize();
|
Settings.initialize();
|
||||||
InputStream taskProperties = null;
|
InputStream taskProperties = null;
|
||||||
try {
|
try {
|
||||||
taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
|
taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
|
||||||
Settings.mergeProperties(taskProperties);
|
Settings.mergeProperties(taskProperties);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
log("Unable to load the dependency-check ant task.properties file.", ex, Project.MSG_WARN);
|
final String msg = "Unable to load the dependency-check ant task.properties file.";
|
||||||
|
if (this.failOnError) {
|
||||||
|
throw new BuildException(msg, ex);
|
||||||
|
}
|
||||||
|
log(msg, ex, Project.MSG_WARN);
|
||||||
} finally {
|
} finally {
|
||||||
if (taskProperties != null) {
|
if (taskProperties != null) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -18,14 +18,17 @@
|
|||||||
package org.owasp.dependencycheck.taskdefs;
|
package org.owasp.dependencycheck.taskdefs;
|
||||||
|
|
||||||
import org.apache.tools.ant.BuildException;
|
import org.apache.tools.ant.BuildException;
|
||||||
|
import org.apache.tools.ant.Project;
|
||||||
import org.owasp.dependencycheck.Engine;
|
import org.owasp.dependencycheck.Engine;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
|
import org.owasp.dependencycheck.data.update.exception.UpdateException;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
import org.slf4j.impl.StaticLoggerBinder;
|
import org.slf4j.impl.StaticLoggerBinder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An Ant task definition to execute dependency-check update. This will download the latest data from the National Vulnerability
|
* An Ant task definition to execute dependency-check update. This will download
|
||||||
* Database (NVD) and store a copy in the local database.
|
* the latest data from the National Vulnerability Database (NVD) and store a
|
||||||
|
* copy in the local database.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
@@ -381,10 +384,11 @@ public class Update extends Purge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the update by initializing the settings, downloads the NVD XML data, and then processes the data storing it in the
|
* Executes the update by initializing the settings, downloads the NVD XML
|
||||||
* local database.
|
* data, and then processes the data storing it in the local database.
|
||||||
*
|
*
|
||||||
* @throws BuildException thrown if a connection to the local database cannot be made.
|
* @throws BuildException thrown if a connection to the local database
|
||||||
|
* cannot be made.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws BuildException {
|
public void execute() throws BuildException {
|
||||||
@@ -392,9 +396,20 @@ public class Update extends Purge {
|
|||||||
Engine engine = null;
|
Engine engine = null;
|
||||||
try {
|
try {
|
||||||
engine = new Engine(Update.class.getClassLoader());
|
engine = new Engine(Update.class.getClassLoader());
|
||||||
engine.doUpdates();
|
try {
|
||||||
|
engine.doUpdates();
|
||||||
|
} catch (UpdateException ex) {
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new BuildException(ex);
|
||||||
|
}
|
||||||
|
log(ex.getMessage(), Project.MSG_ERR);
|
||||||
|
}
|
||||||
} catch (DatabaseException ex) {
|
} catch (DatabaseException ex) {
|
||||||
throw new BuildException("Unable to connect to the dependency-check database; unable to update the NVD data", ex);
|
final String msg = "Unable to connect to the dependency-check database; unable to update the NVD data";
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new BuildException(msg, ex);
|
||||||
|
}
|
||||||
|
log(msg, Project.MSG_ERR);
|
||||||
} finally {
|
} finally {
|
||||||
Settings.cleanup(true);
|
Settings.cleanup(true);
|
||||||
if (engine != null) {
|
if (engine != null) {
|
||||||
@@ -404,8 +419,9 @@ public class Update extends Purge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
|
* Takes the properties supplied and updates the dependency-check settings.
|
||||||
* required to change the proxy server, port, and connection timeout.
|
* Additionally, this sets the system properties required to change the
|
||||||
|
* proxy server, port, and connection timeout.
|
||||||
*
|
*
|
||||||
* @throws BuildException thrown when an invalid setting is configured.
|
* @throws BuildException thrown when an invalid setting is configured.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Configuration: dependency-check-purge Task
|
|||||||
--------------------
|
--------------------
|
||||||
The following properties can be set on the dependency-check-purge task.
|
The following properties can be set on the dependency-check-purge task.
|
||||||
|
|
||||||
Property | Description | Default Value
|
Property | Description | Default Value
|
||||||
----------------------|----------------------------------------------------------------|------------------
|
----------------------|------------------------------------------------------------------------|------------------
|
||||||
dataDirectory | Data directory that is used to store the local copy of the NVD | data
|
dataDirectory | Data directory that is used to store the local copy of the NVD | data
|
||||||
|
failOnError | Whether the build should fail if there is an error executing the purge | true
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ proxyPort | The Proxy Port. |
|
|||||||
proxyUsername | Defines the proxy user name. |
|
proxyUsername | Defines the proxy user name. |
|
||||||
proxyPassword | Defines the proxy password. |
|
proxyPassword | Defines the proxy password. |
|
||||||
connectionTimeout | The URL Connection Timeout. |
|
connectionTimeout | The URL Connection Timeout. |
|
||||||
|
failOnError | Whether the build should fail if there is an error executing the update | true
|
||||||
|
|
||||||
Advanced Configuration
|
Advanced Configuration
|
||||||
====================
|
====================
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ Property | Description
|
|||||||
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
|
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
|
||||||
cveValidForHours | Sets the number of hours to wait before checking for new updates from the NVD | 4
|
cveValidForHours | Sets the number of hours to wait before checking for new updates from the NVD | 4
|
||||||
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
|
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
|
||||||
|
failOnError | Whether the build should fail if there is an error executing the dependency-check analysis | true
|
||||||
projectName | The name of the project being scanned. | Dependency-Check
|
projectName | The name of the project being scanned. | Dependency-Check
|
||||||
reportFormat | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
reportFormat | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
||||||
reportOutputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target'
|
reportOutputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target'
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ import org.owasp.dependencycheck.utils.Settings;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import ch.qos.logback.core.FileAppender;
|
import ch.qos.logback.core.FileAppender;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import org.owasp.dependencycheck.data.update.exception.UpdateException;
|
||||||
|
import org.owasp.dependencycheck.exception.ExceptionCollection;
|
||||||
|
import org.owasp.dependencycheck.exception.ReportException;
|
||||||
|
import org.owasp.dependencycheck.utils.InvalidSettingException;
|
||||||
import org.slf4j.impl.StaticLoggerBinder;
|
import org.slf4j.impl.StaticLoggerBinder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,13 +62,15 @@ public class App {
|
|||||||
* @param args the command line arguments
|
* @param args the command line arguments
|
||||||
*/
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
int exitCode = 0;
|
||||||
try {
|
try {
|
||||||
Settings.initialize();
|
Settings.initialize();
|
||||||
final App app = new App();
|
final App app = new App();
|
||||||
app.run(args);
|
exitCode = app.run(args);
|
||||||
} finally {
|
} finally {
|
||||||
Settings.cleanup(true);
|
Settings.cleanup(true);
|
||||||
}
|
}
|
||||||
|
System.exit(exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,7 +78,8 @@ public class App {
|
|||||||
*
|
*
|
||||||
* @param args the command line arguments
|
* @param args the command line arguments
|
||||||
*/
|
*/
|
||||||
public void run(String[] args) {
|
public int run(String[] args) {
|
||||||
|
int exitCode = 0;
|
||||||
final CliParser cli = new CliParser();
|
final CliParser cli = new CliParser();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -79,11 +87,11 @@ public class App {
|
|||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
System.err.println(ex.getMessage());
|
System.err.println(ex.getMessage());
|
||||||
cli.printHelp();
|
cli.printHelp();
|
||||||
return;
|
return -1;
|
||||||
} catch (ParseException ex) {
|
} catch (ParseException ex) {
|
||||||
System.err.println(ex.getMessage());
|
System.err.println(ex.getMessage());
|
||||||
cli.printHelp();
|
cli.printHelp();
|
||||||
return;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cli.getVerboseLog() != null) {
|
if (cli.getVerboseLog() != null) {
|
||||||
@@ -93,8 +101,15 @@ public class App {
|
|||||||
if (cli.isPurge()) {
|
if (cli.isPurge()) {
|
||||||
if (cli.getConnectionString() != null) {
|
if (cli.getConnectionString() != null) {
|
||||||
LOGGER.error("Unable to purge the database when using a non-default connection string");
|
LOGGER.error("Unable to purge the database when using a non-default connection string");
|
||||||
|
exitCode = -3;
|
||||||
} else {
|
} else {
|
||||||
populateSettings(cli);
|
try {
|
||||||
|
populateSettings(cli);
|
||||||
|
} catch (InvalidSettingException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
LOGGER.debug("Error loading properties file", ex);
|
||||||
|
exitCode = -4;
|
||||||
|
}
|
||||||
File db;
|
File db;
|
||||||
try {
|
try {
|
||||||
db = new File(Settings.getDataDirectory(), "dc.h2.db");
|
db = new File(Settings.getDataDirectory(), "dc.h2.db");
|
||||||
@@ -103,46 +118,96 @@ public class App {
|
|||||||
LOGGER.info("Database file purged; local copy of the NVD has been removed");
|
LOGGER.info("Database file purged; local copy of the NVD has been removed");
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error("Unable to delete '{}'; please delete the file manually", db.getAbsolutePath());
|
LOGGER.error("Unable to delete '{}'; please delete the file manually", db.getAbsolutePath());
|
||||||
|
exitCode = -5;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error("Unable to purge database; the database file does not exists: {}", db.getAbsolutePath());
|
LOGGER.error("Unable to purge database; the database file does not exists: {}", db.getAbsolutePath());
|
||||||
|
exitCode = -6;
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.error("Unable to delete the database");
|
LOGGER.error("Unable to delete the database");
|
||||||
|
exitCode = -7;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (cli.isGetVersion()) {
|
} else if (cli.isGetVersion()) {
|
||||||
cli.printVersionInfo();
|
cli.printVersionInfo();
|
||||||
} else if (cli.isUpdateOnly()) {
|
} else if (cli.isUpdateOnly()) {
|
||||||
populateSettings(cli);
|
try {
|
||||||
runUpdateOnly();
|
populateSettings(cli);
|
||||||
|
} catch (InvalidSettingException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
LOGGER.debug("Error loading properties file", ex);
|
||||||
|
exitCode = -4;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
runUpdateOnly();
|
||||||
|
} catch (UpdateException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
exitCode = -8;
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
exitCode = -9;
|
||||||
|
}
|
||||||
} else if (cli.isRunScan()) {
|
} else if (cli.isRunScan()) {
|
||||||
populateSettings(cli);
|
try {
|
||||||
|
populateSettings(cli);
|
||||||
|
} catch (InvalidSettingException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
LOGGER.debug("Error loading properties file", ex);
|
||||||
|
exitCode = -4;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), cli.getScanFiles(),
|
runScan(cli.getReportDirectory(), cli.getReportFormat(), cli.getProjectName(), cli.getScanFiles(),
|
||||||
cli.getExcludeList(), cli.getSymLinkDepth());
|
cli.getExcludeList(), cli.getSymLinkDepth());
|
||||||
} catch (InvalidScanPathException ex) {
|
} catch (InvalidScanPathException ex) {
|
||||||
LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths");
|
LOGGER.error("An invalid scan path was detected; unable to scan '//*' paths");
|
||||||
|
exitCode = -10;
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
exitCode = -11;
|
||||||
|
} catch (ReportException ex) {
|
||||||
|
LOGGER.error(ex.getMessage());
|
||||||
|
exitCode = -12;
|
||||||
|
} catch (ExceptionCollection ex) {
|
||||||
|
if (ex.isFatal()) {
|
||||||
|
exitCode =-13;
|
||||||
|
LOGGER.error("One or more fatal errors occured");
|
||||||
|
} else {
|
||||||
|
exitCode =-14;
|
||||||
|
}
|
||||||
|
for (Throwable e : ex.getExceptions()) {
|
||||||
|
LOGGER.error(e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cli.printHelp();
|
cli.printHelp();
|
||||||
}
|
}
|
||||||
|
return exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans the specified directories and writes the dependency reports to the reportDirectory.
|
* Scans the specified directories and writes the dependency reports to the
|
||||||
|
* reportDirectory.
|
||||||
*
|
*
|
||||||
* @param reportDirectory the path to the directory where the reports will be written
|
* @param reportDirectory the path to the directory where the reports will
|
||||||
|
* be written
|
||||||
* @param outputFormat the output format of the report
|
* @param outputFormat the output format of the report
|
||||||
* @param applicationName the application name for the report
|
* @param applicationName the application name for the report
|
||||||
* @param files the files/directories to scan
|
* @param files the files/directories to scan
|
||||||
* @param excludes the patterns for files/directories to exclude
|
* @param excludes the patterns for files/directories to exclude
|
||||||
* @param symLinkDepth the depth that symbolic links will be followed
|
* @param symLinkDepth the depth that symbolic links will be followed
|
||||||
*
|
*
|
||||||
* @throws InvalidScanPathException thrown if the path to scan starts with "//"
|
* @throws InvalidScanPathException thrown if the path to scan starts with
|
||||||
|
* "//"
|
||||||
|
* @throws ReportException thrown when the report cannot be generated
|
||||||
|
* @throws DatabaseException thrown when there is an error connecting to the
|
||||||
|
* database
|
||||||
|
* @throws ExceptionCollection thrown when an exception occurs during
|
||||||
|
* analysis; there may be multiple exceptions contained within the
|
||||||
|
* collection.
|
||||||
*/
|
*/
|
||||||
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files,
|
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files,
|
||||||
String[] excludes, int symLinkDepth) throws InvalidScanPathException {
|
String[] excludes, int symLinkDepth) throws InvalidScanPathException, DatabaseException, ExceptionCollection, ReportException {
|
||||||
Engine engine = null;
|
Engine engine = null;
|
||||||
try {
|
try {
|
||||||
engine = new Engine();
|
engine = new Engine();
|
||||||
@@ -174,8 +239,6 @@ public class App {
|
|||||||
include = "**/*";
|
include = "**/*";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//LOGGER.debug("baseDir: {}", baseDir);
|
|
||||||
//LOGGER.debug("include: {}", include);
|
|
||||||
scanner.setBasedir(baseDir);
|
scanner.setBasedir(baseDir);
|
||||||
final String[] includes = {include};
|
final String[] includes = {include};
|
||||||
scanner.setIncludes(includes);
|
scanner.setIncludes(includes);
|
||||||
@@ -197,7 +260,15 @@ public class App {
|
|||||||
}
|
}
|
||||||
engine.scan(paths);
|
engine.scan(paths);
|
||||||
|
|
||||||
engine.analyzeDependencies();
|
ExceptionCollection exCol = null;
|
||||||
|
try {
|
||||||
|
engine.analyzeDependencies();
|
||||||
|
} catch (ExceptionCollection ex) {
|
||||||
|
if (ex.isFatal()) {
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
exCol = ex;
|
||||||
|
}
|
||||||
final List<Dependency> dependencies = engine.getDependencies();
|
final List<Dependency> dependencies = engine.getDependencies();
|
||||||
DatabaseProperties prop = null;
|
DatabaseProperties prop = null;
|
||||||
CveDB cve = null;
|
CveDB cve = null;
|
||||||
@@ -205,8 +276,6 @@ public class App {
|
|||||||
cve = new CveDB();
|
cve = new CveDB();
|
||||||
cve.open();
|
cve.open();
|
||||||
prop = cve.getDatabaseProperties();
|
prop = cve.getDatabaseProperties();
|
||||||
} catch (DatabaseException ex) {
|
|
||||||
LOGGER.debug("Unable to retrieve DB Properties", ex);
|
|
||||||
} finally {
|
} finally {
|
||||||
if (cve != null) {
|
if (cve != null) {
|
||||||
cve.close();
|
cve.close();
|
||||||
@@ -215,16 +284,14 @@ public class App {
|
|||||||
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
|
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
|
||||||
try {
|
try {
|
||||||
report.generateReports(reportDirectory, outputFormat);
|
report.generateReports(reportDirectory, outputFormat);
|
||||||
} catch (IOException ex) {
|
} catch (ReportException ex) {
|
||||||
LOGGER.error("There was an IO error while attempting to generate the report.");
|
if (exCol != null) {
|
||||||
LOGGER.debug("", ex);
|
exCol.addException(ex);
|
||||||
} catch (Throwable ex) {
|
throw exCol;
|
||||||
LOGGER.error("There was an error while attempting to generate the report.");
|
} else {
|
||||||
LOGGER.debug("", ex);
|
throw ex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (DatabaseException ex) {
|
|
||||||
LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped");
|
|
||||||
LOGGER.debug("", ex);
|
|
||||||
} finally {
|
} finally {
|
||||||
if (engine != null) {
|
if (engine != null) {
|
||||||
engine.cleanup();
|
engine.cleanup();
|
||||||
@@ -235,14 +302,11 @@ public class App {
|
|||||||
/**
|
/**
|
||||||
* Only executes the update phase of dependency-check.
|
* Only executes the update phase of dependency-check.
|
||||||
*/
|
*/
|
||||||
private void runUpdateOnly() {
|
private void runUpdateOnly() throws UpdateException, DatabaseException {
|
||||||
Engine engine = null;
|
Engine engine = null;
|
||||||
try {
|
try {
|
||||||
engine = new Engine();
|
engine = new Engine();
|
||||||
engine.doUpdates();
|
engine.doUpdates();
|
||||||
} catch (DatabaseException ex) {
|
|
||||||
LOGGER.error("Unable to connect to the dependency-check database; analysis has stopped");
|
|
||||||
LOGGER.debug("", ex);
|
|
||||||
} finally {
|
} finally {
|
||||||
if (engine != null) {
|
if (engine != null) {
|
||||||
engine.cleanup();
|
engine.cleanup();
|
||||||
@@ -253,11 +317,13 @@ public class App {
|
|||||||
/**
|
/**
|
||||||
* Updates the global Settings.
|
* Updates the global Settings.
|
||||||
*
|
*
|
||||||
* @param cli a reference to the CLI Parser that contains the command line arguments used to set the corresponding settings in
|
* @param cli a reference to the CLI Parser that contains the command line
|
||||||
* the core engine.
|
* arguments used to set the corresponding settings in the core engine.
|
||||||
|
*
|
||||||
|
* @throws InvalidSettingException thrown when a user defined properties
|
||||||
|
* file is unable to be loaded.
|
||||||
*/
|
*/
|
||||||
private void populateSettings(CliParser cli) {
|
private void populateSettings(CliParser cli) throws InvalidSettingException {
|
||||||
|
|
||||||
final boolean autoUpdate = cli.isAutoUpdate();
|
final boolean autoUpdate = cli.isAutoUpdate();
|
||||||
final String connectionTimeout = cli.getConnectionTimeout();
|
final String connectionTimeout = cli.getConnectionTimeout();
|
||||||
final String proxyServer = cli.getProxyServer();
|
final String proxyServer = cli.getProxyServer();
|
||||||
@@ -286,11 +352,9 @@ public class App {
|
|||||||
try {
|
try {
|
||||||
Settings.mergeProperties(propertiesFile);
|
Settings.mergeProperties(propertiesFile);
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
LOGGER.error("Unable to load properties file '{}'", propertiesFile.getPath());
|
throw new InvalidSettingException("Unable to find properties file '" + propertiesFile.getPath() + "'", ex);
|
||||||
LOGGER.debug("", ex);
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.error("Unable to find properties file '{}'", propertiesFile.getPath());
|
throw new InvalidSettingException("Error reading properties file '" + propertiesFile.getPath() + "'", ex);
|
||||||
LOGGER.debug("", ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We have to wait until we've merged the properties before attempting to set whether we use
|
// We have to wait until we've merged the properties before attempting to set whether we use
|
||||||
@@ -385,15 +449,16 @@ public class App {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes a path and resolves it to be a canonical & absolute path. The caveats are that this method will take an Ant style
|
* Takes a path and resolves it to be a canonical & absolute path. The
|
||||||
* file selector path (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at least to the left of the first *
|
* caveats are that this method will take an Ant style file selector path
|
||||||
* or ?).
|
* (../someDir/**\/*.jar) and convert it to an absolute/canonical path (at
|
||||||
|
* least to the left of the first * or ?).
|
||||||
*
|
*
|
||||||
* @param path the path to canonicalize
|
* @param path the path to canonicalize
|
||||||
* @return the canonical path
|
* @return the canonical path
|
||||||
*/
|
*/
|
||||||
protected String ensureCanonicalPath(String path) {
|
protected String ensureCanonicalPath(String path) {
|
||||||
String basePath = null;
|
String basePath;
|
||||||
String wildCards = null;
|
String wildCards = null;
|
||||||
final String file = path.replace('\\', '/');
|
final String file = path.replace('\\', '/');
|
||||||
if (file.contains("*") || file.contains("?")) {
|
if (file.contains("*") || file.contains("?")) {
|
||||||
|
|||||||
@@ -359,12 +359,12 @@ public class Engine implements FileFilter {
|
|||||||
LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
|
LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
exceptions.add(ex);
|
exceptions.add(ex);
|
||||||
throw new ExceptionCollection(exceptions, true);
|
throw new ExceptionCollection("Unable to continue dependency-check analysis.",exceptions, true);
|
||||||
} catch (DatabaseException ex) {
|
} catch (DatabaseException ex) {
|
||||||
LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
|
LOGGER.error("{}\n\nUnable to continue dependency-check analysis.", ex.getMessage());
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
exceptions.add(ex);
|
exceptions.add(ex);
|
||||||
throw new ExceptionCollection(exceptions, true);
|
throw new ExceptionCollection("Unable to connect to the dependency-check database", exceptions, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------");
|
LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------");
|
||||||
@@ -424,7 +424,7 @@ public class Engine implements FileFilter {
|
|||||||
LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------");
|
LOGGER.debug("\n----------------------------------------------------\nEND ANALYSIS\n----------------------------------------------------");
|
||||||
LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart);
|
LOGGER.info("Analysis Complete ({} ms)", System.currentTimeMillis() - analysisStart);
|
||||||
if (exceptions.size() > 0) {
|
if (exceptions.size() > 0) {
|
||||||
throw new ExceptionCollection(exceptions);
|
throw new ExceptionCollection("One or more exceptions occured during dependency-check analysis", exceptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.exception;
|
package org.owasp.dependencycheck.exception;
|
||||||
|
|
||||||
|
import java.io.PrintStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -36,6 +38,18 @@ public class ExceptionCollection extends Exception {
|
|||||||
super();
|
super();
|
||||||
this.exceptions = exceptions;
|
this.exceptions = exceptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new exception collection.
|
||||||
|
*
|
||||||
|
* @param msg the exception message
|
||||||
|
* @param exceptions a list of exceptions
|
||||||
|
*/
|
||||||
|
public ExceptionCollection(String msg, List<Throwable> exceptions) {
|
||||||
|
super(msg);
|
||||||
|
this.exceptions = exceptions;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new exception collection.
|
* Instantiates a new exception collection.
|
||||||
*
|
*
|
||||||
@@ -48,7 +62,22 @@ public class ExceptionCollection extends Exception {
|
|||||||
this.exceptions = exceptions;
|
this.exceptions = exceptions;
|
||||||
this.fatal = fatal;
|
this.fatal = fatal;
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new exception collection.
|
||||||
|
*
|
||||||
|
* @param msg the exception message
|
||||||
|
* @param exceptions a list of exceptions
|
||||||
|
* @param fatal indicates if the exception that occurred is fatal - meaning
|
||||||
|
* that no analysis was performed.
|
||||||
|
*/
|
||||||
|
public ExceptionCollection(String msg, List<Throwable> exceptions, boolean fatal) {
|
||||||
|
super(msg);
|
||||||
|
this.exceptions = exceptions;
|
||||||
|
this.fatal = fatal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
* Instantiates a new exception collection.
|
* Instantiates a new exception collection.
|
||||||
*
|
*
|
||||||
* @param exceptions a list of exceptions
|
* @param exceptions a list of exceptions
|
||||||
@@ -60,6 +89,18 @@ public class ExceptionCollection extends Exception {
|
|||||||
this.exceptions.add(exceptions);
|
this.exceptions.add(exceptions);
|
||||||
this.fatal = fatal;
|
this.fatal = fatal;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Instantiates a new exception collection.
|
||||||
|
*
|
||||||
|
* @param msg the exception message
|
||||||
|
* @param exception a list of exceptions
|
||||||
|
*/
|
||||||
|
public ExceptionCollection(String msg, Throwable exception) {
|
||||||
|
super(msg);
|
||||||
|
this.exceptions.add(exception);
|
||||||
|
this.fatal = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates a new exception collection.
|
* Instantiates a new exception collection.
|
||||||
*/
|
*/
|
||||||
@@ -94,7 +135,8 @@ public class ExceptionCollection extends Exception {
|
|||||||
public void addException(Throwable ex) {
|
public void addException(Throwable ex) {
|
||||||
this.exceptions.add(ex);
|
this.exceptions.add(ex);
|
||||||
}
|
}
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* Adds an exception to the collection.
|
* Adds an exception to the collection.
|
||||||
*
|
*
|
||||||
* @param ex the exception to add
|
* @param ex the exception to add
|
||||||
@@ -105,8 +147,8 @@ public class ExceptionCollection extends Exception {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag indicating if a fatal exception occurred that would prevent the attempt
|
* Flag indicating if a fatal exception occurred that would prevent the
|
||||||
* at completing the analysis even if exceptions occurred.
|
* attempt at completing the analysis even if exceptions occurred.
|
||||||
*/
|
*/
|
||||||
private boolean fatal = false;
|
private boolean fatal = false;
|
||||||
|
|
||||||
@@ -128,4 +170,42 @@ public class ExceptionCollection extends Exception {
|
|||||||
this.fatal = fatal;
|
this.fatal = fatal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the stack trace.
|
||||||
|
*
|
||||||
|
* @param s the writer to print to
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void printStackTrace(PrintWriter s) {
|
||||||
|
s.println("Multiple Exceptions Occured");
|
||||||
|
super.printStackTrace(s);
|
||||||
|
for (Throwable t : this.exceptions) {
|
||||||
|
s.println("Next Exception:");
|
||||||
|
t.printStackTrace(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the stack trace.
|
||||||
|
*
|
||||||
|
* @param s the stream to write the stack trace to
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void printStackTrace(PrintStream s) {
|
||||||
|
s.println("Multiple Exceptions Occured");
|
||||||
|
super.printStackTrace(s);
|
||||||
|
for (Throwable t : this.exceptions) {
|
||||||
|
s.println("Next Exception:");
|
||||||
|
t.printStackTrace(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints the stack trace to standard error.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void printStackTrace() {
|
||||||
|
this.printStackTrace(System.err);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import org.apache.maven.MavenExecutionException;
|
||||||
import org.apache.maven.plugin.MojoExecutionException;
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
import org.apache.maven.plugin.MojoFailureException;
|
import org.apache.maven.plugin.MojoFailureException;
|
||||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||||
@@ -36,11 +37,13 @@ import org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer;
|
|||||||
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
|
import org.owasp.dependencycheck.exception.ExceptionCollection;
|
||||||
|
import org.owasp.dependencycheck.exception.ReportException;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maven Plugin that checks project dependencies and the dependencies of all child modules to see if they have any known published
|
* Maven Plugin that checks project dependencies and the dependencies of all
|
||||||
* vulnerabilities.
|
* child modules to see if they have any known published vulnerabilities.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
@@ -55,18 +58,27 @@ import org.owasp.dependencycheck.utils.Settings;
|
|||||||
public class AggregateMojo extends BaseDependencyCheckMojo {
|
public class AggregateMojo extends BaseDependencyCheckMojo {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the aggregate dependency-check goal. This runs dependency-check and generates the subsequent reports.
|
* The key to store aggregate exception in the root Maven execution context.
|
||||||
|
*/
|
||||||
|
private static final String AGGREGATE_EXCEPTIONS = "AggregateExceptions";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the aggregate dependency-check goal. This runs dependency-check
|
||||||
|
* and generates the subsequent reports.
|
||||||
*
|
*
|
||||||
* @throws MojoExecutionException thrown if there is ane exception running the mojo
|
* @throws MojoExecutionException thrown if there is ane exception running
|
||||||
* @throws MojoFailureException thrown if dependency-check is configured to fail the build
|
* the mojo
|
||||||
|
* @throws MojoFailureException thrown if dependency-check is configured to
|
||||||
|
* fail the build
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void runCheck() throws MojoExecutionException, MojoFailureException {
|
public void runCheck() throws MojoExecutionException, MojoFailureException {
|
||||||
final Engine engine = generateDataFile();
|
final MavenEngine engine = generateDataFile();
|
||||||
|
if (engine == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//if (getProject() == getReactorProjects().get(getReactorProjects().size() - 1)) {
|
|
||||||
if (getProject() == getLastProject()) {
|
if (getProject() == getLastProject()) {
|
||||||
|
|
||||||
//ensure that the .ser file was created for each.
|
//ensure that the .ser file was created for each.
|
||||||
for (MavenProject current : getReactorProjects()) {
|
for (MavenProject current : getReactorProjects()) {
|
||||||
final File dataFile = getDataFile(current);
|
final File dataFile = getDataFile(current);
|
||||||
@@ -76,7 +88,6 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
generateDataFile(engine, current);
|
generateDataFile(engine, current);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MavenProject current : getReactorProjects()) {
|
for (MavenProject current : getReactorProjects()) {
|
||||||
List<Dependency> dependencies = readDataFile(current);
|
List<Dependency> dependencies = readDataFile(current);
|
||||||
if (dependencies == null) {
|
if (dependencies == null) {
|
||||||
@@ -90,10 +101,8 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
getLog().debug(String.format("Adding %d dependencies from %s", childDeps.size(), reportOn.getName()));
|
getLog().debug(String.format("Adding %d dependencies from %s", childDeps.size(), reportOn.getName()));
|
||||||
}
|
}
|
||||||
dependencies.addAll(childDeps);
|
dependencies.addAll(childDeps);
|
||||||
} else {
|
} else if (getLog().isDebugEnabled()) {
|
||||||
if (getLog().isDebugEnabled()) {
|
getLog().debug(String.format("No dependencies read for %s", reportOn.getName()));
|
||||||
getLog().debug(String.format("No dependencies read for %s", reportOn.getName()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
engine.getDependencies().clear();
|
engine.getDependencies().clear();
|
||||||
@@ -118,7 +127,21 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
//we shouldn't write this because nothing is configured to generate this report.
|
//we shouldn't write this because nothing is configured to generate this report.
|
||||||
outputDir = new File(current.getBuild().getDirectory());
|
outputDir = new File(current.getBuild().getDirectory());
|
||||||
}
|
}
|
||||||
writeReports(engine, current, outputDir);
|
try {
|
||||||
|
writeReports(engine, current, outputDir);
|
||||||
|
} catch (ReportException ex) {
|
||||||
|
ExceptionCollection exCol = (ExceptionCollection) engine.getExecutionRoot().getContextValue(AGGREGATE_EXCEPTIONS);
|
||||||
|
if (exCol == null) {
|
||||||
|
exCol = new ExceptionCollection("Error writing aggregate report",ex);
|
||||||
|
} else {
|
||||||
|
exCol.addException(ex);
|
||||||
|
}
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new MojoExecutionException("One or more exceptions occured during dependency-check analysis", exCol);
|
||||||
|
} else {
|
||||||
|
getLog().debug("One or more exceptions occured during dependency-check analysis", exCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
engine.cleanup();
|
engine.cleanup();
|
||||||
@@ -126,7 +149,8 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the last project in the reactor - taking into account skipped projects.
|
* Gets the last project in the reactor - taking into account skipped
|
||||||
|
* projects.
|
||||||
*
|
*
|
||||||
* @return the last project in the reactor
|
* @return the last project in the reactor
|
||||||
*/
|
*/
|
||||||
@@ -152,7 +176,8 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a set containing all the descendant projects of the given project.
|
* Returns a set containing all the descendant projects of the given
|
||||||
|
* project.
|
||||||
*
|
*
|
||||||
* @param project the project for which all descendants will be returned
|
* @param project the project for which all descendants will be returned
|
||||||
* @return the set of descendant projects
|
* @return the set of descendant projects
|
||||||
@@ -232,49 +257,85 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
* Test if the project has pom packaging
|
* Test if the project has pom packaging
|
||||||
*
|
*
|
||||||
* @param mavenProject Project to test
|
* @param mavenProject Project to test
|
||||||
* @return <code>true</code> if it has a pom packaging; otherwise <code>false</code>
|
* @return <code>true</code> if it has a pom packaging; otherwise
|
||||||
|
* <code>false</code>
|
||||||
*/
|
*/
|
||||||
protected boolean isMultiModule(MavenProject mavenProject) {
|
protected boolean isMultiModule(MavenProject mavenProject) {
|
||||||
return "pom".equals(mavenProject.getPackaging());
|
return "pom".equals(mavenProject.getPackaging());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the engine, runs a scan, and writes the serialized dependencies to disk.
|
* Initializes the engine, runs a scan, and writes the serialized
|
||||||
|
* dependencies to disk.
|
||||||
*
|
*
|
||||||
* @return the Engine used to execute dependency-check
|
* @return the MavenEngine used to execute dependency-check
|
||||||
* @throws MojoExecutionException thrown if there is an exception running the mojo
|
* @throws MojoExecutionException thrown if there is an exception running
|
||||||
* @throws MojoFailureException thrown if dependency-check is configured to fail the build if severe CVEs are identified.
|
* the mojo
|
||||||
|
* @throws MojoFailureException thrown if dependency-check is configured to
|
||||||
|
* fail the build if severe CVEs are identified.
|
||||||
*/
|
*/
|
||||||
protected Engine generateDataFile() throws MojoExecutionException, MojoFailureException {
|
protected MavenEngine generateDataFile() throws MojoExecutionException, MojoFailureException {
|
||||||
final Engine engine;
|
MavenEngine engine = null;
|
||||||
try {
|
try {
|
||||||
engine = initializeEngine();
|
engine = initializeEngine();
|
||||||
} catch (DatabaseException ex) {
|
} catch (DatabaseException ex) {
|
||||||
if (getLog().isDebugEnabled()) {
|
if (getLog().isDebugEnabled()) {
|
||||||
getLog().debug("Database connection error", ex);
|
getLog().debug("Database connection error", ex);
|
||||||
}
|
}
|
||||||
throw new MojoExecutionException("An exception occured connecting to the local database. Please see the log file for more details.", ex);
|
final String msg = "An exception occured connecting to the local database. Please see the log file for more details.";
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new MojoExecutionException(msg, ex);
|
||||||
|
}
|
||||||
|
getLog().error(msg, ex);
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
return generateDataFile(engine, getProject());
|
return generateDataFile(engine, getProject());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs dependency-check's Engine and writes the serialized dependencies to disk.
|
* Runs dependency-check's MavenEngine and writes the serialized
|
||||||
|
* dependencies to disk.
|
||||||
*
|
*
|
||||||
* @param engine the Engine to use when scanning.
|
* @param engine the MavenEngine to use when scanning.
|
||||||
* @param project the project to scan and generate the data file for
|
* @param project the project to scan and generate the data file for
|
||||||
* @return the Engine used to execute dependency-check
|
* @return the MavenEngine used to execute dependency-check
|
||||||
* @throws MojoExecutionException thrown if there is an exception running the mojo
|
* @throws MojoExecutionException thrown if there is an exception running
|
||||||
* @throws MojoFailureException thrown if dependency-check is configured to fail the build if severe CVEs are identified.
|
* the mojo
|
||||||
|
* @throws MojoFailureException thrown if dependency-check is configured to
|
||||||
|
* fail the build if severe CVEs are identified.
|
||||||
*/
|
*/
|
||||||
protected Engine generateDataFile(Engine engine, MavenProject project) throws MojoExecutionException, MojoFailureException {
|
protected MavenEngine generateDataFile(MavenEngine engine, MavenProject project) throws MojoExecutionException, MojoFailureException {
|
||||||
if (getLog().isDebugEnabled()) {
|
if (getLog().isDebugEnabled()) {
|
||||||
getLog().debug(String.format("Begin Scanning: %s", project.getName()));
|
getLog().debug(String.format("Begin Scanning: %s", project.getName()));
|
||||||
}
|
}
|
||||||
engine.getDependencies().clear();
|
engine.getDependencies().clear();
|
||||||
engine.resetFileTypeAnalyzers();
|
engine.resetFileTypeAnalyzers();
|
||||||
scanArtifacts(project, engine);
|
scanArtifacts(project, engine);
|
||||||
engine.analyzeDependencies();
|
try {
|
||||||
|
engine.analyzeDependencies();
|
||||||
|
} catch (ExceptionCollection ex) {
|
||||||
|
ExceptionCollection col = (ExceptionCollection) engine.getExecutionRoot().getContextValue(AGGREGATE_EXCEPTIONS);
|
||||||
|
if (col == null) {
|
||||||
|
col = ex;
|
||||||
|
} else if (ex.isFatal()) {
|
||||||
|
col.setFatal(true);
|
||||||
|
col.getExceptions().addAll(ex.getExceptions());
|
||||||
|
}
|
||||||
|
if (col.isFatal()) {
|
||||||
|
final String msg = String.format("Fatal exception(s) analyzing %s", project.getName());
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new MojoExecutionException(msg, ex);
|
||||||
|
}
|
||||||
|
getLog().error(msg, col);
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
final String msg = String.format("Exception(s) analyzing %s", project.getName());
|
||||||
|
if (getLog().isDebugEnabled()) {
|
||||||
|
getLog().debug(msg, ex);
|
||||||
|
}
|
||||||
|
engine.getExecutionRoot().setContextValue(AGGREGATE_EXCEPTIONS, col);
|
||||||
|
}
|
||||||
|
}
|
||||||
final File target = new File(project.getBuild().getDirectory());
|
final File target = new File(project.getBuild().getDirectory());
|
||||||
writeDataFile(project, target, engine.getDependencies());
|
writeDataFile(project, target, engine.getDependencies());
|
||||||
showSummary(project, engine.getDependencies());
|
showSummary(project, engine.getDependencies());
|
||||||
@@ -306,7 +367,8 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page.
|
* Gets the description of the Dependency-Check report to be displayed in
|
||||||
|
* the Maven Generated Reports page.
|
||||||
*
|
*
|
||||||
* @param locale The Locale to get the description for
|
* @param locale The Locale to get the description for
|
||||||
* @return the description
|
* @return the description
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import org.owasp.dependencycheck.dependency.Confidence;
|
|||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Identifier;
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
import org.owasp.dependencycheck.dependency.Vulnerability;
|
import org.owasp.dependencycheck.dependency.Vulnerability;
|
||||||
|
import org.owasp.dependencycheck.exception.ReportException;
|
||||||
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
||||||
import org.owasp.dependencycheck.utils.ExpectedOjectInputStream;
|
import org.owasp.dependencycheck.utils.ExpectedOjectInputStream;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
@@ -69,14 +70,27 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
* System specific new line character.
|
* System specific new line character.
|
||||||
*/
|
*/
|
||||||
private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
|
private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
|
||||||
|
//</editor-fold>
|
||||||
|
// <editor-fold defaultstate="collapsed" desc="Maven bound parameters and components">
|
||||||
/**
|
/**
|
||||||
* Sets whether or not the external report format should be used.
|
* Sets whether or not the external report format should be used.
|
||||||
*/
|
*/
|
||||||
@Parameter(property = "metaFileName", defaultValue = "dependency-check.ser", required = true)
|
@Parameter(property = "metaFileName", defaultValue = "dependency-check.ser", required = true)
|
||||||
private String dataFileName;
|
private String dataFileName;
|
||||||
|
/**
|
||||||
|
* Sets whether or not the external report format should be used.
|
||||||
|
*/
|
||||||
|
@Parameter(property = "failOnError", defaultValue = "true", required = true)
|
||||||
|
private boolean failOnError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if the mojo should fail the build if an exception occurs.
|
||||||
|
* @return whether or not the mojo should fail the build
|
||||||
|
*/
|
||||||
|
protected boolean isFailOnError() {
|
||||||
|
return failOnError;
|
||||||
|
}
|
||||||
|
|
||||||
//</editor-fold>
|
|
||||||
// <editor-fold defaultstate="collapsed" desc="Maven bound parameters and components">
|
|
||||||
/**
|
/**
|
||||||
* The Maven Project Object.
|
* The Maven Project Object.
|
||||||
*/
|
*/
|
||||||
@@ -111,13 +125,11 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
* Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not
|
* Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not
|
||||||
* recommended that this be turned to false. Default is true.
|
* recommended that this be turned to false. Default is true.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("CanBeFinal")
|
|
||||||
@Parameter(property = "autoUpdate")
|
@Parameter(property = "autoUpdate")
|
||||||
private Boolean autoUpdate;
|
private Boolean autoUpdate;
|
||||||
/**
|
/**
|
||||||
* Sets whether Experimental analyzers are enabled. Default is false.
|
* Sets whether Experimental analyzers are enabled. Default is false.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("CanBeFinal")
|
|
||||||
@Parameter(property = "enableExperimental")
|
@Parameter(property = "enableExperimental")
|
||||||
private Boolean enableExperimental;
|
private Boolean enableExperimental;
|
||||||
/**
|
/**
|
||||||
@@ -145,7 +157,6 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
/**
|
/**
|
||||||
* The maven settings proxy id.
|
* The maven settings proxy id.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("CanBeFinal")
|
|
||||||
@Parameter(property = "mavenSettingsProxyId", required = false)
|
@Parameter(property = "mavenSettingsProxyId", required = false)
|
||||||
private String mavenSettingsProxyId;
|
private String mavenSettingsProxyId;
|
||||||
|
|
||||||
@@ -162,6 +173,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
/**
|
/**
|
||||||
* Flag indicating whether or not to show a summary in the output.
|
* Flag indicating whether or not to show a summary in the output.
|
||||||
*/
|
*/
|
||||||
|
@SuppressWarnings("CanBeFinal")
|
||||||
@Parameter(property = "showSummary", defaultValue = "true", required = false)
|
@Parameter(property = "showSummary", defaultValue = "true", required = false)
|
||||||
private boolean showSummary = true;
|
private boolean showSummary = true;
|
||||||
|
|
||||||
@@ -541,7 +553,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
* @param project the project to scan the dependencies of
|
* @param project the project to scan the dependencies of
|
||||||
* @param engine the engine to use to scan the dependencies
|
* @param engine the engine to use to scan the dependencies
|
||||||
*/
|
*/
|
||||||
protected void scanArtifacts(MavenProject project, Engine engine) {
|
protected void scanArtifacts(MavenProject project, MavenEngine engine) {
|
||||||
for (Artifact a : project.getArtifacts()) {
|
for (Artifact a : project.getArtifacts()) {
|
||||||
if (excludeFromScan(a)) {
|
if (excludeFromScan(a)) {
|
||||||
continue;
|
continue;
|
||||||
@@ -649,14 +661,14 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes a new <code>Engine</code> that can be used for scanning.
|
* Initializes a new <code>MavenEngine</code> that can be used for scanning.
|
||||||
*
|
*
|
||||||
* @return a newly instantiated <code>Engine</code>
|
* @return a newly instantiated <code>MavenEngine</code>
|
||||||
* @throws DatabaseException thrown if there is a database exception
|
* @throws DatabaseException thrown if there is a database exception
|
||||||
*/
|
*/
|
||||||
protected Engine initializeEngine() throws DatabaseException {
|
protected MavenEngine initializeEngine() throws DatabaseException {
|
||||||
populateSettings();
|
populateSettings();
|
||||||
return new Engine(this.project,
|
return new MavenEngine(this.project,
|
||||||
this.reactorProjects);
|
this.reactorProjects);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -875,10 +887,11 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
* Generates the reports for a given dependency-check engine.
|
* Generates the reports for a given dependency-check engine.
|
||||||
*
|
*
|
||||||
* @param engine a dependency-check engine
|
* @param engine a dependency-check engine
|
||||||
* @param p the maven project
|
* @param p the Maven project
|
||||||
* @param outputDir the directory path to write the report(s).
|
* @param outputDir the directory path to write the report(s)
|
||||||
|
* @throws ReportException thrown if there is an error writing the report
|
||||||
*/
|
*/
|
||||||
protected void writeReports(Engine engine, MavenProject p, File outputDir) {
|
protected void writeReports(MavenEngine engine, MavenProject p, File outputDir) throws ReportException {
|
||||||
DatabaseProperties prop = null;
|
DatabaseProperties prop = null;
|
||||||
CveDB cve = null;
|
CveDB cve = null;
|
||||||
try {
|
try {
|
||||||
@@ -897,19 +910,11 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop);
|
final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop);
|
||||||
try {
|
try {
|
||||||
r.generateReports(outputDir.getAbsolutePath(), format);
|
r.generateReports(outputDir.getAbsolutePath(), format);
|
||||||
} catch (IOException ex) {
|
} catch (ReportException ex) {
|
||||||
getLog().error(
|
final String msg = String.format("Error generating the report for %s", p.getName());
|
||||||
"Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
throw new ReportException(msg, ex);
|
||||||
if (getLog().isDebugEnabled()) {
|
|
||||||
getLog().debug("", ex);
|
|
||||||
}
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
getLog().error(
|
|
||||||
"Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
|
||||||
if (getLog().isDebugEnabled()) {
|
|
||||||
getLog().debug("", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary">
|
//<editor-fold defaultstate="collapsed" desc="Methods to fail build or show summary">
|
||||||
@@ -1074,7 +1079,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
* scan data between the "check" and "aggregate" phase.
|
* scan data between the "check" and "aggregate" phase.
|
||||||
*
|
*
|
||||||
* @param project the Maven project to read the data file from
|
* @param project the Maven project to read the data file from
|
||||||
* @return a <code>Engine</code> object populated with dependencies if the
|
* @return a <code>MavenEngine</code> object populated with dependencies if the
|
||||||
* serialized data file exists; otherwise <code>null</code> is returned
|
* serialized data file exists; otherwise <code>null</code> is returned
|
||||||
*/
|
*/
|
||||||
protected List<Dependency> readDataFile(MavenProject project) {
|
protected List<Dependency> readDataFile(MavenProject project) {
|
||||||
|
|||||||
@@ -26,10 +26,13 @@ import org.apache.maven.plugins.annotations.Mojo;
|
|||||||
import org.apache.maven.plugins.annotations.Parameter;
|
import org.apache.maven.plugins.annotations.Parameter;
|
||||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
|
import org.owasp.dependencycheck.exception.ExceptionCollection;
|
||||||
|
import org.owasp.dependencycheck.exception.ReportException;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maven Plugin that checks the project dependencies to see if they have any known published vulnerabilities.
|
* Maven Plugin that checks the project dependencies to see if they have any
|
||||||
|
* known published vulnerabilities.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
@@ -45,7 +48,8 @@ public class CheckMojo extends BaseDependencyCheckMojo {
|
|||||||
/**
|
/**
|
||||||
* Returns whether or not a the report can be generated.
|
* Returns whether or not a the report can be generated.
|
||||||
*
|
*
|
||||||
* @return <code>true</code> if the report can be generated; otherwise <code>false</code>
|
* @return <code>true</code> if the report can be generated; otherwise
|
||||||
|
* <code>false</code>
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean canGenerateReport() {
|
public boolean canGenerateReport() {
|
||||||
@@ -60,33 +64,65 @@ public class CheckMojo extends BaseDependencyCheckMojo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the dependency-check engine on the project's dependencies and generates the report.
|
* Executes the dependency-check engine on the project's dependencies and
|
||||||
|
* generates the report.
|
||||||
*
|
*
|
||||||
* @throws MojoExecutionException thrown if there is an exception executing the goal
|
* @throws MojoExecutionException thrown if there is an exception executing
|
||||||
* @throws MojoFailureException thrown if dependency-check is configured to fail the build
|
* the goal
|
||||||
|
* @throws MojoFailureException thrown if dependency-check is configured to
|
||||||
|
* fail the build
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void runCheck() throws MojoExecutionException, MojoFailureException {
|
public void runCheck() throws MojoExecutionException, MojoFailureException {
|
||||||
final Engine engine;
|
MavenEngine engine = null;
|
||||||
try {
|
try {
|
||||||
engine = initializeEngine();
|
engine = initializeEngine();
|
||||||
} catch (DatabaseException ex) {
|
} catch (DatabaseException ex) {
|
||||||
if (getLog().isDebugEnabled()) {
|
if (getLog().isDebugEnabled()) {
|
||||||
getLog().debug("Database connection error", ex);
|
getLog().debug("Database connection error", ex);
|
||||||
}
|
}
|
||||||
throw new MojoExecutionException("An exception occured connecting to the local database. Please see the log file for more details.", ex);
|
final String msg = "An exception occured connecting to the local database. Please see the log file for more details.";
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new MojoExecutionException(msg, ex);
|
||||||
|
}
|
||||||
|
getLog().error(msg);
|
||||||
}
|
}
|
||||||
scanArtifacts(getProject(), engine);
|
if (engine != null) {
|
||||||
if (engine.getDependencies().isEmpty()) {
|
scanArtifacts(getProject(), engine);
|
||||||
getLog().info("No dependencies were identified that could be analyzed by dependency-check");
|
if (engine.getDependencies().isEmpty()) {
|
||||||
} else {
|
getLog().info("No dependencies were identified that could be analyzed by dependency-check");
|
||||||
engine.analyzeDependencies();
|
} else {
|
||||||
writeReports(engine, getProject(), getCorrectOutputDirectory());
|
ExceptionCollection exCol = null;
|
||||||
writeDataFile(getProject(), null, engine.getDependencies());
|
try {
|
||||||
showSummary(getProject(), engine.getDependencies());
|
engine.analyzeDependencies();
|
||||||
checkForFailure(engine.getDependencies());
|
} catch (ExceptionCollection ex) {
|
||||||
|
if (this.isFailOnError() && ex.isFatal()) {
|
||||||
|
throw new MojoExecutionException("One or more exceptions occured during analysis", ex);
|
||||||
|
}
|
||||||
|
exCol = ex;
|
||||||
|
}
|
||||||
|
if (exCol == null || !exCol.isFatal()) {
|
||||||
|
try {
|
||||||
|
writeReports(engine, getProject(), getCorrectOutputDirectory());
|
||||||
|
} catch (ReportException ex) {
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
if (exCol!= null) {
|
||||||
|
exCol.addException(ex);
|
||||||
|
} else {
|
||||||
|
exCol = new ExceptionCollection("Unable to write the dependency-check report", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writeDataFile(getProject(), null, engine.getDependencies());
|
||||||
|
showSummary(getProject(), engine.getDependencies());
|
||||||
|
checkForFailure(engine.getDependencies());
|
||||||
|
if (exCol != null && this.isFailOnError()) {
|
||||||
|
throw new MojoExecutionException("One or more exceptions occured during dependency-check analysis", exCol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
engine.cleanup();
|
||||||
}
|
}
|
||||||
engine.cleanup();
|
|
||||||
Settings.cleanup();
|
Settings.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +145,8 @@ public class CheckMojo extends BaseDependencyCheckMojo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page.
|
* Gets the description of the Dependency-Check report to be displayed in
|
||||||
|
* the Maven Generated Reports page.
|
||||||
*
|
*
|
||||||
* @param locale The Locale to get the description for
|
* @param locale The Locale to get the description for
|
||||||
* @return the description
|
* @return the description
|
||||||
|
|||||||
@@ -36,12 +36,12 @@ import org.slf4j.LoggerFactory;
|
|||||||
*
|
*
|
||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class Engine extends org.owasp.dependencycheck.Engine {
|
public class MavenEngine extends org.owasp.dependencycheck.Engine {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logger.
|
* The logger.
|
||||||
*/
|
*/
|
||||||
private static final transient Logger LOGGER = LoggerFactory.getLogger(Engine.class);
|
private static final transient Logger LOGGER = LoggerFactory.getLogger(MavenEngine.class);
|
||||||
/**
|
/**
|
||||||
* A key used to persist an object in the MavenProject.
|
* A key used to persist an object in the MavenProject.
|
||||||
*/
|
*/
|
||||||
@@ -69,7 +69,7 @@ public class Engine extends org.owasp.dependencycheck.Engine {
|
|||||||
* @throws DatabaseException thrown if there is an issue connecting to the
|
* @throws DatabaseException thrown if there is an issue connecting to the
|
||||||
* database
|
* database
|
||||||
*/
|
*/
|
||||||
public Engine(MavenProject project, List<MavenProject> reactorProjects) throws DatabaseException {
|
public MavenEngine(MavenProject project, List<MavenProject> reactorProjects) throws DatabaseException {
|
||||||
this.currentProject = project;
|
this.currentProject = project;
|
||||||
this.reactorProjects = reactorProjects;
|
this.reactorProjects = reactorProjects;
|
||||||
initializeEngine();
|
initializeEngine();
|
||||||
@@ -117,7 +117,7 @@ public class Engine extends org.owasp.dependencycheck.Engine {
|
|||||||
* @throws DatabaseException thrown if there is an issue connecting to the
|
* @throws DatabaseException thrown if there is an issue connecting to the
|
||||||
* database
|
* database
|
||||||
*/
|
*/
|
||||||
private Engine() throws DatabaseException {
|
private MavenEngine() throws DatabaseException {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -208,7 +208,7 @@ public class Engine extends org.owasp.dependencycheck.Engine {
|
|||||||
*
|
*
|
||||||
* @return the root Maven Project
|
* @return the root Maven Project
|
||||||
*/
|
*/
|
||||||
private MavenProject getExecutionRoot() {
|
MavenProject getExecutionRoot() {
|
||||||
if (reactorProjects == null) {
|
if (reactorProjects == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -54,14 +54,20 @@ public class PurgeMojo extends BaseDependencyCheckMojo {
|
|||||||
/**
|
/**
|
||||||
* Purges the local copy of the NVD.
|
* Purges the local copy of the NVD.
|
||||||
*
|
*
|
||||||
* @throws MojoExecutionException thrown if there is an exception executing the goal
|
* @throws MojoExecutionException thrown if there is an exception executing
|
||||||
* @throws MojoFailureException thrown if dependency-check is configured to fail the build
|
* the goal
|
||||||
|
* @throws MojoFailureException thrown if dependency-check is configured to
|
||||||
|
* fail the build
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void runCheck() throws MojoExecutionException, MojoFailureException {
|
public void runCheck() throws MojoExecutionException, MojoFailureException {
|
||||||
|
|
||||||
if (getConnectionString() != null && !getConnectionString().isEmpty()) {
|
if (getConnectionString() != null && !getConnectionString().isEmpty()) {
|
||||||
getLog().error("Unable to purge the local NVD when using a non-default connection string");
|
final String msg = "Unable to purge the local NVD when using a non-default connection string";
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new MojoFailureException(msg);
|
||||||
|
}
|
||||||
|
getLog().error(msg);
|
||||||
} else {
|
} else {
|
||||||
populateSettings();
|
populateSettings();
|
||||||
File db;
|
File db;
|
||||||
@@ -71,13 +77,25 @@ public class PurgeMojo extends BaseDependencyCheckMojo {
|
|||||||
if (db.delete()) {
|
if (db.delete()) {
|
||||||
getLog().info("Database file purged; local copy of the NVD has been removed");
|
getLog().info("Database file purged; local copy of the NVD has been removed");
|
||||||
} else {
|
} else {
|
||||||
getLog().error(String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath()));
|
final String msg = String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath());
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new MojoFailureException(msg);
|
||||||
|
}
|
||||||
|
getLog().error(msg);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
getLog().error(String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath()));
|
final String msg = String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath());
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new MojoFailureException(msg);
|
||||||
|
}
|
||||||
|
getLog().error(msg);
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
getLog().error("Unable to delete the database");
|
final String msg = "Unable to delete the database";
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new MojoExecutionException(msg, ex);
|
||||||
|
}
|
||||||
|
getLog().error(msg);
|
||||||
}
|
}
|
||||||
Settings.cleanup();
|
Settings.cleanup();
|
||||||
}
|
}
|
||||||
@@ -95,7 +113,8 @@ public class PurgeMojo extends BaseDependencyCheckMojo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page.
|
* Gets the description of the Dependency-Check report to be displayed in
|
||||||
|
* the Maven Generated Reports page.
|
||||||
*
|
*
|
||||||
* @param locale The Locale to get the description for
|
* @param locale The Locale to get the description for
|
||||||
* @return the description
|
* @return the description
|
||||||
|
|||||||
@@ -24,10 +24,12 @@ import org.apache.maven.plugins.annotations.LifecyclePhase;
|
|||||||
import org.apache.maven.plugins.annotations.Mojo;
|
import org.apache.maven.plugins.annotations.Mojo;
|
||||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
|
import org.owasp.dependencycheck.data.update.exception.UpdateException;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maven Plugin that checks the project dependencies to see if they have any known published vulnerabilities.
|
* Maven Plugin that checks the project dependencies to see if they have any
|
||||||
|
* known published vulnerabilities.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
@@ -51,14 +53,17 @@ public class UpdateMojo extends BaseDependencyCheckMojo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the dependency-check engine on the project's dependencies and generates the report.
|
* Executes the dependency-check engine on the project's dependencies and
|
||||||
|
* generates the report.
|
||||||
*
|
*
|
||||||
* @throws MojoExecutionException thrown if there is an exception executing the goal
|
* @throws MojoExecutionException thrown if there is an exception executing
|
||||||
* @throws MojoFailureException thrown if dependency-check is configured to fail the build
|
* the goal
|
||||||
|
* @throws MojoFailureException thrown if dependency-check is configured to
|
||||||
|
* fail the build
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void runCheck() throws MojoExecutionException, MojoFailureException {
|
public void runCheck() throws MojoExecutionException, MojoFailureException {
|
||||||
final Engine engine;
|
MavenEngine engine = null;
|
||||||
try {
|
try {
|
||||||
engine = initializeEngine();
|
engine = initializeEngine();
|
||||||
engine.update();
|
engine.update();
|
||||||
@@ -66,9 +71,21 @@ public class UpdateMojo extends BaseDependencyCheckMojo {
|
|||||||
if (getLog().isDebugEnabled()) {
|
if (getLog().isDebugEnabled()) {
|
||||||
getLog().debug("Database connection error", ex);
|
getLog().debug("Database connection error", ex);
|
||||||
}
|
}
|
||||||
throw new MojoExecutionException("An exception occured connecting to the local database. Please see the log file for more details.", ex);
|
final String msg = "An exception occured connecting to the local database. Please see the log file for more details.";
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new MojoExecutionException(msg, ex);
|
||||||
|
}
|
||||||
|
getLog().error(msg);
|
||||||
|
} catch (UpdateException ex) {
|
||||||
|
final String msg = "An exception occured while downloading updates. Please see the log file for more details.";
|
||||||
|
if (this.isFailOnError()) {
|
||||||
|
throw new MojoExecutionException(msg, ex);
|
||||||
|
}
|
||||||
|
getLog().error(msg);
|
||||||
|
}
|
||||||
|
if (engine != null) {
|
||||||
|
engine.cleanup();
|
||||||
}
|
}
|
||||||
engine.cleanup();
|
|
||||||
Settings.cleanup();
|
Settings.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +101,8 @@ public class UpdateMojo extends BaseDependencyCheckMojo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page.
|
* Gets the description of the Dependency-Check report to be displayed in
|
||||||
|
* the Maven Generated Reports page.
|
||||||
*
|
*
|
||||||
* @param locale The Locale to get the description for
|
* @param locale The Locale to get the description for
|
||||||
* @return the description
|
* @return the description
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ Property | Description | Default Value
|
|||||||
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
|
autoUpdate | Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. | true
|
||||||
cveValidForHours | Sets the number of hours to wait before checking for new updates from the NVD. | 4
|
cveValidForHours | Sets the number of hours to wait before checking for new updates from the NVD. | 4
|
||||||
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
|
failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which means since the CVSS scores are 0-10, by default the build will never fail. | 11
|
||||||
|
failOnError | Whether the build should fail if there is an error executing the dependency-check analysis | true
|
||||||
format | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
format | The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the Site plugin unless the externalReport is set to true. | HTML
|
||||||
name | The name of the report in the site | dependency-check or dependency-check:aggregate
|
name | The name of the report in the site | dependency-check or dependency-check:aggregate
|
||||||
outputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target'
|
outputDirectory | The location to write the report(s). Note, this is not used if generating the report as part of a `mvn site` build | 'target'
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public class BaseDependencyCheckMojoTest extends BaseTest {
|
|||||||
|
|
||||||
boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
|
boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
|
||||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||||
Engine engine = new Engine(null, null);
|
MavenEngine engine = new MavenEngine(null, null);
|
||||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
|
||||||
|
|
||||||
assertTrue(engine.getDependencies().isEmpty());
|
assertTrue(engine.getDependencies().isEmpty());
|
||||||
|
|||||||
Reference in New Issue
Block a user