From 97b2e1a4da1060754da7835cd559118da52f3bc1 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Tue, 14 Mar 2017 09:06:17 -0400 Subject: [PATCH 1/6] added documentation per issue https://github.com/jeremylong/dependency-check-gradle/issues/38 --- .../markdown/dependency-check-gradle/configuration-purge.md | 5 +++++ .../markdown/dependency-check-gradle/configuration-update.md | 1 + src/site/markdown/dependency-check-gradle/configuration.md | 1 + 3 files changed, 7 insertions(+) diff --git a/src/site/markdown/dependency-check-gradle/configuration-purge.md b/src/site/markdown/dependency-check-gradle/configuration-purge.md index 00b5bba6d..3e4c136ce 100644 --- a/src/site/markdown/dependency-check-gradle/configuration-purge.md +++ b/src/site/markdown/dependency-check-gradle/configuration-purge.md @@ -9,6 +9,11 @@ dependencyCheckPurge | Deletes the local copy of Configuration: dependencyCheckPurge ==================== +The following properties can be configured for the dependencyCheckPurge task: + +Property | Description | Default Value +---------------------|------------------------------------|------------------ +failOnError | Fails the build if an error occurs during the dependency-check analysis. | true #### Example ```groovy diff --git a/src/site/markdown/dependency-check-gradle/configuration-update.md b/src/site/markdown/dependency-check-gradle/configuration-update.md index e83f2dc03..f3ab37d35 100644 --- a/src/site/markdown/dependency-check-gradle/configuration-update.md +++ b/src/site/markdown/dependency-check-gradle/configuration-update.md @@ -14,6 +14,7 @@ The following properties can be configured for the dependencyCheckUpdate task: Property | Description | Default Value ---------------------|------------------------------------|------------------ cveValidForHours | Sets the number of hours to wait before checking for new updates from the NVD. | 4 +failOnError | Fails the build if an error occurs during the dependency-check analysis. | true #### Example ```groovy diff --git a/src/site/markdown/dependency-check-gradle/configuration.md b/src/site/markdown/dependency-check-gradle/configuration.md index 7e4183d74..f33730a01 100644 --- a/src/site/markdown/dependency-check-gradle/configuration.md +++ b/src/site/markdown/dependency-check-gradle/configuration.md @@ -15,6 +15,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 cveValidForHours | Sets the number of hours to wait before checking for new updates from the NVD. | 4 +failOnError | Fails the build if an error occurs during the dependency-check analysis. | true failBuildOnCVSS | Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11; since the CVSS scores are 0-10, by default the build will never fail. | 11 format | The report format to be generated (HTML, XML, VULN, ALL). | HTML outputDirectory | The location to write the report(s). This directory will be located in the build directory. | build/reports From 947499726a39c07f032a141431971a17af2b4910 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Wed, 15 Mar 2017 07:36:28 -0400 Subject: [PATCH 2/6] initial attempt --- .../taskdefs/DependencyCheckTaskTest.java | 8 ++++- .../dependencycheck/data/nvdcve/CveDB.java | 31 ++++++++++--------- .../owasp/dependencycheck/BaseDBTestCase.java | 1 + .../update/NvdCveUpdaterIntegrationTest.java | 4 +-- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java b/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java index de9f62c1e..5cb27bdc3 100644 --- a/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java +++ b/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java @@ -30,6 +30,8 @@ import org.owasp.dependencycheck.BaseDBTestCase; import org.owasp.dependencycheck.utils.Settings; import static org.junit.Assert.assertTrue; +import org.owasp.dependencycheck.data.nvdcve.CveDB; +import org.owasp.dependencycheck.data.nvdcve.DatabaseException; /** @@ -48,6 +50,7 @@ public class DependencyCheckTaskTest { public void setUp() throws Exception { Settings.initialize(); BaseDBTestCase.ensureDBExists(); + CveDB.getInstance().openDatabase(); final String buildFile = this.getClass().getClassLoader().getResource("build.xml").getPath(); buildFileRule.configureProject(buildFile); } @@ -57,6 +60,10 @@ public class DependencyCheckTaskTest { //no cleanup... //executeTarget("cleanup"); Settings.cleanup(true); + try { + CveDB.getInstance().closeDatabase(); + } catch (DatabaseException ex) { + } } /** @@ -73,7 +80,6 @@ public class DependencyCheckTaskTest { buildFileRule.executeTarget("test.fileset"); assertTrue("DependencyCheck report was not generated", report.exists()); - } /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java index 0a966a24b..ffaabf023 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java @@ -75,7 +75,7 @@ public final class CveDB { /** * The bundle of statements used when accessing the database. */ - private final ResourceBundle statementBundle; + private ResourceBundle statementBundle; /** * Database properties object containing the 'properties' from the database * table. @@ -84,7 +84,7 @@ public final class CveDB { /** * The prepared statements. */ - private final EnumMap preparedStatements; + private EnumMap preparedStatements; /** * The enum value names must match the keys of the statements in the @@ -203,12 +203,6 @@ public final class CveDB { */ private CveDB() throws DatabaseException { openDatabase(); - final String databaseProductName = determineDatabaseProductName(); - statementBundle = databaseProductName != null - ? ResourceBundle.getBundle("data/dbStatements", new Locale(databaseProductName)) - : ResourceBundle.getBundle("data/dbStatements"); - preparedStatements = prepareStatements(); - databaseProperties = new DatabaseProperties(this); } /** @@ -237,6 +231,12 @@ public final class CveDB { public synchronized void openDatabase() throws DatabaseException { if (!isOpen()) { connection = ConnectionFactory.getConnection(); + final String databaseProductName = determineDatabaseProductName(); + statementBundle = databaseProductName != null + ? ResourceBundle.getBundle("data/dbStatements", new Locale(databaseProductName)) + : ResourceBundle.getBundle("data/dbStatements"); + preparedStatements = prepareStatements(); + databaseProperties = new DatabaseProperties(this); } } @@ -257,7 +257,8 @@ public final class CveDB { LOGGER.debug("", ex); } connection = null; - instance = null; + preparedStatements = null; + databaseProperties = null; } } @@ -266,7 +267,7 @@ public final class CveDB { * * @return whether the database connection is open or closed */ - private boolean isOpen() { + private synchronized boolean isOpen() { return connection != null; } @@ -277,7 +278,7 @@ public final class CveDB { * @throws DatabaseException thrown if there is an error preparing the * statements */ - private EnumMap prepareStatements() + private synchronized EnumMap prepareStatements() throws DatabaseException { final EnumMap result = new EnumMap<>(PreparedStatementCveDb.class); @@ -301,7 +302,7 @@ public final class CveDB { /** * Closes all prepared statements. */ - private void closeStatements() { + private synchronized void closeStatements() { for (PreparedStatement preparedStatement : preparedStatements.values()) { DBUtils.closeStatement(preparedStatement); } @@ -315,7 +316,7 @@ public final class CveDB { * @return the prepared statement * @throws SQLException thrown if a SQL Exception occurs */ - private PreparedStatement getPreparedStatement(PreparedStatementCveDb key) throws SQLException { + private synchronized PreparedStatement getPreparedStatement(PreparedStatementCveDb key) throws SQLException { final PreparedStatement preparedStatement = preparedStatements.get(key); preparedStatement.clearParameters(); return preparedStatement; @@ -351,7 +352,7 @@ public final class CveDB { * * @return the value of databaseProperties */ - public DatabaseProperties getDatabaseProperties() { + public synchronized DatabaseProperties getDatabaseProperties() { return databaseProperties; } @@ -360,7 +361,7 @@ public final class CveDB { * * @return the database properties */ - protected DatabaseProperties reloadProperties() { + protected synchronized DatabaseProperties reloadProperties() { databaseProperties = new DatabaseProperties(this); return databaseProperties; } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java index 5582c69f8..79e372d13 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java @@ -51,6 +51,7 @@ public abstract class BaseDBTestCase extends BaseTest { @Before public void setUpDb() throws Exception { ensureDBExists(); + CveDB.getInstance().openDatabase(); } @AfterClass diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.java index d2305a956..5ebe3351f 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.java @@ -20,7 +20,7 @@ package org.owasp.dependencycheck.data.update; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import org.junit.Test; -import org.owasp.dependencycheck.BaseTest; +import org.owasp.dependencycheck.BaseDBTestCase; import org.owasp.dependencycheck.data.update.exception.UpdateException; import org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve; @@ -28,7 +28,7 @@ import org.owasp.dependencycheck.data.update.nvd.UpdateableNvdCve; * * @author Jeremy Long */ -public class NvdCveUpdaterIntegrationTest extends BaseTest { +public class NvdCveUpdaterIntegrationTest extends BaseDBTestCase { public NvdCveUpdater getUpdater() { NvdCveUpdater instance = new NvdCveUpdater(); From a23d127c62ddf00907441d37fedac884d32460fa Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 25 Mar 2017 09:05:51 -0400 Subject: [PATCH 3/6] initial fix for CveDB singleton --- .../owasp/dependencycheck/taskdefs/Check.java | 5 +- .../java/org/owasp/dependencycheck/App.java | 1 + .../org/owasp/dependencycheck/Engine.java | 7 +- .../agent/DependencyCheckScanAgent.java | 2 + .../dependencycheck/analyzer/CPEAnalyzer.java | 4 + .../analyzer/NvdCveAnalyzer.java | 1 + .../analyzer/RubyBundleAuditAnalyzer.java | 8 ++ .../dependencycheck/data/nvdcve/CveDB.java | 85 +++++++++++-------- .../data/update/EngineVersionCheck.java | 7 +- .../data/update/NvdCveUpdater.java | 3 + .../owasp/dependencycheck/BaseDBTestCase.java | 5 -- .../EngineIntegrationTest.java | 1 + .../analyzer/RubyBundleAuditAnalyzerTest.java | 17 ++-- .../data/nvdcve/CveDBIntegrationTest.java | 6 ++ .../data/nvdcve/CveDBMySQLTest.java | 8 +- .../DatabasePropertiesIntegrationTest.java | 5 ++ .../ReportGeneratorIntegrationTest.java | 1 + .../maven/BaseDependencyCheckMojo.java | 1 + 18 files changed, 108 insertions(+), 59 deletions(-) diff --git a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java index c68fefdb8..426f90cc0 100644 --- a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java +++ b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java @@ -941,13 +941,14 @@ public class Check extends Update { } } DatabaseProperties prop = null; - CveDB cve; try { - cve = CveDB.getInstance(); + final CveDB cve = CveDB.getInstance(); prop = cve.getDatabaseProperties(); } catch (DatabaseException ex) { //TODO shouldn't this be a fatal exception log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); + } finally { + CveDB.close(); } final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); 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 506ae0cac..b8a0abe19 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 @@ -285,6 +285,7 @@ public class App { final CveDB cve = CveDB.getInstance(); final DatabaseProperties prop = cve.getDatabaseProperties(); final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop); + CveDB.close(); try { report.generateReports(reportDirectory, outputFormat); } catch (ReportException ex) { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java index 14c9a4e2a..8be22c518 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java @@ -126,11 +126,7 @@ public class Engine implements FileFilter { * Properly cleans up resources allocated during analysis. */ public void cleanup() { - try { - CveDB.getInstance().closeDatabase(); - } catch (DatabaseException ex) { - LOGGER.trace("Error closing the database", ex); - } + CveDB.close(); ConnectionFactory.cleanup(); } @@ -754,6 +750,7 @@ public class Engine implements FileFilter { if (!cve.dataExists()) { throw new NoDataException("No documents exist"); } + CveDB.close(); } /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java index eafdb7b1e..b6c35acef 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java @@ -850,6 +850,8 @@ public class DependencyCheckScanAgent { } catch (DatabaseException ex) { //TODO shouldn't this throw an exception or return? LOGGER.debug("Unable to retrieve DB Properties", ex); + } finally { + CveDB.close(); } final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); try { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java index 455e6689c..f30127e35 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java @@ -182,6 +182,10 @@ public class CPEAnalyzer extends AbstractAnalyzer { */ @Override public void closeAnalyzer() { + if (cve != null) { + CveDB.close(); + cve = null; + } if (cpe != null) { cpe.close(); cpe = null; diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java index 10525ee62..e254932af 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java @@ -68,6 +68,7 @@ public class NvdCveAnalyzer extends AbstractAnalyzer { */ @Override public void closeAnalyzer() { + CveDB.close(); cveDB = null; } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java index f8239eadf..bd7b79b7c 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java @@ -208,6 +208,14 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } } + /** + * Closes the data source. + */ + @Override + public void closeAnalyzer() { + CveDB.close(); + cvedb = null; + } /** * Returns the name of the analyzer. * diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java index 0a966a24b..1e6b737b6 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java @@ -64,6 +64,11 @@ public final class CveDB { * Singleton instance of the CveDB. */ private static CveDB instance = null; + /** + * Track the number of current users of the CveDB; so that if someone is + * using database another user cannot close the connection on them. + */ + private int usageCount = 0; /** * The logger. */ @@ -75,7 +80,7 @@ public final class CveDB { /** * The bundle of statements used when accessing the database. */ - private final ResourceBundle statementBundle; + private ResourceBundle statementBundle; /** * Database properties object containing the 'properties' from the database * table. @@ -84,7 +89,7 @@ public final class CveDB { /** * The prepared statements. */ - private final EnumMap preparedStatements; + private final EnumMap preparedStatements = new EnumMap<>(PreparedStatementCveDb.class); /** * The enum value names must match the keys of the statements in the @@ -191,6 +196,10 @@ public final class CveDB { if (instance == null) { instance = new CveDB(); } + if (!instance.isOpen()) { + instance.open(); + } + instance.usageCount += 1; return instance; } @@ -202,23 +211,17 @@ public final class CveDB { * database. */ private CveDB() throws DatabaseException { - openDatabase(); - final String databaseProductName = determineDatabaseProductName(); - statementBundle = databaseProductName != null - ? ResourceBundle.getBundle("data/dbStatements", new Locale(databaseProductName)) - : ResourceBundle.getBundle("data/dbStatements"); - preparedStatements = prepareStatements(); - databaseProperties = new DatabaseProperties(this); } /** * Tries to determine the product name of the database. * + * @param conn the database connection * @return the product name of the database if successful, {@code null} else */ - private synchronized String determineDatabaseProductName() { + private static String determineDatabaseProductName(Connection conn) { try { - final String databaseProductName = connection.getMetaData().getDatabaseProductName(); + final String databaseProductName = conn.getMetaData().getDatabaseProductName(); LOGGER.debug("Database product: {}", databaseProductName); return databaseProductName; } catch (SQLException se) { @@ -234,30 +237,42 @@ public final class CveDB { * @throws DatabaseException thrown if there is an error opening the * database connection */ - public synchronized void openDatabase() throws DatabaseException { - if (!isOpen()) { - connection = ConnectionFactory.getConnection(); + private synchronized void open() throws DatabaseException { + if (!instance.isOpen()) { + instance.connection = ConnectionFactory.getConnection(); + final String databaseProductName = determineDatabaseProductName(instance.connection); + instance.statementBundle = databaseProductName != null + ? ResourceBundle.getBundle("data/dbStatements", new Locale(databaseProductName)) + : ResourceBundle.getBundle("data/dbStatements"); + instance.prepareStatements(); + instance.databaseProperties = new DatabaseProperties(instance); } } /** - * Closes the DB4O database. Close should be called on this object when it - * is done being used. + * Closes the database connection. Close should be called on this object + * when it is done being used. */ - public synchronized void closeDatabase() { - if (isOpen()) { - closeStatements(); - try { - connection.close(); - } catch (SQLException ex) { - LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); - LOGGER.debug("", ex); - } catch (Throwable ex) { - LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); - LOGGER.debug("", ex); + public static synchronized void close() { + if (instance != null) { + instance.usageCount -= 1; + if (instance.usageCount <= 0 && instance.isOpen()) { + instance.usageCount = 0; + instance.closeStatements(); + try { + instance.connection.close(); + } catch (SQLException ex) { + LOGGER.error("There was an error attempting to close the CveDB, see the log for more details."); + LOGGER.debug("", ex); + } catch (Throwable ex) { + LOGGER.error("There was an exception attempting to close the CveDB, see the log for more details."); + LOGGER.debug("", ex); + } + instance.statementBundle = null; + instance.preparedStatements.clear(); + instance.databaseProperties = null; + instance.connection = null; } - connection = null; - instance = null; } } @@ -271,16 +286,13 @@ public final class CveDB { } /** - * Prepares all statements to be used and returns them. + * Prepares all statements to be used. * - * @return the prepared statements * @throws DatabaseException thrown if there is an error preparing the * statements */ - private EnumMap prepareStatements() + private void prepareStatements() throws DatabaseException { - - final EnumMap result = new EnumMap<>(PreparedStatementCveDb.class); for (PreparedStatementCveDb key : values()) { final String statementString = statementBundle.getString(key.name()); final PreparedStatement preparedStatement; @@ -293,9 +305,8 @@ public final class CveDB { } catch (SQLException exception) { throw new DatabaseException(exception); } - result.put(key, preparedStatement); + preparedStatements.put(key, preparedStatement); } - return result; } /** @@ -342,7 +353,7 @@ public final class CveDB { @SuppressWarnings("FinalizeDeclaration") protected void finalize() throws Throwable { LOGGER.debug("Entering finalize"); - closeDatabase(); + close(); super.finalize(); } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java index ad25e6ae4..7aa65a9b1 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java @@ -94,6 +94,7 @@ public class EngineVersionCheck implements CachedWebDataSource { @Override public void update() throws UpdateException { try { + CveDB db = CveDB.getInstance(); final boolean autoupdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE, true); final boolean enabled = Settings.getBoolean(Settings.KEYS.UPDATE_VERSION_CHECK_ENABLED, true); final String original = Settings.getString(Settings.KEYS.CVE_ORIGINAL_MODIFIED_20_URL); @@ -105,7 +106,9 @@ public class EngineVersionCheck implements CachedWebDataSource { */ if (enabled && autoupdate && original != null && original.equals(current)) { LOGGER.debug("Begin Engine Version Check"); - final DatabaseProperties properties = CveDB.getInstance().getDatabaseProperties(); + + final DatabaseProperties properties = db.getDatabaseProperties(); + final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0")); final long now = System.currentTimeMillis(); updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, ""); @@ -124,6 +127,8 @@ public class EngineVersionCheck implements CachedWebDataSource { throw new UpdateException("Error occurred updating database properties."); } catch (InvalidSettingException ex) { LOGGER.debug("Unable to determine if autoupdate is enabled", ex); + } finally { + CveDB.close(); } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java index 80ebb1bf6..98a12d958 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java @@ -139,6 +139,7 @@ public class NvdCveUpdater implements CachedWebDataSource { throw new UpdateException("Database Exception, unable to update the data to use the most current data.", ex); } finally { shutdownExecutorServices(); + CveDB.close(); } } @@ -206,6 +207,8 @@ public class NvdCveUpdater implements CachedWebDataSource { return cve.dataExists(); } catch (DatabaseException ex) { return false; + } finally { + CveDB.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java index 5582c69f8..fb0e17448 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java @@ -53,11 +53,6 @@ public abstract class BaseDBTestCase extends BaseTest { ensureDBExists(); } - @AfterClass - public static void tearDownClass() throws Exception { - CveDB.getInstance().closeDatabase(); - } - public static void ensureDBExists() throws Exception { File f = new File("./target/data/dc.h2.db"); if (f.exists() && f.isFile() && f.length() < 71680) { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java index 5a78871c1..85958a39c 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java @@ -73,6 +73,7 @@ public class EngineIntegrationTest extends BaseDBTestCase { } CveDB cveDB = CveDB.getInstance(); DatabaseProperties dbProp = cveDB.getDatabaseProperties(); + CveDB.close(); ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); rg.generateReports("./target/", "ALL"); instance.cleanup(); diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java index ff5a4a9e1..d2e655ac7 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java @@ -53,7 +53,7 @@ import org.owasp.dependencycheck.exception.InitializationException; * @author Dale Visser */ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { - + private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); /** @@ -117,7 +117,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { analyzer.analyze(result, engine); int size = engine.getDependencies().size(); assertTrue(size >= 1); - + Dependency dependency = engine.getDependencies().get(0); assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); @@ -136,16 +136,16 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { public void testAddCriticalityToVulnerability() throws AnalysisException, DatabaseException { try { analyzer.initialize(); - + final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "ruby/vulnerable/gems/sinatra/Gemfile.lock")); final Engine engine = new Engine(); analyzer.analyze(result, engine); - + Dependency dependency = engine.getDependencies().get(0); Vulnerability vulnerability = dependency.getVulnerabilities().first(); assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0); - + } catch (InitializationException | DatabaseException | AnalysisException e) { LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\"."); Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); @@ -166,6 +166,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { analyzer.initialize(); } catch (Exception e) { //expected, so ignore. + LOGGER.error("Exception", e); } finally { assertThat(analyzer.isEnabled(), is(false)); LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); @@ -197,14 +198,14 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { while (dIterator.hasNext()) { Dependency dept = dIterator.next(); LOGGER.info("dept path: " + dept.getActualFilePath()); - + Set identifiers = dept.getIdentifiers(); Iterator idIterator = identifiers.iterator(); while (idIterator.hasNext()) { Identifier id = idIterator.next(); LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence()); } - + Set prodEv = dept.getProductEvidence().getEvidence(); Iterator it = prodEv.iterator(); while (it.hasNext()) { @@ -217,7 +218,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { Evidence e = vIt.next(); LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); } - + Set vendorEv = dept.getVendorEvidence().getEvidence(); Iterator vendorIt = vendorEv.iterator(); while (vendorIt.hasNext()) { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java index 54ad59c88..916f9462d 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java @@ -51,6 +51,8 @@ public class CveDBIntegrationTest extends BaseDBTestCase { instance.commit(); } catch (DatabaseException | SQLException ex) { fail(ex.getMessage()); + } finally { + CveDB.close(); } } @@ -64,6 +66,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { String product = "struts"; Set result = instance.getCPEs(vendor, product); assertTrue(result.size() > 5); + CveDB.close(); } /** @@ -74,6 +77,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { CveDB instance = CveDB.getInstance(); Vulnerability result = instance.getVulnerability("CVE-2014-0094"); assertEquals("The ParametersInterceptor in Apache Struts before 2.3.16.1 allows remote attackers to \"manipulate\" the ClassLoader via the class parameter, which is passed to the getClass method.", result.getDescription()); + CveDB.close(); } /** @@ -110,6 +114,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { } } assertTrue("Expected " + expected + ", but was not identified", found); + CveDB.close(); } /** @@ -165,5 +170,6 @@ public class CveDBIntegrationTest extends BaseDBTestCase { identifiedVersion = new DependencyVersion("1.6.3"); results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); assertNotNull(results); + CveDB.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java index 99e2b3581..dbe7d22bc 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java @@ -44,6 +44,8 @@ public class CveDBMySQLTest extends BaseTest { } catch (DatabaseException ex) { System.out.println("Unable to connect to the My SQL database; verify that the db server is running and that the schema has been generated"); fail(ex.getMessage()); + } finally { + CveDB.close(); } } @@ -61,6 +63,8 @@ public class CveDBMySQLTest extends BaseTest { } catch (Exception ex) { System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); throw ex; + } finally { + CveDB.close(); } } @@ -77,6 +81,8 @@ public class CveDBMySQLTest extends BaseTest { } catch (Exception ex) { System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); throw ex; - } + } finally { + CveDB.close(); + } } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java index 6c6af8bcf..6067f8e40 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java @@ -41,6 +41,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { assertNotNull(instance); //no exception means the call worked... whether or not it is empty depends on if the db is new //assertEquals(expResult, result); + CveDB.close(); } /** @@ -59,6 +60,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { instance = cveDB.reloadProperties(); long results = Long.parseLong(instance.getProperty("NVD CVE " + key)); assertEquals(expected, results); + CveDB.close(); } /** @@ -73,6 +75,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { String expResult = "default"; String result = instance.getProperty(key, defaultValue); assertEquals(expResult, result); + CveDB.close(); } /** @@ -87,6 +90,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { double version = Double.parseDouble(result); assertTrue(version >= 2.8); assertTrue(version <= 10); + CveDB.close(); } /** @@ -98,5 +102,6 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { DatabaseProperties instance = cveDB.getDatabaseProperties(); Properties result = instance.getProperties(); assertTrue(result.size() > 0); + CveDB.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java index f379d332d..0b9e72390 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java @@ -149,6 +149,7 @@ public class ReportGeneratorIntegrationTest extends BaseDBTestCase { ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp); generator.generateReport(templateName, writeTo); + CveDB.close(); engine.cleanup(); 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 d2e95260c..629d722a4 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 @@ -1017,6 +1017,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } } final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); + CveDB.close(); try { r.generateReports(outputDir.getAbsolutePath(), format); } catch (ReportException ex) { From 109f5c22e99f499a551e686037295698f13b7757 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 25 Mar 2017 09:06:34 -0400 Subject: [PATCH 4/6] initial fix for CveDB singleton --- .../dependencycheck/data/update/EngineVersionCheck.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java index 7aa65a9b1..6958d6ba7 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java @@ -94,7 +94,7 @@ public class EngineVersionCheck implements CachedWebDataSource { @Override public void update() throws UpdateException { try { - CveDB db = CveDB.getInstance(); + final CveDB db = CveDB.getInstance(); final boolean autoupdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE, true); final boolean enabled = Settings.getBoolean(Settings.KEYS.UPDATE_VERSION_CHECK_ENABLED, true); final String original = Settings.getString(Settings.KEYS.CVE_ORIGINAL_MODIFIED_20_URL); @@ -106,9 +106,9 @@ public class EngineVersionCheck implements CachedWebDataSource { */ if (enabled && autoupdate && original != null && original.equals(current)) { LOGGER.debug("Begin Engine Version Check"); - + final DatabaseProperties properties = db.getDatabaseProperties(); - + final long lastChecked = Long.parseLong(properties.getProperty(ENGINE_VERSION_CHECKED_ON, "0")); final long now = System.currentTimeMillis(); updateToVersion = properties.getProperty(CURRENT_ENGINE_RELEASE, ""); From e2a1a595431161034d97e8ae2aab0c4679f0b7e9 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Fri, 31 Mar 2017 06:58:37 -0400 Subject: [PATCH 5/6] fixed issues related to making the cveDb a singleton --- .../owasp/dependencycheck/taskdefs/Check.java | 5 +- .../taskdefs/DependencyCheckTaskTest.java | 6 -- .../java/org/owasp/dependencycheck/App.java | 11 ++- .../org/owasp/dependencycheck/Engine.java | 80 +++++++++++++------ .../agent/DependencyCheckScanAgent.java | 8 +- .../dependencycheck/analyzer/CPEAnalyzer.java | 2 +- .../analyzer/NvdCveAnalyzer.java | 2 +- .../analyzer/RubyBundleAuditAnalyzer.java | 13 +-- .../data/nvdcve/ConnectionFactory.java | 20 ++++- .../dependencycheck/data/nvdcve/CveDB.java | 7 +- .../data/update/EngineVersionCheck.java | 5 +- .../data/update/NvdCveUpdater.java | 27 +++---- .../owasp/dependencycheck/BaseDBTestCase.java | 1 - .../EngineIntegrationTest.java | 9 ++- .../analyzer/RubyBundleAuditAnalyzerTest.java | 26 +++--- .../data/nvdcve/CveDBIntegrationTest.java | 12 +-- .../data/nvdcve/CveDBMySQLTest.java | 13 +-- .../DatabasePropertiesIntegrationTest.java | 10 +-- .../ReportGeneratorIntegrationTest.java | 2 +- .../maven/BaseDependencyCheckMojo.java | 4 +- 20 files changed, 153 insertions(+), 110 deletions(-) diff --git a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java index 426f90cc0..5cc1e8226 100644 --- a/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java +++ b/dependency-check-ant/src/main/java/org/owasp/dependencycheck/taskdefs/Check.java @@ -941,14 +941,11 @@ public class Check extends Update { } } DatabaseProperties prop = null; - try { - final CveDB cve = CveDB.getInstance(); + try (CveDB cve = CveDB.getInstance()) { prop = cve.getDatabaseProperties(); } catch (DatabaseException ex) { //TODO shouldn't this be a fatal exception log("Unable to retrieve DB Properties", ex, Project.MSG_DEBUG); - } finally { - CveDB.close(); } final ReportGenerator reporter = new ReportGenerator(getProjectName(), engine.getDependencies(), engine.getAnalyzers(), prop); diff --git a/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java b/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java index 5cb27bdc3..04a6b4c44 100644 --- a/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java +++ b/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java @@ -33,7 +33,6 @@ import static org.junit.Assert.assertTrue; import org.owasp.dependencycheck.data.nvdcve.CveDB; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; - /** * * @author Jeremy Long @@ -50,7 +49,6 @@ public class DependencyCheckTaskTest { public void setUp() throws Exception { Settings.initialize(); BaseDBTestCase.ensureDBExists(); - CveDB.getInstance().openDatabase(); final String buildFile = this.getClass().getClassLoader().getResource("build.xml").getPath(); buildFileRule.configureProject(buildFile); } @@ -60,10 +58,6 @@ public class DependencyCheckTaskTest { //no cleanup... //executeTarget("cleanup"); Settings.cleanup(true); - try { - CveDB.getInstance().closeDatabase(); - } catch (DatabaseException ex) { - } } /** 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 b8a0abe19..52c6fce77 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 @@ -282,10 +282,15 @@ public class App { exCol = ex; } final List dependencies = engine.getDependencies(); - final CveDB cve = CveDB.getInstance(); - final DatabaseProperties prop = cve.getDatabaseProperties(); + DatabaseProperties prop = null; + try (CveDB cve = CveDB.getInstance()) { + prop = cve.getDatabaseProperties(); + } catch (DatabaseException ex) { + //TODO shouldn't this be a fatal exception + LOGGER.debug("Unable to retrieve DB Properties", ex); + } final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop); - CveDB.close(); + try { report.generateReports(reportDirectory, outputFormat); } catch (ReportException ex) { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java index 8be22c518..bfbc066c8 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/Engine.java @@ -38,6 +38,7 @@ import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileFilter; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -83,6 +84,10 @@ public class Engine implements FileFilter { * services. */ private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader(); + /** + * A reference to the database. + */ + private CveDB database = null; /** * The Logger for use throughout the class. */ @@ -126,7 +131,10 @@ public class Engine implements FileFilter { * Properly cleans up resources allocated during analysis. */ public void cleanup() { - CveDB.close(); + if (database != null) { + database.close(); + database = null; + } ConnectionFactory.cleanup(); } @@ -479,31 +487,14 @@ public class Engine implements FileFilter { */ public void analyzeDependencies() throws ExceptionCollection { final List exceptions = Collections.synchronizedList(new ArrayList()); - boolean autoUpdate = true; - try { - autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); - } catch (InvalidSettingException ex) { - LOGGER.debug("Invalid setting for auto-update; using true."); - exceptions.add(ex); - } - if (autoUpdate) { - try { - doUpdates(); - } catch (UpdateException ex) { - exceptions.add(ex); - LOGGER.warn("Unable to update Cached Web DataSource, using local " - + "data instead. Results may not include recent vulnerabilities."); - LOGGER.debug("Update Error", ex); - } - } + + initializeAndUpdateDatabase(exceptions); //need to ensure that data exists try { ensureDataExists(); } catch (NoDataException ex) { throwFatalExceptionCollection("Unable to continue dependency-check analysis.", ex, exceptions); - } catch (DatabaseException ex) { - throwFatalExceptionCollection("Unable to connect to the dependency-check database.", ex, exceptions); } LOGGER.debug("\n----------------------------------------------------\nBEGIN ANALYSIS\n----------------------------------------------------"); @@ -550,6 +541,47 @@ public class Engine implements FileFilter { } } + /** + * Performs any necessary updates and initializes the database. + * + * @param exceptions a collection to store non-fatal exceptions + * @throws ExceptionCollection thrown if fatal exceptions occur + */ + private void initializeAndUpdateDatabase(final List exceptions) throws ExceptionCollection { + boolean autoUpdate = true; + try { + autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); + } catch (InvalidSettingException ex) { + LOGGER.debug("Invalid setting for auto-update; using true."); + exceptions.add(ex); + } + if (autoUpdate) { + try { + database = CveDB.getInstance(); + doUpdates(); + } catch (UpdateException ex) { + exceptions.add(ex); + LOGGER.warn("Unable to update Cached Web DataSource, using local " + + "data instead. Results may not include recent vulnerabilities."); + LOGGER.debug("Update Error", ex); + } catch (DatabaseException ex) { + throw new ExceptionCollection("Unable to connect to the database", ex); + } + } else { + try { + if (ConnectionFactory.isH2Connection() && !ConnectionFactory.h2DataFileExists()) { + throw new ExceptionCollection(new NoDataException("Autoupdate is disabled and the database does not exist"), true); + } else { + database = CveDB.getInstance(); + } + } catch (IOException ex) { + throw new ExceptionCollection(new DatabaseException("Autoupdate is disabled and unable to connect to the database"), true); + } catch (DatabaseException ex) { + throwFatalExceptionCollection("Unable to connect to the dependency-check database.", ex, exceptions); + } + } + } + /** * Executes executes the analyzer using multiple threads. * @@ -742,15 +774,11 @@ public class Engine implements FileFilter { * NoDataException is thrown. * * @throws NoDataException thrown if no data exists in the CPE Index - * @throws DatabaseException thrown if there is an exception opening the - * database */ - private void ensureDataExists() throws NoDataException, DatabaseException { - final CveDB cve = CveDB.getInstance(); - if (!cve.dataExists()) { + private void ensureDataExists() throws NoDataException { + if (database == null || !database.dataExists()) { throw new NoDataException("No documents exist"); } - CveDB.close(); } /** diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java index b6c35acef..2ee63b1f6 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/agent/DependencyCheckScanAgent.java @@ -843,15 +843,11 @@ public class DependencyCheckScanAgent { */ private void generateExternalReports(Engine engine, File outDirectory) { DatabaseProperties prop = null; - CveDB cve; - try { - cve = CveDB.getInstance(); + try (CveDB cve = CveDB.getInstance()) { prop = cve.getDatabaseProperties(); } catch (DatabaseException ex) { - //TODO shouldn't this throw an exception or return? + //TODO shouldn't this be a fatal exception LOGGER.debug("Unable to retrieve DB Properties", ex); - } finally { - CveDB.close(); } final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop); try { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java index f30127e35..14177fa9b 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CPEAnalyzer.java @@ -183,7 +183,7 @@ public class CPEAnalyzer extends AbstractAnalyzer { @Override public void closeAnalyzer() { if (cve != null) { - CveDB.close(); + cve.close(); cve = null; } if (cpe != null) { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java index e254932af..c3cdedf2f 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NvdCveAnalyzer.java @@ -68,7 +68,7 @@ public class NvdCveAnalyzer extends AbstractAnalyzer { */ @Override public void closeAnalyzer() { - CveDB.close(); + cveDB.close(); cveDB = null; } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java index bd7b79b7c..e872dd050 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzer.java @@ -132,7 +132,8 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { LOGGER.info("Launching: " + args + " from " + folder); return builder.start(); } catch (IOException ioe) { - throw new AnalysisException("bundle-audit failure", ioe); + throw new AnalysisException("bundle-audit initialization failure; this error can be ignored if you are not analyzing Ruby. " + + "Otherwise ensure that bundle-audit is installed and the path to bundle audit is correctly specified", ioe); } } @@ -159,7 +160,6 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } catch (AnalysisException ae) { setEnabled(false); - cvedb = null; final String msg = String.format("Exception from bundle-audit process: %s. Disabling %s", ae.getCause(), ANALYZER_NAME); throw new InitializationException(msg, ae); } catch (IOException ex) { @@ -208,14 +208,17 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { } } - /** + /** * Closes the data source. */ @Override public void closeAnalyzer() { - CveDB.close(); - cvedb = null; + if (cvedb != null) { + cvedb.close(); + cvedb = null; + } } + /** * Returns the name of the analyzer. * diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java index b901231b4..4402fd341 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/ConnectionFactory.java @@ -241,13 +241,31 @@ public final class ConnectionFactory { * @throws IOException thrown if the data directory does not exist and * cannot be created */ - private static boolean h2DataFileExists() throws IOException { + public static boolean h2DataFileExists() throws IOException { final File dir = Settings.getDataDirectory(); final String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME); final File file = new File(dir, fileName); return file.exists(); } + /** + * Determines if the connection string is for an H2 database. + * + * @return true if the connection string is for an H2 database + */ + public static boolean isH2Connection() { + String connStr; + try { + connStr = Settings.getConnectionString( + Settings.KEYS.DB_CONNECTION_STRING, + Settings.KEYS.DB_FILE_NAME); + } catch (IOException ex) { + LOGGER.debug("Unable to get connectionn string", ex); + return false; + } + return connStr.startsWith("jdbc:h2:file:"); + } + /** * Creates the database structure (tables and indexes) to store the CVE * data. diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java index ac105dbf6..bb32ae907 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/CveDB.java @@ -58,7 +58,7 @@ import static org.owasp.dependencycheck.data.nvdcve.CveDB.PreparedStatementCveDb * @author Jeremy Long */ @ThreadSafe -public final class CveDB { +public final class CveDB implements AutoCloseable { /** * Singleton instance of the CveDB. @@ -253,7 +253,8 @@ public final class CveDB { * Closes the database connection. Close should be called on this object * when it is done being used. */ - public static synchronized void close() { + @Override + public synchronized void close() { if (instance != null) { instance.usageCount -= 1; if (instance.usageCount <= 0 && instance.isOpen()) { @@ -281,7 +282,7 @@ public final class CveDB { * * @return whether the database connection is open or closed */ - private synchronized boolean isOpen() { + protected synchronized boolean isOpen() { return connection != null; } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java index 6958d6ba7..2bd2eb5ef 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/EngineVersionCheck.java @@ -93,8 +93,7 @@ public class EngineVersionCheck implements CachedWebDataSource { */ @Override public void update() throws UpdateException { - try { - final CveDB db = CveDB.getInstance(); + try (CveDB db = CveDB.getInstance()) { final boolean autoupdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE, true); final boolean enabled = Settings.getBoolean(Settings.KEYS.UPDATE_VERSION_CHECK_ENABLED, true); final String original = Settings.getString(Settings.KEYS.CVE_ORIGINAL_MODIFIED_20_URL); @@ -127,8 +126,6 @@ public class EngineVersionCheck implements CachedWebDataSource { throw new UpdateException("Error occurred updating database properties."); } catch (InvalidSettingException ex) { LOGGER.debug("Unable to determine if autoupdate is enabled", ex); - } finally { - CveDB.close(); } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java index 98a12d958..2ae21797c 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java @@ -104,17 +104,17 @@ public class NvdCveUpdater implements CachedWebDataSource { LOGGER.trace("invalid setting UPDATE_NVDCVE_ENABLED", ex); } + boolean autoUpdate = true; + try { + autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); + } catch (InvalidSettingException ex) { + LOGGER.debug("Invalid setting for auto-update; using true."); + } + if (!autoUpdate) { + return; + } + initializeExecutorServices(); try { - boolean autoUpdate = true; - try { - autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); - } catch (InvalidSettingException ex) { - LOGGER.debug("Invalid setting for auto-update; using true."); - } - if (!autoUpdate) { - return; - } - initializeExecutorServices(); cveDb = CveDB.getInstance(); dbProperties = cveDb.getDatabaseProperties(); @@ -139,7 +139,7 @@ public class NvdCveUpdater implements CachedWebDataSource { throw new UpdateException("Database Exception, unable to update the data to use the most current data.", ex); } finally { shutdownExecutorServices(); - CveDB.close(); + cveDb.close(); } } @@ -202,13 +202,10 @@ public class NvdCveUpdater implements CachedWebDataSource { * @return true if the database contains data */ private boolean dataExists() { - try { - final CveDB cve = CveDB.getInstance(); + try (CveDB cve = CveDB.getInstance()) { return cve.dataExists(); } catch (DatabaseException ex) { return false; - } finally { - CveDB.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java index 0c2fd0bdf..fb0e17448 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java @@ -51,7 +51,6 @@ public abstract class BaseDBTestCase extends BaseTest { @Before public void setUpDb() throws Exception { ensureDBExists(); - CveDB.getInstance().openDatabase(); } public static void ensureDBExists() throws Exception { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java index 85958a39c..94f58dba6 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java @@ -71,10 +71,11 @@ public class EngineIntegrationTest extends BaseDBTestCase { throw ex; } } - CveDB cveDB = CveDB.getInstance(); - DatabaseProperties dbProp = cveDB.getDatabaseProperties(); - CveDB.close(); - ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), dbProp); + DatabaseProperties prop = null; + try (CveDB cve = CveDB.getInstance()) { + prop = cve.getDatabaseProperties(); + } + ReportGenerator rg = new ReportGenerator("DependencyCheck", instance.getDependencies(), instance.getAnalyzers(), prop); rg.generateReports("./target/", "ALL"); instance.cleanup(); } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java index d2e655ac7..ea986dfbf 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java @@ -28,6 +28,7 @@ import java.util.List; import java.util.Set; import org.junit.After; +import static org.junit.Assert.assertNotNull; import org.junit.Assume; import org.junit.Before; import org.junit.Test; @@ -53,7 +54,7 @@ import org.owasp.dependencycheck.exception.InitializationException; * @author Dale Visser */ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { - + private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzerTest.class); /** @@ -82,8 +83,10 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { */ @After public void tearDown() throws Exception { - analyzer.close(); - analyzer = null; + if (analyzer != null) { + analyzer.close(); + analyzer = null; + } } /** @@ -117,7 +120,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { analyzer.analyze(result, engine); int size = engine.getDependencies().size(); assertTrue(size >= 1); - + Dependency dependency = engine.getDependencies().get(0); assertTrue(dependency.getProductEvidence().toString().toLowerCase().contains("redcarpet")); assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2")); @@ -136,16 +139,16 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { public void testAddCriticalityToVulnerability() throws AnalysisException, DatabaseException { try { analyzer.initialize(); - + final Dependency result = new Dependency(BaseTest.getResourceAsFile(this, "ruby/vulnerable/gems/sinatra/Gemfile.lock")); final Engine engine = new Engine(); analyzer.analyze(result, engine); - + Dependency dependency = engine.getDependencies().get(0); Vulnerability vulnerability = dependency.getVulnerabilities().first(); assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0); - + } catch (InitializationException | DatabaseException | AnalysisException e) { LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\"."); Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e); @@ -166,7 +169,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { analyzer.initialize(); } catch (Exception e) { //expected, so ignore. - LOGGER.error("Exception", e); + assertNotNull(e); } finally { assertThat(analyzer.isEnabled(), is(false)); LOGGER.info("phantom-bundle-audit is not available. Ruby Bundle Audit Analyzer is disabled as expected."); @@ -191,6 +194,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { fail(ex.getMessage()); } catch (ExceptionCollection ex) { Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", ex); + return; } List dependencies = engine.getDependencies(); LOGGER.info(dependencies.size() + " dependencies found."); @@ -198,14 +202,14 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { while (dIterator.hasNext()) { Dependency dept = dIterator.next(); LOGGER.info("dept path: " + dept.getActualFilePath()); - + Set identifiers = dept.getIdentifiers(); Iterator idIterator = identifiers.iterator(); while (idIterator.hasNext()) { Identifier id = idIterator.next(); LOGGER.info(" Identifier: " + id.getValue() + ", type=" + id.getType() + ", url=" + id.getUrl() + ", conf=" + id.getConfidence()); } - + Set prodEv = dept.getProductEvidence().getEvidence(); Iterator it = prodEv.iterator(); while (it.hasNext()) { @@ -218,7 +222,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase { Evidence e = vIt.next(); LOGGER.info(" version: name=" + e.getName() + ", value=" + e.getValue() + ", source=" + e.getSource() + ", confidence=" + e.getConfidence()); } - + Set vendorEv = dept.getVendorEvidence().getEvidence(); Iterator vendorIt = vendorEv.iterator(); while (vendorIt.hasNext()) { diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java index 916f9462d..32cf3a9f2 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBIntegrationTest.java @@ -29,6 +29,7 @@ import java.util.Map.Entry; import java.util.Set; import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; @@ -52,7 +53,8 @@ public class CveDBIntegrationTest extends BaseDBTestCase { } catch (DatabaseException | SQLException ex) { fail(ex.getMessage()); } finally { - CveDB.close(); + instance.close(); + assertFalse(instance.isOpen()); } } @@ -66,7 +68,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { String product = "struts"; Set result = instance.getCPEs(vendor, product); assertTrue(result.size() > 5); - CveDB.close(); + instance.close(); } /** @@ -77,7 +79,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { CveDB instance = CveDB.getInstance(); Vulnerability result = instance.getVulnerability("CVE-2014-0094"); assertEquals("The ParametersInterceptor in Apache Struts before 2.3.16.1 allows remote attackers to \"manipulate\" the ClassLoader via the class parameter, which is passed to the getClass method.", result.getDescription()); - CveDB.close(); + instance.close(); } /** @@ -114,7 +116,7 @@ public class CveDBIntegrationTest extends BaseDBTestCase { } } assertTrue("Expected " + expected + ", but was not identified", found); - CveDB.close(); + instance.close(); } /** @@ -170,6 +172,6 @@ public class CveDBIntegrationTest extends BaseDBTestCase { identifiedVersion = new DependencyVersion("1.6.3"); results = instance.getMatchingSoftware(versions, "springsource", "spring_framework", identifiedVersion); assertNotNull(results); - CveDB.close(); + instance.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java index dbe7d22bc..6915ee6de 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/CveDBMySQLTest.java @@ -19,6 +19,7 @@ package org.owasp.dependencycheck.data.nvdcve; import java.util.List; import java.util.Set; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -39,13 +40,15 @@ public class CveDBMySQLTest extends BaseTest { */ @Test public void testOpen() { + CveDB instance = null; try { - CveDB instance = CveDB.getInstance(); + instance = CveDB.getInstance(); } catch (DatabaseException ex) { System.out.println("Unable to connect to the My SQL database; verify that the db server is running and that the schema has been generated"); fail(ex.getMessage()); } finally { - CveDB.close(); + instance.close(); + assertFalse(instance.isOpen()); } } @@ -57,14 +60,14 @@ public class CveDBMySQLTest extends BaseTest { CveDB instance = CveDB.getInstance(); try { String vendor = "apache"; - String product = "struts"; + String product = "struts"; Set result = instance.getCPEs(vendor, product); assertTrue("Has data been loaded into the MySQL DB? if not consider using the CLI to populate it", result.size() > 5); } catch (Exception ex) { System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); throw ex; } finally { - CveDB.close(); + instance.close(); } } @@ -82,7 +85,7 @@ public class CveDBMySQLTest extends BaseTest { System.out.println("Unable to access the My SQL database; verify that the db server is running and that the schema has been generated"); throw ex; } finally { - CveDB.close(); + instance.close(); } } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java index 6067f8e40..2a64775ae 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/nvdcve/DatabasePropertiesIntegrationTest.java @@ -41,7 +41,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { assertNotNull(instance); //no exception means the call worked... whether or not it is empty depends on if the db is new //assertEquals(expResult, result); - CveDB.close(); + cveDB.close(); } /** @@ -60,7 +60,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { instance = cveDB.reloadProperties(); long results = Long.parseLong(instance.getProperty("NVD CVE " + key)); assertEquals(expected, results); - CveDB.close(); + cveDB.close(); } /** @@ -75,7 +75,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { String expResult = "default"; String result = instance.getProperty(key, defaultValue); assertEquals(expResult, result); - CveDB.close(); + cveDB.close(); } /** @@ -90,7 +90,7 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { double version = Double.parseDouble(result); assertTrue(version >= 2.8); assertTrue(version <= 10); - CveDB.close(); + cveDB.close(); } /** @@ -102,6 +102,6 @@ public class DatabasePropertiesIntegrationTest extends BaseDBTestCase { DatabaseProperties instance = cveDB.getDatabaseProperties(); Properties result = instance.getProperties(); assertTrue(result.size() > 0); - CveDB.close(); + cveDB.close(); } } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java index 0b9e72390..f0a7ff01c 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/reporting/ReportGeneratorIntegrationTest.java @@ -149,7 +149,7 @@ public class ReportGeneratorIntegrationTest extends BaseDBTestCase { ReportGenerator generator = new ReportGenerator("Test Report", engine.getDependencies(), engine.getAnalyzers(), dbProp); generator.generateReport(templateName, writeTo); - CveDB.close(); + cveDB.close(); engine.cleanup(); 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 629d722a4..76b74d9dd 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 @@ -1007,8 +1007,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma */ protected void writeReports(Engine engine, MavenProject p, File outputDir) throws ReportException { DatabaseProperties prop = null; - try { - final CveDB cve = CveDB.getInstance(); + try (CveDB cve = CveDB.getInstance()) { prop = cve.getDatabaseProperties(); } catch (DatabaseException ex) { //TODO shouldn't this throw an exception? @@ -1017,7 +1016,6 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma } } final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop); - CveDB.close(); try { r.generateReports(outputDir.getAbsolutePath(), format); } catch (ReportException ex) { From 35d0f21c47cc11173a00a37a188d138efd16da27 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 1 Apr 2017 10:02:24 -0400 Subject: [PATCH 6/6] fix codacy issues --- .../taskdefs/DependencyCheckTaskTest.java | 9 ++------- .../java/org/owasp/dependencycheck/BaseDBTestCase.java | 2 -- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java b/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java index 04a6b4c44..ffab315f3 100644 --- a/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java +++ b/dependency-check-ant/src/test/java/org/owasp/dependencycheck/taskdefs/DependencyCheckTaskTest.java @@ -30,8 +30,6 @@ import org.owasp.dependencycheck.BaseDBTestCase; import org.owasp.dependencycheck.utils.Settings; import static org.junit.Assert.assertTrue; -import org.owasp.dependencycheck.data.nvdcve.CveDB; -import org.owasp.dependencycheck.data.nvdcve.DatabaseException; /** * @@ -66,13 +64,10 @@ public class DependencyCheckTaskTest { @Test public void testAddFileSet() throws Exception { File report = new File("target/dependency-check-report.html"); - if (report.exists()) { - if (!report.delete()) { - throw new Exception("Unable to delete 'target/DependencyCheck-Report.html' prior to test."); - } + if (report.exists() && !report.delete()) { + throw new Exception("Unable to delete 'target/DependencyCheck-Report.html' prior to test."); } buildFileRule.executeTarget("test.fileset"); - assertTrue("DependencyCheck report was not generated", report.exists()); } diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java index df1b910c2..bfcb5cb5a 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/BaseDBTestCase.java @@ -25,9 +25,7 @@ import java.io.FileOutputStream; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.apache.commons.compress.utils.IOUtils; -import org.junit.AfterClass; import org.junit.Before; -import org.owasp.dependencycheck.data.nvdcve.CveDB; import org.owasp.dependencycheck.utils.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory;