From cb3cf79beb09be3038b190575bd4f0437acf312f Mon Sep 17 00:00:00 2001 From: Mark Rekveld Date: Fri, 7 Jul 2017 17:11:49 +0200 Subject: [PATCH 1/8] Engine execution modes --- .../org/owasp/dependencycheck/Engine.java | 134 ++++++++++++------ .../analyzer/AnalyzerService.java | 29 +++- .../data/nvdcve/DatabaseException.java | 2 +- 3 files changed, 114 insertions(+), 51 deletions(-) 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 1d6cb2ab6..b81da05e8 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 @@ -24,6 +24,7 @@ import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer; import org.owasp.dependencycheck.data.nvdcve.ConnectionFactory; import org.owasp.dependencycheck.data.nvdcve.CveDB; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; import org.owasp.dependencycheck.data.update.CachedWebDataSource; import org.owasp.dependencycheck.data.update.UpdateService; import org.owasp.dependencycheck.data.update.exception.UpdateException; @@ -31,6 +32,8 @@ import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.exception.ExceptionCollection; import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.exception.NoDataException; +import org.owasp.dependencycheck.exception.ReportException; +import org.owasp.dependencycheck.reporting.ReportGenerator; import org.owasp.dependencycheck.utils.InvalidSettingException; import org.owasp.dependencycheck.utils.Settings; import org.slf4j.Logger; @@ -39,24 +42,10 @@ 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; -import java.util.EnumMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.CancellationException; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; -import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties; -import org.owasp.dependencycheck.exception.ReportException; -import org.owasp.dependencycheck.reporting.ReportGenerator; +import java.util.*; +import java.util.concurrent.*; + +import static org.owasp.dependencycheck.analyzer.AnalysisPhase.*; /** * Scans files, directories, etc. for Dependencies. Analyzers are loaded and @@ -68,6 +57,35 @@ import org.owasp.dependencycheck.reporting.ReportGenerator; */ public class Engine implements FileFilter { + public enum Mode { + EVIDENCE_COLLECTION( + false, + INITIAL, + PRE_INFORMATION_COLLECTION, + INFORMATION_COLLECTION, + POST_INFORMATION_COLLECTION + ), + EVIDENCE_PROCESSING( + true, + PRE_IDENTIFIER_ANALYSIS, + IDENTIFIER_ANALYSIS, + POST_IDENTIFIER_ANALYSIS, + PRE_FINDING_ANALYSIS, + FINDING_ANALYSIS, + POST_FINDING_ANALYSIS, + FINAL + ), + STANDALONE(true, AnalysisPhase.values()); + + public final boolean requiresDatabase; + public final AnalysisPhase[] phases; + + Mode(boolean requiresDatabase, AnalysisPhase... phases) { + this.requiresDatabase = requiresDatabase; + this.phases = phases; + } + } + /** * The list of dependencies. */ @@ -82,11 +100,13 @@ public class Engine implements FileFilter { */ private final Set fileTypeAnalyzers = new HashSet<>(); + private final Mode mode; + /** * The ClassLoader to use when dynamically loading Analyzer and Update * services. */ - private ClassLoader serviceClassLoader = Thread.currentThread().getContextClassLoader(); + private ClassLoader serviceClassLoader; /** * A reference to the database. */ @@ -98,23 +118,32 @@ public class Engine implements FileFilter { /** * Creates a new Engine. - * - * @throws DatabaseException thrown if there is an error connecting to the - * database */ - public Engine() throws DatabaseException { - initializeEngine(); + public Engine() { + this(Mode.STANDALONE); + } + + public Engine(Mode mode) { + this(Thread.currentThread().getContextClassLoader(), mode); } /** * Creates a new Engine. * * @param serviceClassLoader a reference the class loader being used - * @throws DatabaseException thrown if there is an error connecting to the - * database */ - public Engine(ClassLoader serviceClassLoader) throws DatabaseException { + public Engine(ClassLoader serviceClassLoader) { + this(serviceClassLoader, Mode.STANDALONE); + } + + /** + * Creates a new Engine. + * + * @param serviceClassLoader a reference the class loader being used + */ + public Engine(ClassLoader serviceClassLoader, Mode mode) { this.serviceClassLoader = serviceClassLoader; + this.mode = mode; initializeEngine(); } @@ -125,8 +154,10 @@ public class Engine implements FileFilter { * @throws DatabaseException thrown if there is an error connecting to the * database */ - protected final void initializeEngine() throws DatabaseException { - ConnectionFactory.initialize(); + protected final void initializeEngine() { + if (mode.requiresDatabase) { + ConnectionFactory.initialize(); + } loadAnalyzers(); } @@ -134,11 +165,13 @@ public class Engine implements FileFilter { * Properly cleans up resources allocated during analysis. */ public void cleanup() { - if (database != null) { - database.close(); - database = null; + if (mode.requiresDatabase) { + if (database != null) { + database.close(); + database = null; + } + ConnectionFactory.cleanup(); } - ConnectionFactory.cleanup(); } /** @@ -149,12 +182,12 @@ public class Engine implements FileFilter { if (!analyzers.isEmpty()) { return; } - for (AnalysisPhase phase : AnalysisPhase.values()) { + for (AnalysisPhase phase : mode.phases) { analyzers.put(phase, new ArrayList()); } final AnalyzerService service = new AnalyzerService(serviceClassLoader); - final List iterator = service.getAnalyzers(); + final List iterator = service.getAnalyzers(mode.phases); for (Analyzer a : iterator) { analyzers.get(a.getAnalysisPhase()).add(a); if (a instanceof FileTypeAnalyzer) { @@ -503,7 +536,7 @@ public class Engine implements FileFilter { final long analysisStart = System.currentTimeMillis(); // analysis phases - for (AnalysisPhase phase : AnalysisPhase.values()) { + for (AnalysisPhase phase : mode.phases) { final List analyzerList = analyzers.get(phase); for (final Analyzer analyzer : analyzerList) { @@ -549,6 +582,9 @@ public class Engine implements FileFilter { * @throws ExceptionCollection thrown if fatal exceptions occur */ private void initializeAndUpdateDatabase(final List exceptions) throws ExceptionCollection { + if (!mode.requiresDatabase) { + return; + } boolean autoUpdate = true; try { autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE); @@ -705,15 +741,19 @@ public class Engine implements FileFilter { * @throws UpdateException thrown if the operation fails */ public void doUpdates() throws UpdateException { - LOGGER.info("Checking for updates"); - final long updateStart = System.currentTimeMillis(); - final UpdateService service = new UpdateService(serviceClassLoader); - final Iterator iterator = service.getDataSources(); - while (iterator.hasNext()) { - final CachedWebDataSource source = iterator.next(); - source.update(); + if (mode.requiresDatabase) { + LOGGER.info("Checking for updates"); + final long updateStart = System.currentTimeMillis(); + final UpdateService service = new UpdateService(serviceClassLoader); + final Iterator iterator = service.getDataSources(); + while (iterator.hasNext()) { + final CachedWebDataSource source = iterator.next(); + source.update(); + } + LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart); + } else { + LOGGER.info("Skipping update check in evidence collection mode."); } - LOGGER.info("Check for updates complete ({} ms)", System.currentTimeMillis() - updateStart); } /** @@ -778,7 +818,7 @@ public class Engine implements FileFilter { * @throws NoDataException thrown if no data exists in the CPE Index */ private void ensureDataExists() throws NoDataException { - if (database == null || !database.dataExists()) { + if (mode.requiresDatabase && (database == null || !database.dataExists())) { throw new NoDataException("No documents exist"); } } @@ -813,7 +853,9 @@ public class Engine implements FileFilter { */ public synchronized void writeReports(String applicationName, String groupId, String artifactId, String version, File outputDir, String format) throws ReportException { - + if (mode == Mode.EVIDENCE_COLLECTION) { + throw new UnsupportedOperationException("Cannot generate report in evidence collection mode."); + } final DatabaseProperties prop = database.getDatabaseProperties(); final ReportGenerator r = new ReportGenerator(applicationName, groupId, artifactId, version, dependencies, getAnalyzers(), prop); try { diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java index 7c2c18d2f..e4274217a 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AnalyzerService.java @@ -17,14 +17,14 @@ */ package org.owasp.dependencycheck.analyzer; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.ServiceLoader; import org.owasp.dependencycheck.utils.InvalidSettingException; import org.owasp.dependencycheck.utils.Settings; import org.slf4j.LoggerFactory; +import java.util.*; + +import static java.util.Arrays.asList; + /** * The Analyzer Service Loader. This class loads all services that implement * org.owasp.dependencycheck.analyzer.Analyzer. @@ -57,6 +57,24 @@ public class AnalyzerService { * @return a list of Analyzers. */ public List getAnalyzers() { + return getAnalyzers(AnalysisPhase.values()); + } + + /** + * Returns a list of all instances of the Analyzer interface that are bound to one of the given phases. + * + * @return a list of Analyzers. + */ + public List getAnalyzers(AnalysisPhase... phases) { + return getAnalyzers(asList(phases)); + } + + /** + * Returns a list of all instances of the Analyzer interface that are bound to one of the given phases. + * + * @return a list of Analyzers. + */ + private List getAnalyzers(List phases) { final List analyzers = new ArrayList<>(); final Iterator iterator = service.iterator(); boolean experimentalEnabled = false; @@ -67,6 +85,9 @@ public class AnalyzerService { } while (iterator.hasNext()) { final Analyzer a = iterator.next(); + if (!phases.contains(a.getAnalysisPhase())) { + continue; + } if (!experimentalEnabled && a.getClass().isAnnotationPresent(Experimental.class)) { continue; } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/DatabaseException.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/DatabaseException.java index 40ac796f4..474664302 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/DatabaseException.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nvdcve/DatabaseException.java @@ -22,7 +22,7 @@ package org.owasp.dependencycheck.data.nvdcve; * * @author Jeremy Long */ -public class DatabaseException extends Exception { +public class DatabaseException extends RuntimeException { /** * the serial version uid. From f2aa3f12be706940dd02353afe9171d3d10ab4a6 Mon Sep 17 00:00:00 2001 From: Mark Rekveld Date: Mon, 10 Jul 2017 16:23:17 +0200 Subject: [PATCH 2/8] javadocs + tests --- .../org/owasp/dependencycheck/Engine.java | 23 +++++- .../owasp/dependencycheck/EngineModeTest.java | 81 +++++++++++++++++++ .../analyzer/AnalyzerServiceTest.java | 28 ++++++- 3 files changed, 126 insertions(+), 6 deletions(-) create mode 100644 dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeTest.java 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 b81da05e8..9e48bce14 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 @@ -57,7 +57,14 @@ import static org.owasp.dependencycheck.analyzer.AnalysisPhase.*; */ public class Engine implements FileFilter { + /** + * {@link Engine} execution modes. + */ public enum Mode { + /** + * In evidence collection mode the {@link Engine} only collect evidence from the scan targets, + * and doesn't require a database. + */ EVIDENCE_COLLECTION( false, INITIAL, @@ -65,6 +72,11 @@ public class Engine implements FileFilter { INFORMATION_COLLECTION, POST_INFORMATION_COLLECTION ), + /** + * In evidence processing mode the {@link Engine} processes the evidence collected using the + * {@link #EVIDENCE_COLLECTION} mode. Dependencies should be injected into the {@link Engine} + * using {@link Engine#setDependencies(List)}. + */ EVIDENCE_PROCESSING( true, PRE_IDENTIFIER_ANALYSIS, @@ -75,6 +87,9 @@ public class Engine implements FileFilter { POST_FINDING_ANALYSIS, FINAL ), + /** + * In standalone mode the {@link Engine} will collect and process evidence in a single execution. + */ STANDALONE(true, AnalysisPhase.values()); public final boolean requiresDatabase; @@ -117,18 +132,21 @@ public class Engine implements FileFilter { private static final Logger LOGGER = LoggerFactory.getLogger(Engine.class); /** - * Creates a new Engine. + * Creates a new {@link Mode#STANDALONE} Engine. */ public Engine() { this(Mode.STANDALONE); } + /** + * Creates a new Engine. + */ public Engine(Mode mode) { this(Thread.currentThread().getContextClassLoader(), mode); } /** - * Creates a new Engine. + * Creates a new {@link Mode#STANDALONE} Engine. * * @param serviceClassLoader a reference the class loader being used */ @@ -140,6 +158,7 @@ public class Engine implements FileFilter { * Creates a new Engine. * * @param serviceClassLoader a reference the class loader being used + * @param mode the mode of the engine */ public Engine(ClassLoader serviceClassLoader, Mode mode) { this.serviceClassLoader = serviceClassLoader; diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeTest.java new file mode 100644 index 000000000..680c89e09 --- /dev/null +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeTest.java @@ -0,0 +1,81 @@ +package org.owasp.dependencycheck; + +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.rules.TestName; +import org.owasp.dependencycheck.analyzer.AnalysisPhase; +import org.owasp.dependencycheck.utils.Settings; + +import java.nio.file.Files; +import java.nio.file.Path; + +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +/** + * @author Mark Rekveld + */ +public class EngineModeTest extends BaseTest { + + @Rule + public TemporaryFolder tempDir = new TemporaryFolder(); + @Rule + public TestName testName = new TestName(); + private Engine engine; + + @Before + public void setUp() throws Exception { + Settings.setString(Settings.KEYS.DATA_DIRECTORY, tempDir.newFolder().getAbsolutePath()); + } + + @After + public void tearDown() throws Exception { + engine.cleanup(); + } + + @Test + public void testEvidenceCollectionMode() throws Exception { + engine = new Engine(Engine.Mode.EVIDENCE_COLLECTION); + assertDatabase(false); + for (AnalysisPhase phase : Engine.Mode.EVIDENCE_COLLECTION.phases) { + assertThat(engine.getAnalyzers(phase), is(notNullValue())); + } + for (AnalysisPhase phase : Engine.Mode.EVIDENCE_PROCESSING.phases) { + assertThat(engine.getAnalyzers(phase), is(nullValue())); + } + } + + @Test + public void testEvidenceProcessingMode() throws Exception { + engine = new Engine(Engine.Mode.EVIDENCE_PROCESSING); + assertDatabase(true); + for (AnalysisPhase phase : Engine.Mode.EVIDENCE_PROCESSING.phases) { + assertThat(engine.getAnalyzers(phase), is(notNullValue())); + } + for (AnalysisPhase phase : Engine.Mode.EVIDENCE_COLLECTION.phases) { + assertThat(engine.getAnalyzers(phase), is(nullValue())); + } + } + + @Test + public void testStandaloneMode() throws Exception { + engine = new Engine(Engine.Mode.STANDALONE); + assertDatabase(true); + for (AnalysisPhase phase : Engine.Mode.STANDALONE.phases) { + assertThat(engine.getAnalyzers(phase), is(notNullValue())); + } + } + + private void assertDatabase(boolean exists) throws Exception { + Path directory = Settings.getDataDirectory().toPath(); + assertThat(Files.exists(directory), is(true)); + assertThat(Files.isDirectory(directory), is(true)); + Path database = directory.resolve(Settings.getString(Settings.KEYS.DB_FILE_NAME)); + assertThat(Files.exists(database), is(exists)); + } +} diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java index b88bc4f3d..34f83be44 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AnalyzerServiceTest.java @@ -17,13 +17,18 @@ */ package org.owasp.dependencycheck.analyzer; -import java.util.List; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; import org.junit.Test; import org.owasp.dependencycheck.BaseDBTestCase; import org.owasp.dependencycheck.utils.Settings; +import java.util.List; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.owasp.dependencycheck.analyzer.AnalysisPhase.FINAL; +import static org.owasp.dependencycheck.analyzer.AnalysisPhase.INITIAL; + /** * * @author Jeremy Long @@ -46,7 +51,22 @@ public class AnalyzerServiceTest extends BaseDBTestCase { } assertTrue("JarAnalyzer loaded", found); } - + + /** + * Test of getAnalyzers method, of class AnalyzerService. + */ + @Test + public void testGetAnalyzers_SpecificPhases() throws Exception { + AnalyzerService instance = new AnalyzerService(Thread.currentThread().getContextClassLoader()); + List result = instance.getAnalyzers(INITIAL, FINAL); + + for (Analyzer a : result) { + if (a.getAnalysisPhase() != INITIAL && a.getAnalysisPhase() != FINAL) { + fail("Only expecting analyzers for phases " + INITIAL + " and " + FINAL); + } + } + } + /** * Test of getAnalyzers method, of class AnalyzerService. */ From 1fe24a2e0cee063932517baa91e6321187ab613f Mon Sep 17 00:00:00 2001 From: Mark Rekveld Date: Mon, 10 Jul 2017 16:36:41 +0200 Subject: [PATCH 3/8] type --- .../src/main/java/org/owasp/dependencycheck/Engine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 9e48bce14..f09f1db72 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 @@ -62,7 +62,7 @@ public class Engine implements FileFilter { */ public enum Mode { /** - * In evidence collection mode the {@link Engine} only collect evidence from the scan targets, + * In evidence collection mode the {@link Engine} only collects evidence from the scan targets, * and doesn't require a database. */ EVIDENCE_COLLECTION( From e6ec9d9aa3bd152f871d36b1229f043c668306cb Mon Sep 17 00:00:00 2001 From: Mark Rekveld Date: Mon, 10 Jul 2017 16:58:08 +0200 Subject: [PATCH 4/8] Autocloseable --- .../org/owasp/dependencycheck/Engine.java | 7 ++- .../owasp/dependencycheck/EngineModeTest.java | 46 +++++++++---------- 2 files changed, 27 insertions(+), 26 deletions(-) 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 f09f1db72..965debe5e 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 @@ -55,7 +55,7 @@ import static org.owasp.dependencycheck.analyzer.AnalysisPhase.*; * * @author Jeremy Long */ -public class Engine implements FileFilter { +public class Engine implements FileFilter, AutoCloseable { /** * {@link Engine} execution modes. @@ -193,6 +193,11 @@ public class Engine implements FileFilter { } } + @Override + public void close() throws Exception { + cleanup(); + } + /** * Loads the analyzers specified in the configuration file (or system * properties). diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeTest.java index 680c89e09..3f6bb86d3 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeTest.java @@ -1,6 +1,5 @@ package org.owasp.dependencycheck; -import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -26,48 +25,45 @@ public class EngineModeTest extends BaseTest { public TemporaryFolder tempDir = new TemporaryFolder(); @Rule public TestName testName = new TestName(); - private Engine engine; @Before public void setUp() throws Exception { Settings.setString(Settings.KEYS.DATA_DIRECTORY, tempDir.newFolder().getAbsolutePath()); } - @After - public void tearDown() throws Exception { - engine.cleanup(); - } - @Test public void testEvidenceCollectionMode() throws Exception { - engine = new Engine(Engine.Mode.EVIDENCE_COLLECTION); - assertDatabase(false); - for (AnalysisPhase phase : Engine.Mode.EVIDENCE_COLLECTION.phases) { - assertThat(engine.getAnalyzers(phase), is(notNullValue())); - } - for (AnalysisPhase phase : Engine.Mode.EVIDENCE_PROCESSING.phases) { - assertThat(engine.getAnalyzers(phase), is(nullValue())); + try (Engine engine = new Engine(Engine.Mode.EVIDENCE_COLLECTION)) { + assertDatabase(false); + for (AnalysisPhase phase : Engine.Mode.EVIDENCE_COLLECTION.phases) { + assertThat(engine.getAnalyzers(phase), is(notNullValue())); + } + for (AnalysisPhase phase : Engine.Mode.EVIDENCE_PROCESSING.phases) { + assertThat(engine.getAnalyzers(phase), is(nullValue())); + } } } @Test public void testEvidenceProcessingMode() throws Exception { - engine = new Engine(Engine.Mode.EVIDENCE_PROCESSING); - assertDatabase(true); - for (AnalysisPhase phase : Engine.Mode.EVIDENCE_PROCESSING.phases) { - assertThat(engine.getAnalyzers(phase), is(notNullValue())); - } - for (AnalysisPhase phase : Engine.Mode.EVIDENCE_COLLECTION.phases) { - assertThat(engine.getAnalyzers(phase), is(nullValue())); + try (Engine engine = new Engine(Engine.Mode.EVIDENCE_PROCESSING)) { + assertDatabase(true); + for (AnalysisPhase phase : Engine.Mode.EVIDENCE_PROCESSING.phases) { + assertThat(engine.getAnalyzers(phase), is(notNullValue())); + } + for (AnalysisPhase phase : Engine.Mode.EVIDENCE_COLLECTION.phases) { + assertThat(engine.getAnalyzers(phase), is(nullValue())); + } } } @Test public void testStandaloneMode() throws Exception { - engine = new Engine(Engine.Mode.STANDALONE); - assertDatabase(true); - for (AnalysisPhase phase : Engine.Mode.STANDALONE.phases) { - assertThat(engine.getAnalyzers(phase), is(notNullValue())); + try (Engine engine = new Engine(Engine.Mode.STANDALONE)) { + assertDatabase(true); + for (AnalysisPhase phase : Engine.Mode.STANDALONE.phases) { + assertThat(engine.getAnalyzers(phase), is(notNullValue())); + } } } From 7c0a7a0dd0ee9fe23929fa2653adcc00332ec938 Mon Sep 17 00:00:00 2001 From: Mark Rekveld Date: Mon, 10 Jul 2017 17:18:22 +0200 Subject: [PATCH 5/8] removed throws --- .../src/main/java/org/owasp/dependencycheck/Engine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 965debe5e..1735b2aa3 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 @@ -194,7 +194,7 @@ public class Engine implements FileFilter, AutoCloseable { } @Override - public void close() throws Exception { + public void close() { cleanup(); } From 11ef55920e349251975f92f8e91e6d36c07619e4 Mon Sep 17 00:00:00 2001 From: Mark Rekveld Date: Mon, 10 Jul 2017 18:14:42 +0200 Subject: [PATCH 6/8] missing mode.phases --- .../src/main/java/org/owasp/dependencycheck/Engine.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 1735b2aa3..a81cedd6f 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 @@ -583,7 +583,7 @@ public class Engine implements FileFilter, AutoCloseable { } } } - for (AnalysisPhase phase : AnalysisPhase.values()) { + for (AnalysisPhase phase : mode.phases) { final List analyzerList = analyzers.get(phase); for (Analyzer a : analyzerList) { @@ -788,7 +788,7 @@ public class Engine implements FileFilter, AutoCloseable { */ public List getAnalyzers() { final List ret = new ArrayList<>(); - for (AnalysisPhase phase : AnalysisPhase.values()) { + for (AnalysisPhase phase : mode.phases) { final List analyzerList = analyzers.get(phase); ret.addAll(analyzerList); } From ccce1eea4b759fb114f2c59b0f51876be06ccaac Mon Sep 17 00:00:00 2001 From: Mark Rekveld Date: Tue, 11 Jul 2017 09:59:28 +0200 Subject: [PATCH 7/8] tests --- ...{EngineModeTest.java => EngineModeIT.java} | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) rename dependency-check-core/src/test/java/org/owasp/dependencycheck/{EngineModeTest.java => EngineModeIT.java} (59%) diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeIT.java similarity index 59% rename from dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeTest.java rename to dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeIT.java index 3f6bb86d3..d0fc74227 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineModeIT.java @@ -6,20 +6,25 @@ import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.junit.rules.TestName; import org.owasp.dependencycheck.analyzer.AnalysisPhase; +import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.utils.Settings; +import java.io.File; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; import static org.hamcrest.CoreMatchers.notNullValue; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; /** * @author Mark Rekveld */ -public class EngineModeTest extends BaseTest { +public class EngineModeIT extends BaseTest { @Rule public TemporaryFolder tempDir = new TemporaryFolder(); @@ -32,7 +37,8 @@ public class EngineModeTest extends BaseTest { } @Test - public void testEvidenceCollectionMode() throws Exception { + public void testEvidenceCollectionAndEvidenceProcessingModes() throws Exception { + List dependencies; try (Engine engine = new Engine(Engine.Mode.EVIDENCE_COLLECTION)) { assertDatabase(false); for (AnalysisPhase phase : Engine.Mode.EVIDENCE_COLLECTION.phases) { @@ -41,11 +47,17 @@ public class EngineModeTest extends BaseTest { for (AnalysisPhase phase : Engine.Mode.EVIDENCE_PROCESSING.phases) { assertThat(engine.getAnalyzers(phase), is(nullValue())); } + File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); + engine.scan(file); + engine.analyzeDependencies(); + dependencies = engine.getDependencies(); + assertThat(dependencies.size(), is(1)); + Dependency dependency = dependencies.get(0); + assertTrue(dependency.getVendorEvidence().toString().toLowerCase().contains("apache")); + assertTrue(dependency.getVendorEvidence().getWeighting().contains("apache")); + assertTrue(dependency.getVulnerabilities().isEmpty()); } - } - @Test - public void testEvidenceProcessingMode() throws Exception { try (Engine engine = new Engine(Engine.Mode.EVIDENCE_PROCESSING)) { assertDatabase(true); for (AnalysisPhase phase : Engine.Mode.EVIDENCE_PROCESSING.phases) { @@ -54,6 +66,10 @@ public class EngineModeTest extends BaseTest { for (AnalysisPhase phase : Engine.Mode.EVIDENCE_COLLECTION.phases) { assertThat(engine.getAnalyzers(phase), is(nullValue())); } + engine.setDependencies(dependencies); + engine.analyzeDependencies(); + Dependency dependency = dependencies.get(0); + assertFalse(dependency.getVulnerabilities().isEmpty()); } } @@ -64,6 +80,15 @@ public class EngineModeTest extends BaseTest { for (AnalysisPhase phase : Engine.Mode.STANDALONE.phases) { assertThat(engine.getAnalyzers(phase), is(notNullValue())); } + File file = BaseTest.getResourceAsFile(this, "struts2-core-2.1.2.jar"); + engine.scan(file); + engine.analyzeDependencies(); + List dependencies = engine.getDependencies(); + assertThat(dependencies.size(), is(1)); + Dependency dependency = dependencies.get(0); + assertTrue(dependency.getVendorEvidence().toString().toLowerCase().contains("apache")); + assertTrue(dependency.getVendorEvidence().getWeighting().contains("apache")); + assertFalse(dependency.getVulnerabilities().isEmpty()); } } From b762d8e66411859313a8547b3e2bd4163c4c02f7 Mon Sep 17 00:00:00 2001 From: Mark Rekveld Date: Wed, 12 Jul 2017 13:10:36 +0200 Subject: [PATCH 8/8] comment --- .../src/main/java/org/owasp/dependencycheck/Engine.java | 3 +++ 1 file changed, 3 insertions(+) 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 a81cedd6f..b4469dfc2 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 @@ -115,6 +115,9 @@ public class Engine implements FileFilter, AutoCloseable { */ private final Set fileTypeAnalyzers = new HashSet<>(); + /** + * The engine execution mode indicating it will either collect evidence or process evidence or both. + */ private final Mode mode; /**