From e630c484ffc66ff3d745812244e0a79b637962e0 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sun, 30 Aug 2015 07:02:26 -0400 Subject: [PATCH] implementing the purge feature as requested in issue #328 --- .../taskdefs/DependencyCheckTask.java | 41 ++++++- .../src/site/markdown/configuration.md | 1 + .../java/org/owasp/dependencycheck/App.java | 24 +++- .../org/owasp/dependencycheck/CliParser.java | 2 +- .../src/site/markdown/arguments.md | 1 + .../maven/BaseDependencyCheckMojo.java | 11 +- .../dependencycheck/maven/PurgeMojo.java | 107 ++++++++++++++++++ .../src/site/markdown/configuration.md | 15 +-- 8 files changed, 191 insertions(+), 11 deletions(-) create mode 100644 dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/PurgeMojo.java diff --git a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.java b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.java index 6892dc63a..71fa3cb16 100644 --- a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.java +++ b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTask.java @@ -605,6 +605,29 @@ public class DependencyCheckTask extends Task { this.centralAnalyzerEnabled = centralAnalyzerEnabled; } + /** + * Whether or not the local copy of the NVD should be purged. + */ + private boolean purge = false; + + /** + * Used to determine if the local copy of the NVD should be purged. + * + * @return true if the local copy of the NVD should be purged + */ + public boolean isPurge() { + return purge; + } + + /** + * Set whether or not the local copy of the NVD should be purged. + * + * @param purge setting to true will cause the local copy of the NVD to be deleted. + */ + public void setPurge(boolean purge) { + this.purge = purge; + } + /** * Whether or not the nexus analyzer is enabled. */ @@ -929,7 +952,23 @@ public class DependencyCheckTask extends Task { dealWithReferences(); validateConfiguration(); populateSettings(); - + if (purge) { + File db; + try { + db = new File(Settings.getDataDirectory(), "dc.h2.db"); + if (db.exists()) { + if (db.delete()) { + log("Database file purged; local copy of the NVD has been removed", Project.MSG_INFO); + } else { + log(String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath()), Project.MSG_ERR); + } + } else { + log(String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath()), Project.MSG_ERR); + } + } catch (IOException ex) { + log("Unable to delete the database", Project.MSG_ERR); + } + } Engine engine = null; try { engine = new Engine(DependencyCheckTask.class.getClassLoader()); diff --git a/dependency-check-ant/src/site/markdown/configuration.md b/dependency-check-ant/src/site/markdown/configuration.md index 3b751cfc3..ab4e4d169 100644 --- a/dependency-check-ant/src/site/markdown/configuration.md +++ b/dependency-check-ant/src/site/markdown/configuration.md @@ -76,3 +76,4 @@ databaseDriverPath | The path to the database driver JAR file; only used if th connectionString | The connection string used to connect to the database. |   databaseUser | The username used when connecting to the database. |   databasePassword | The password used when connecting to the database. |   +purge | Delete the local copy of the NVD. This is used to force a refresh of the data. |   diff --git a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java index dbc557a61..ca5aa8e77 100644 --- a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java +++ b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/App.java @@ -37,6 +37,7 @@ import org.owasp.dependencycheck.utils.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ch.qos.logback.core.FileAppender; +import java.util.logging.Level; import org.slf4j.impl.StaticLoggerBinder; /** @@ -90,7 +91,28 @@ public class App { prepareLogger(cli.getVerboseLog()); } - if (cli.isGetVersion()) { + if (cli.isPurge()) { + if (cli.getConnectionString() != null) { + LOGGER.error("Unable to purge the database when using a non-default connection string"); + } else { + populateSettings(cli); + File db; + try { + db = new File(Settings.getDataDirectory(), "dc.h2.db"); + if (db.exists()) { + if (db.delete()) { + LOGGER.info("Database file purged; local copy of the NVD has been removed"); + } else { + LOGGER.error("Unable to delete '{}'; please delete the file manually", db.getAbsolutePath()); + } + } else { + LOGGER.error("Unable to purge database; the database file does not exists: {}", db.getAbsolutePath()); + } + } catch (IOException ex) { + LOGGER.error("Unable to delete the database"); + } + } + } else if (cli.isGetVersion()) { cli.printVersionInfo(); } else if (cli.isUpdateOnly()) { populateSettings(cli); diff --git a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java index eb91022f1..07b2ad1f8 100644 --- a/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java +++ b/dependency-check-cli/src/main/java/org/owasp/dependencycheck/CliParser.java @@ -987,7 +987,7 @@ public final class CliParser { /** * The long CLI argument name specifying that only the update phase should be executed; no scan should be run. */ - public static final String PURGE_NVD = "purgelocalnvd"; + public static final String PURGE_NVD = "purge"; /** * The long CLI argument name specifying the directory to write the reports to. */ diff --git a/dependency-check-cli/src/site/markdown/arguments.md b/dependency-check-cli/src/site/markdown/arguments.md index 0a22250ee..97c285571 100644 --- a/dependency-check-cli/src/site/markdown/arguments.md +++ b/dependency-check-cli/src/site/markdown/arguments.md @@ -56,3 +56,4 @@ Short | Argument Name        | Paramete | \-\-dbPassword | \ | The password for connecting to the database. |   | \-\-dbUser | \ | The username used to connect to the database. |   \-d | \-\-data | \ | The location of the data directory used to store persistent data. This option should generally not be set. |   + | \-\-purge | | Delete the local copy of the NVD. This is used to force a refresh of the data. |   \ No newline at end of file diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index ef223cd92..82ccaf15a 100644 --- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -233,6 +233,15 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma */ @Parameter(property = "connectionString", defaultValue = "", required = false) private String connectionString; + + /** + * Returns the connection string. + * + * @return the connection string + */ + protected String getConnectionString() { + return connectionString; + } /** * The database driver name. An example would be org.h2.Driver. */ @@ -594,7 +603,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties * required to change the proxy url, port, and connection timeout. */ - private void populateSettings() { + protected void populateSettings() { Settings.initialize(); InputStream mojoProperties = null; try { diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/PurgeMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/PurgeMojo.java new file mode 100644 index 000000000..d9f766498 --- /dev/null +++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/PurgeMojo.java @@ -0,0 +1,107 @@ +/* + * 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) 2015 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.maven; + +import java.io.File; +import java.io.IOException; +import java.util.Locale; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +import org.owasp.dependencycheck.utils.Settings; + +/** + * Maven Plugin that purges the local copy of the NVD data. + * + * @author Jeremy Long + */ +@Mojo( + name = "purge", + defaultPhase = LifecyclePhase.GENERATE_RESOURCES, + threadSafe = true, + requiresDependencyResolution = ResolutionScope.NONE, + requiresOnline = true +) +public class PurgeMojo extends BaseDependencyCheckMojo { + + /** + * Returns false; this mojo cannot generate a report. + * + * @return false + */ + @Override + public boolean canGenerateReport() { + return false; + } + + /** + * Purges the local copy of the NVD. + * + * @throws MojoExecutionException thrown if there is an exception executing the goal + * @throws MojoFailureException thrown if dependency-check is configured to fail the build + */ + @Override + public void runCheck() throws MojoExecutionException, MojoFailureException { + + if (getConnectionString() != null && !getConnectionString().isEmpty()) { + getLog().error("Unable to purge the local NVD when using a non-default connection string"); + } else { + populateSettings(); + File db; + try { + db = new File(Settings.getDataDirectory(), "dc.h2.db"); + if (db.exists()) { + if (db.delete()) { + getLog().info("Database file purged; local copy of the NVD has been removed"); + } else { + getLog().error(String.format("Unable to delete '%s'; please delete the file manually", db.getAbsolutePath())); + } + } else { + getLog().error(String.format("Unable to purge database; the database file does not exists: %s", db.getAbsolutePath())); + } + } catch (IOException ex) { + getLog().error("Unable to delete the database"); + } + Settings.cleanup(); + } + } + + /** + * Returns the report name. + * + * @param locale the location + * @return the report name + */ + public String getName(Locale locale) { + return "dependency-check-purge"; + } + + /** + * 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 + * @return the description + */ + public String getDescription(Locale locale) { + return "Purges the local cache of the NVD dataT."; + } + +} diff --git a/dependency-check-maven/src/site/markdown/configuration.md b/dependency-check-maven/src/site/markdown/configuration.md index afe2e9e99..7bc6afcd7 100644 --- a/dependency-check-maven/src/site/markdown/configuration.md +++ b/dependency-check-maven/src/site/markdown/configuration.md @@ -6,6 +6,7 @@ Goal | Description aggregate | Runs dependency-check against the child projects and aggregates the results into a single report. check | Runs dependency-check against the project and generates a report. update-only | Updates the local cache of the NVD data from NIST. +purge | Deletes the local copy of the NVD. This is used to force a refresh of the data. Configuration ==================== @@ -49,13 +50,13 @@ Advanced Configuration The following properties can be configured in the plugin. However, they are less frequently changed. One exception may be the cvedUrl properties, which can be used to host a mirror of the NVD within an enterprise environment. -Property | Description | Default Value ----------------------|--------------------------------------------------------------------------|------------------ -cveUrl12Modified | URL for the modified CVE 1.2. | http://nvd.nist.gov/download/nvdcve-modified.xml -cveUrl20Modified | URL for the modified CVE 2.0. | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml -cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year. | http://nvd.nist.gov/download/nvdcve-%d.xml -cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year. | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml -connectionTimeout | Sets the URL Connection Timeout used when downloading external data. |   +Property | Description | Default Value +---------------------|---------------------------------------------------------------------------------------------|------------------ +cveUrl12Modified | URL for the modified CVE 1.2. | http://nvd.nist.gov/download/nvdcve-modified.xml +cveUrl20Modified | URL for the modified CVE 2.0. | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml +cveUrl12Base | Base URL for each year's CVE 1.2, the %d will be replaced with the year. | http://nvd.nist.gov/download/nvdcve-%d.xml +cveUrl20Base | Base URL for each year's CVE 2.0, the %d will be replaced with the year. | http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml +connectionTimeout | Sets the URL Connection Timeout used when downloading external data. |   dataDirectory | Sets the data directory to hold SQL CVEs contents. This should generally not be changed. |   databaseDriverName | The name of the database driver. Example: org.h2.Driver. |   databaseDriverPath | The path to the database driver JAR file; only used if the driver is not in the class path. |