From cead88d2217b5bfb3a43baa58b8ccefd022cc658 Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Sat, 9 Jul 2016 07:39:00 -0400 Subject: [PATCH] reworked initialization exceptions as part of planned resolution for issue #215 --- .../analyzer/AbstractAnalyzer.java | 8 ++- .../analyzer/AbstractFileTypeAnalyzer.java | 47 ++++++++----- .../analyzer/AbstractSuppressionAnalyzer.java | 20 +++--- .../dependencycheck/analyzer/Analyzer.java | 31 +++++---- .../analyzer/ArchiveAnalyzer.java | 32 +++++---- .../analyzer/AssemblyAnalyzer.java | 42 ++++++++---- .../analyzer/AutoconfAnalyzer.java | 17 +++-- .../analyzer/CMakeAnalyzer.java | 24 ++++--- .../dependencycheck/analyzer/CPEAnalyzer.java | 30 ++++++--- .../analyzer/CentralAnalyzer.java | 26 +++++--- .../analyzer/ComposerLockAnalyzer.java | 17 +++-- .../analyzer/HintAnalyzer.java | 19 ++++-- .../dependencycheck/analyzer/JarAnalyzer.java | 33 ++++++---- .../analyzer/NexusAnalyzer.java | 33 ++++++---- .../analyzer/NodePackageAnalyzer.java | 13 ++-- .../analyzer/NuspecAnalyzer.java | 8 ++- .../analyzer/NvdCveAnalyzer.java | 31 +++++++-- .../analyzer/OpenSSLAnalyzer.java | 5 +- .../analyzer/PythonDistributionAnalyzer.java | 63 +++++++++++------- .../analyzer/PythonPackageAnalyzer.java | 5 +- .../analyzer/RubyBundleAuditAnalyzer.java | 47 +++++++++---- .../analyzer/RubyGemspecAnalyzer.java | 3 +- .../exception/InitializationException.java | 66 +++++++++++++++++++ .../AbstractSuppressionAnalyzerTest.java | 13 ++-- .../analyzer/AssemblyAnalyzerTest.java | 5 +- 25 files changed, 440 insertions(+), 198 deletions(-) create mode 100644 dependency-check-core/src/main/java/org/owasp/dependencycheck/exception/InitializationException.java diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.java index 67a9a85a5..0b35e7fb6 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractAnalyzer.java @@ -17,7 +17,11 @@ */ package org.owasp.dependencycheck.analyzer; +import org.owasp.dependencycheck.exception.InitializationException; + /** + * Base class for analyzers to avoid code duplication of initialize and close + * as most analyzers do not need these methods. * * @author Jeremy Long */ @@ -26,10 +30,10 @@ public abstract class AbstractAnalyzer implements Analyzer { /** * The initialize method does nothing for this Analyzer. * - * @throws Exception thrown if there is an exception + * @throws InitializationException thrown if there is an exception */ @Override - public void initialize() throws Exception { + public void initialize() throws InitializationException { //do nothing } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.java index 10ef1d402..628418f3c 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractFileTypeAnalyzer.java @@ -30,9 +30,11 @@ import java.io.FileFilter; import java.util.Collections; import java.util.HashSet; import java.util.Set; +import org.owasp.dependencycheck.exception.InitializationException; /** - * The base FileTypeAnalyzer that all analyzers that have specific file types they analyze should extend. + * The base FileTypeAnalyzer that all analyzers that have specific file types + * they analyze should extend. * * @author Jeremy Long */ @@ -40,7 +42,8 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen // /** - * Base constructor that all children must call. This checks the configuration to determine if the analyzer is enabled. + * Base constructor that all children must call. This checks the + * configuration to determine if the analyzer is enabled. */ public AbstractFileTypeAnalyzer() { reset(); @@ -58,7 +61,8 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen private boolean filesMatched = false; /** - * Get the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports. + * Get the value of filesMatched. A flag indicating whether the scan + * included any file types this analyzer supports. * * @return the value of filesMatched */ @@ -67,7 +71,8 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen } /** - * Set the value of filesMatched. A flag indicating whether the scan included any file types this analyzer supports. + * Set the value of filesMatched. A flag indicating whether the scan + * included any file types this analyzer supports. * * @param filesMatched new value of filesMatched */ @@ -102,11 +107,13 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen // /** *

- * Returns the {@link java.io.FileFilter} used to determine which files are to be analyzed. An example would be an analyzer - * that inspected Java jar files. Implementors may use {@link org.owasp.dependencycheck.utils.FileFilterBuilder}.

+ * Returns the {@link java.io.FileFilter} used to determine which files are + * to be analyzed. An example would be an analyzer that inspected Java jar + * files. Implementors may use + * {@link org.owasp.dependencycheck.utils.FileFilterBuilder}.

*

- * If the analyzer returns null it will not cause additional files to be analyzed, but will be executed against every file - * loaded.

+ * If the analyzer returns null it will not cause additional files to be + * analyzed, but will be executed against every file loaded.

* * @return the file filter used to determine which files are to be analyzed */ @@ -115,13 +122,15 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen /** * Initializes the file type analyzer. * - * @throws Exception thrown if there is an exception during initialization + * @throws InitializationException thrown if there is an exception during + * initialization */ - protected abstract void initializeFileTypeAnalyzer() throws Exception; + protected abstract void initializeFileTypeAnalyzer() throws InitializationException; /** - * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, - * and added to the list of dependencies within the engine. + * Analyzes a given dependency. If the dependency is an archive, such as a + * WAR or EAR, the contents are extracted, scanned, and added to the list of + * dependencies within the engine. * * @param dependency the dependency to analyze * @param engine the engine scanning @@ -142,10 +151,11 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen /** * Initializes the analyzer. * - * @throws Exception thrown if there is an exception during initialization + * @throws InitializationException thrown if there is an exception during + * initialization */ @Override - public final void initialize() throws Exception { + public final void initialize() throws InitializationException { if (filesMatched) { initializeFileTypeAnalyzer(); } else { @@ -169,8 +179,9 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen } /** - * Analyzes a given dependency. If the dependency is an archive, such as a WAR or EAR, the contents are extracted, scanned, - * and added to the list of dependencies within the engine. + * Analyzes a given dependency. If the dependency is an archive, such as a + * WAR or EAR, the contents are extracted, scanned, and added to the list of + * dependencies within the engine. * * @param dependency the dependency to analyze * @param engine the engine scanning @@ -202,8 +213,8 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen // /** *

- * Utility method to help in the creation of the extensions set. This constructs a new Set that can be used in a final static - * declaration.

+ * Utility method to help in the creation of the extensions set. This + * constructs a new Set that can be used in a final static declaration.

*

* This implementation was copied from * http://stackoverflow.com/questions/2041778/initialize-java-hashset-values-by-construction

diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java index 4bbfc087a..8ae7fcf56 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzer.java @@ -25,6 +25,7 @@ import java.net.URL; import java.util.List; import java.util.Set; import java.util.regex.Pattern; +import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.xml.suppression.SuppressionParseException; import org.owasp.dependencycheck.xml.suppression.SuppressionParser; import org.owasp.dependencycheck.xml.suppression.SuppressionRule; @@ -63,12 +64,16 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { /** * The initialize method loads the suppression XML file. * - * @throws Exception thrown if there is an exception + * @throws InitializationException thrown if there is an exception */ @Override - public void initialize() throws Exception { + public void initialize() throws InitializationException { super.initialize(); - loadSuppressionData(); + try { + loadSuppressionData(); + } catch (SuppressionParseException ex) { + throw new InitializationException("Error initializing the suppression analyzer", ex); + } } /** @@ -104,12 +109,8 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { File file = null; try { rules = parser.parseSuppressionRules(this.getClass().getClassLoader().getResourceAsStream("dependencycheck-base-suppression.xml")); - } catch (SuppressionParseException ex) { - LOGGER.error("Unable to parse the base suppression data file"); - LOGGER.debug("Unable to parse the base suppression data file", ex); } catch (SAXException ex) { - LOGGER.error("Unable to parse the base suppression data file"); - LOGGER.debug("Unable to parse the base suppression data file", ex); + throw new SuppressionParseException("Unable to parse the base suppression data file", ex); } final String suppressionFilePath = Settings.getString(Settings.KEYS.SUPPRESSION_FILE); if (suppressionFilePath == null) { @@ -142,16 +143,13 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { } } } - if (file != null) { try { - //rules = parser.parseSuppressionRules(file); rules.addAll(parser.parseSuppressionRules(file)); LOGGER.debug("{} suppression rules were loaded.", rules.size()); } catch (SuppressionParseException ex) { LOGGER.warn("Unable to parse suppression xml file '{}'", file.getPath()); LOGGER.warn(ex.getMessage()); - LOGGER.debug("", ex); throw ex; } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/Analyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/Analyzer.java index de4e28563..f9681fb6e 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/Analyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/Analyzer.java @@ -20,24 +20,28 @@ package org.owasp.dependencycheck.analyzer; import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.analyzer.exception.AnalysisException; import org.owasp.dependencycheck.dependency.Dependency; +import org.owasp.dependencycheck.exception.InitializationException; /** - * An interface that defines an Analyzer that is used to identify Dependencies. An analyzer will collect information - * about the dependency in the form of Evidence. + * An interface that defines an Analyzer that is used to identify Dependencies. + * An analyzer will collect information about the dependency in the form of + * Evidence. * * @author Jeremy Long */ public interface Analyzer { /** - * Analyzes the given dependency. The analysis could be anything from identifying an Identifier for the dependency, - * to finding vulnerabilities, etc. Additionally, if the analyzer collects enough information to add a description - * or license information for the dependency it should be added. + * Analyzes the given dependency. The analysis could be anything from + * identifying an Identifier for the dependency, to finding vulnerabilities, + * etc. Additionally, if the analyzer collects enough information to add a + * description or license information for the dependency it should be added. * * @param dependency a dependency to analyze. - * @param engine the engine that is scanning the dependencies - this is useful if we need to check other - * dependencies - * @throws AnalysisException is thrown if there is an error analyzing the dependency file + * @param engine the engine that is scanning the dependencies - this is + * useful if we need to check other dependencies + * @throws AnalysisException is thrown if there is an error analyzing the + * dependency file */ void analyze(Dependency dependency, Engine engine) throws AnalysisException; @@ -56,14 +60,17 @@ public interface Analyzer { AnalysisPhase getAnalysisPhase(); /** - * The initialize method is called (once) prior to the analyze method being called on all of the dependencies. + * The initialize method is called (once) prior to the analyze method being + * called on all of the dependencies. * - * @throws Exception is thrown if an exception occurs initializing the analyzer. + * @throws InitializationException is thrown if an exception occurs + * initializing the analyzer. */ - void initialize() throws Exception; + void initialize() throws InitializationException; /** - * The close method is called after all of the dependencies have been analyzed. + * The close method is called after all of the dependencies have been + * analyzed. * * @throws Exception is thrown if an exception occurs closing the analyzer. */ diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.java index c15dc732a..5a14171c7 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ArchiveAnalyzer.java @@ -49,6 +49,7 @@ import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.analyzer.exception.AnalysisException; import org.owasp.dependencycheck.analyzer.exception.ArchiveExtractionException; import org.owasp.dependencycheck.dependency.Dependency; +import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.utils.FileFilterBuilder; import org.owasp.dependencycheck.utils.FileUtils; import org.owasp.dependencycheck.utils.Settings; @@ -174,20 +175,27 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { /** * The initialize method does nothing for this Analyzer. * - * @throws Exception is thrown if there is an exception deleting or creating - * temporary files + * @throws InitializationException is thrown if there is an exception + * deleting or creating temporary files */ @Override - public void initializeFileTypeAnalyzer() throws Exception { - final File baseDir = Settings.getTempDirectory(); - tempFileLocation = File.createTempFile("check", "tmp", baseDir); - if (!tempFileLocation.delete()) { - final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); - throw new AnalysisException(msg); - } - if (!tempFileLocation.mkdirs()) { - final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); - throw new AnalysisException(msg); + public void initializeFileTypeAnalyzer() throws InitializationException { + try { + final File baseDir = Settings.getTempDirectory(); + tempFileLocation = File.createTempFile("check", "tmp", baseDir); + if (!tempFileLocation.delete()) { + setEnabled(false); + final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); + throw new InitializationException(msg); + } + if (!tempFileLocation.mkdirs()) { + setEnabled(false); + final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); + throw new InitializationException(msg); + } + } catch (IOException ex) { + setEnabled(false); + throw new InitializationException("Unable to create a temporary file", ex); } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java index 91488e9b3..e8eaea495 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzer.java @@ -43,9 +43,12 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import java.util.ArrayList; import java.util.List; +import javax.xml.parsers.ParserConfigurationException; +import org.owasp.dependencycheck.exception.InitializationException; /** - * Analyzer for getting company, product, and version information from a .NET assembly. + * Analyzer for getting company, product, and version information from a .NET + * assembly. * * @author colezlaw * @@ -178,13 +181,20 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Initialize the analyzer. In this case, extract GrokAssembly.exe to a temporary location. + * Initialize the analyzer. In this case, extract GrokAssembly.exe to a + * temporary location. * - * @throws Exception if anything goes wrong + * @throws InitializationException thrown if anything goes wrong */ @Override - public void initializeFileTypeAnalyzer() throws Exception { - final File tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory()); + public void initializeFileTypeAnalyzer() throws InitializationException { + final File tempFile; + try { + tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory()); + } catch (IOException ex) { + setEnabled(false); + throw new InitializationException("Unable to create temporary file for the assembly analyzerr", ex); + } FileOutputStream fos = null; InputStream is = null; try { @@ -199,7 +209,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer { } catch (IOException ioe) { this.setEnabled(false); LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage()); - throw new AnalysisException("Could not extract GrokAssembly.exe", ioe); + throw new InitializationException("Could not extract GrokAssembly.exe", ioe); } finally { if (fos != null) { try { @@ -232,19 +242,24 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer { LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer, please see the log for more details."); LOGGER.debug("GrokAssembly.exe is not working properly"); grokAssemblyExe = null; - this.setEnabled(false); - throw new AnalysisException("Could not execute .NET AssemblyAnalyzer"); + setEnabled(false); + throw new InitializationException("Could not execute .NET AssemblyAnalyzer"); } - } catch (AnalysisException e) { + } catch (InitializationException e) { throw e; } catch (Throwable e) { LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n" + "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details."); LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage()); - this.setEnabled(false); - throw new AnalysisException("An error occurred with the .NET AssemblyAnalyzer", e); + setEnabled(false); + throw new InitializationException("An error occurred with the .NET AssemblyAnalyzer", e); + } + try { + builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } catch (ParserConfigurationException ex) { + setEnabled(false); + throw new InitializationException("Error initializing the assembly analyzer", ex); } - builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); } /** @@ -296,7 +311,8 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Returns the key used in the properties file to reference the analyzer's enabled property. + * Returns the key used in the properties file to reference the analyzer's + * enabled property. * * @return the analyzer's enabled property setting key */ diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java index 01f9080e5..2ed211adc 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/AutoconfAnalyzer.java @@ -35,13 +35,16 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.owasp.dependencycheck.exception.InitializationException; /** - * Used to analyze Autoconf input files named configure.ac or configure.in. Files simply named "configure" are also analyzed, - * assuming they are generated by Autoconf, and contain certain special package descriptor variables. + * Used to analyze Autoconf input files named configure.ac or configure.in. + * Files simply named "configure" are also analyzed, assuming they are generated + * by Autoconf, and contain certain special package descriptor variables. * * @author Dale Visser - * @see Autoconf - GNU Project - Free Software Foundation (FSF) + * @see Autoconf - GNU Project + * - Free Software Foundation (FSF) */ @Experimental public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { @@ -142,7 +145,8 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Returns the key used in the properties file to reference the analyzer's enabled property. + * Returns the key used in the properties file to reference the analyzer's + * enabled property. * * @return the analyzer's enabled property setting key */ @@ -270,10 +274,11 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer { /** * Initializes the file type analyzer. * - * @throws Exception thrown if there is an exception during initialization + * @throws InitializationException thrown if there is an exception during + * initialization */ @Override - protected void initializeFileTypeAnalyzer() throws Exception { + protected void initializeFileTypeAnalyzer() throws InitializationException { // No initialization needed. } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java index 41c66d5a5..68a499d31 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CMakeAnalyzer.java @@ -38,14 +38,18 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.owasp.dependencycheck.exception.InitializationException; /** *

- * Used to analyze CMake build files, and collect information that can be used to determine the associated CPE.

+ * Used to analyze CMake build files, and collect information that can be used + * to determine the associated CPE.

*

- * Note: This analyzer catches straightforward invocations of the project command, plus some other observed patterns of version - * inclusion in real CMake projects. Many projects make use of older versions of CMake and/or use custom "homebrew" ways to insert - * version information. Hopefully as the newer CMake call pattern grows in usage, this analyzer allow more CPEs to be + * Note: This analyzer catches straightforward invocations of the project + * command, plus some other observed patterns of version inclusion in real CMake + * projects. Many projects make use of older versions of CMake and/or use custom + * "homebrew" ways to insert version information. Hopefully as the newer CMake + * call pattern grows in usage, this analyzer allow more CPEs to be * identified.

* * @author Dale Visser @@ -135,10 +139,10 @@ public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { /** * No-op initializer implementation. * - * @throws Exception never thrown + * @throws InitializationException never thrown */ @Override - protected void initializeFileTypeAnalyzer() throws Exception { + protected void initializeFileTypeAnalyzer() throws InitializationException { // Nothing to do here. } @@ -147,7 +151,8 @@ public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { * * @param dependency the dependency being analyzed * @param engine the engine being used to perform the scan - * @throws AnalysisException thrown if there is an unrecoverable error analyzing the dependency + * @throws AnalysisException thrown if there is an unrecoverable error + * analyzing the dependency */ @Override protected void analyzeFileType(Dependency dependency, Engine engine) @@ -183,8 +188,9 @@ public class CMakeAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Extracts the version information from the contents. If more then one version is found additional dependencies are added to - * the dependency list. + * Extracts the version information from the contents. If more then one + * version is found additional dependencies are added to the dependency + * list. * * @param dependency the dependency being analyzed * @param engine the dependency-check engine 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 d2fcfb14a..815881155 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 @@ -45,6 +45,7 @@ import org.owasp.dependencycheck.dependency.Evidence; import org.owasp.dependencycheck.dependency.EvidenceCollection; import org.owasp.dependencycheck.dependency.Identifier; import org.owasp.dependencycheck.dependency.VulnerableSoftware; +import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.utils.DependencyVersion; import org.owasp.dependencycheck.utils.DependencyVersionUtil; import org.slf4j.Logger; @@ -123,11 +124,20 @@ public class CPEAnalyzer implements Analyzer { /** * Creates the CPE Lucene Index. * - * @throws Exception is thrown if there is an issue opening the index. + * @throws InitializationException is thrown if there is an issue opening + * the index. */ @Override - public void initialize() throws Exception { - this.open(); + public void initialize() throws InitializationException { + try { + this.open(); + } catch (IOException ex) { + LOGGER.debug("Exception initializing the Lucene Index", ex); + throw new InitializationException("An exception occurred initializing the Lucene Index", ex); + } catch (DatabaseException ex) { + LOGGER.debug("Exception accessing the database", ex); + throw new InitializationException("An exception occurred accessing the database", ex); + } } /** @@ -565,12 +575,14 @@ public class CPEAnalyzer implements Analyzer { final IdentifierMatch match = new IdentifierMatch("cpe", vs.getName(), url, IdentifierConfidence.EXACT_MATCH, conf); collected.add(match); } else //TODO the following isn't quite right is it? need to think about this guessing game a bit more. - if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() - && evVer.matchesAtLeastThreeLevels(dbVer)) { - if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { - if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { - bestGuess = dbVer; - bestGuessConf = conf; + { + if (evVer.getVersionParts().size() <= dbVer.getVersionParts().size() + && evVer.matchesAtLeastThreeLevels(dbVer)) { + if (bestGuessConf == null || bestGuessConf.compareTo(conf) > 0) { + if (bestGuess.getVersionParts().size() < dbVer.getVersionParts().size()) { + bestGuess = dbVer; + bestGuessConf = conf; + } } } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CentralAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CentralAnalyzer.java index 08b9d4f63..3d96c3dc9 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CentralAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CentralAnalyzer.java @@ -33,8 +33,10 @@ import java.io.File; import java.io.FileFilter; import java.io.FileNotFoundException; import java.io.IOException; +import java.net.MalformedURLException; import java.net.URL; import java.util.List; +import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.utils.DownloadFailedException; import org.owasp.dependencycheck.utils.Downloader; import org.owasp.dependencycheck.utils.FileFilterBuilder; @@ -42,8 +44,8 @@ import org.owasp.dependencycheck.utils.InvalidSettingException; import org.owasp.dependencycheck.utils.Settings; /** - * Analyzer which will attempt to locate a dependency, and the GAV information, by querying Central for the dependency's SHA-1 - * digest. + * Analyzer which will attempt to locate a dependency, and the GAV information, + * by querying Central for the dependency's SHA-1 digest. * * @author colezlaw */ @@ -70,7 +72,8 @@ public class CentralAnalyzer extends AbstractFileTypeAnalyzer { private static final String SUPPORTED_EXTENSIONS = "jar"; /** - * The analyzer should be disabled if there are errors, so this is a flag to determine if such an error has occurred. + * The analyzer should be disabled if there are errors, so this is a flag to + * determine if such an error has occurred. */ private boolean errorFlag = false; @@ -96,7 +99,8 @@ public class CentralAnalyzer extends AbstractFileTypeAnalyzer { /** * Determines if this analyzer is enabled. * - * @return true if the analyzer is enabled; otherwise false + * @return true if the analyzer is enabled; otherwise + * false */ private boolean checkEnabled() { boolean retval = false; @@ -122,16 +126,21 @@ public class CentralAnalyzer extends AbstractFileTypeAnalyzer { /** * Initializes the analyzer once before any analysis is performed. * - * @throws Exception if there's an error during initialization + * @throws InitializationException if there's an error during initialization */ @Override - public void initializeFileTypeAnalyzer() throws Exception { + public void initializeFileTypeAnalyzer() throws InitializationException { LOGGER.debug("Initializing Central analyzer"); LOGGER.debug("Central analyzer enabled: {}", isEnabled()); if (isEnabled()) { final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_CENTRAL_URL); LOGGER.debug("Central Analyzer URL: {}", searchUrl); - searcher = new CentralSearch(new URL(searchUrl)); + try { + searcher = new CentralSearch(new URL(searchUrl)); + } catch (MalformedURLException ex) { + setEnabled(false); + throw new InitializationException("The configured URL to Maven Central is malformed: " + searchUrl, ex); + } } } @@ -146,7 +155,8 @@ public class CentralAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Returns the key used in the properties file to to reference the analyzer's enabled property. + * Returns the key used in the properties file to to reference the + * analyzer's enabled property. * * @return the analyzer's enabled property setting key. */ diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.java index df68ac8d3..ea4272121 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/ComposerLockAnalyzer.java @@ -35,6 +35,8 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.nio.charset.Charset; import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import org.owasp.dependencycheck.exception.InitializationException; /** * Used to analyze a composer.lock file for a composer PHP app. @@ -77,15 +79,22 @@ public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer { /** * Initializes the analyzer. * - * @throws Exception thrown if an exception occurs getting an instance of SHA1 + * @throws InitializationException thrown if an exception occurs getting an + * instance of SHA1 */ @Override - protected void initializeFileTypeAnalyzer() throws Exception { - sha1 = MessageDigest.getInstance("SHA1"); + protected void initializeFileTypeAnalyzer() throws InitializationException { + try { + sha1 = MessageDigest.getInstance("SHA1"); + } catch (NoSuchAlgorithmException ex) { + setEnabled(false); + throw new InitializationException("Unable to create SHA1 MmessageDigest", ex); + } } /** - * The MessageDigest for calculating a new digest for the new dependencies added. + * The MessageDigest for calculating a new digest for the new dependencies + * added. */ private MessageDigest sha1 = null; diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/HintAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/HintAnalyzer.java index 3d32dc819..b4ebcbfe0 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/HintAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/HintAnalyzer.java @@ -25,16 +25,14 @@ import java.net.URL; import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import java.util.Set; import java.util.regex.Pattern; import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.analyzer.exception.AnalysisException; -import org.owasp.dependencycheck.dependency.Confidence; import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.dependency.Evidence; +import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.xml.suppression.PropertyType; import org.owasp.dependencycheck.xml.suppression.SuppressionParseException; -import org.owasp.dependencycheck.xml.suppression.SuppressionParser; import org.owasp.dependencycheck.utils.DownloadFailedException; import org.owasp.dependencycheck.utils.Downloader; import org.owasp.dependencycheck.utils.FileUtils; @@ -49,6 +47,8 @@ import org.slf4j.LoggerFactory; import org.xml.sax.SAXException; /** + * This analyzer adds evidence to dependencies to enhance the accuracy of + * library identification. * * @author Jeremy Long */ @@ -87,12 +87,17 @@ public class HintAnalyzer extends AbstractAnalyzer implements Analyzer { /** * The initialize method does nothing for this Analyzer. * - * @throws Exception thrown if there is an exception + * @throws InitializationException thrown if there is an exception */ @Override - public void initialize() throws Exception { - super.initialize(); - loadHintRules(); + public void initialize() throws InitializationException { + try { + super.initialize(); + loadHintRules(); + } catch (HintParseException ex) { + LOGGER.debug("Unable to parse hint file", ex); + throw new InitializationException("Unable to parse the hint file", ex); + } } //
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java index da6fb6078..9d952c14c 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/JarAnalyzer.java @@ -39,6 +39,7 @@ import java.util.jar.Attributes; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; +import java.util.logging.Level; import java.util.regex.Pattern; import java.util.zip.ZipEntry; import org.apache.commons.compress.utils.IOUtils; @@ -49,6 +50,7 @@ import org.owasp.dependencycheck.analyzer.exception.AnalysisException; import org.owasp.dependencycheck.dependency.Confidence; import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.dependency.EvidenceCollection; +import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.utils.FileFilterBuilder; import org.owasp.dependencycheck.xml.pom.License; import org.owasp.dependencycheck.xml.pom.PomUtils; @@ -903,20 +905,27 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer { /** * Initializes the JarAnalyzer. * - * @throws Exception is thrown if there is an exception creating a temporary - * directory + * @throws InitializationException is thrown if there is an exception + * creating a temporary directory */ @Override - public void initializeFileTypeAnalyzer() throws Exception { - final File baseDir = Settings.getTempDirectory(); - tempFileLocation = File.createTempFile("check", "tmp", baseDir); - if (!tempFileLocation.delete()) { - final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); - throw new AnalysisException(msg); - } - if (!tempFileLocation.mkdirs()) { - final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); - throw new AnalysisException(msg); + public void initializeFileTypeAnalyzer() throws InitializationException { + try { + final File baseDir = Settings.getTempDirectory(); + tempFileLocation = File.createTempFile("check", "tmp", baseDir); + if (!tempFileLocation.delete()) { + final String msg = String.format("Unable to delete temporary file '%s'.", tempFileLocation.getAbsolutePath()); + setEnabled(false); + throw new InitializationException(msg); + } + if (!tempFileLocation.mkdirs()) { + final String msg = String.format("Unable to create directory '%s'.", tempFileLocation.getAbsolutePath()); + setEnabled(false); + throw new InitializationException(msg); + } + } catch (IOException ex) { + setEnabled(false); + throw new InitializationException("Unable to create a temporary file", ex); } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NexusAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NexusAnalyzer.java index c23322d76..1ff31ecaa 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NexusAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NexusAnalyzer.java @@ -35,6 +35,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; +import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.utils.DownloadFailedException; import org.owasp.dependencycheck.utils.Downloader; import org.owasp.dependencycheck.utils.FileFilterBuilder; @@ -42,15 +43,18 @@ import org.owasp.dependencycheck.utils.InvalidSettingException; import org.owasp.dependencycheck.utils.Settings; /** - * Analyzer which will attempt to locate a dependency on a Nexus service by SHA-1 digest of the dependency. + * Analyzer which will attempt to locate a dependency on a Nexus service by + * SHA-1 digest of the dependency. * * There are two settings which govern this behavior: * *
    - *
  • {@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED} determines whether this analyzer is even - * enabled. This can be overridden by setting the system property.
  • - *
  • {@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL} the URL to a Nexus service to search by SHA-1. - * There is an expected %s in this where the SHA-1 will get entered.
  • + *
  • {@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_ENABLED} + * determines whether this analyzer is even enabled. This can be overridden by + * setting the system property.
  • + *
  • {@link org.owasp.dependencycheck.utils.Settings.KEYS#ANALYZER_NEXUS_URL} + * the URL to a Nexus service to search by SHA-1. There is an expected + * %s in this where the SHA-1 will get entered.
  • *
* * @author colezlaw @@ -58,7 +62,8 @@ import org.owasp.dependencycheck.utils.Settings; public class NexusAnalyzer extends AbstractFileTypeAnalyzer { /** - * The default URL - this will be used by the CentralAnalyzer to determine whether to enable this. + * The default URL - this will be used by the CentralAnalyzer to determine + * whether to enable this. */ public static final String DEFAULT_URL = "https://repository.sonatype.org/service/local/"; @@ -95,7 +100,8 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer { /** * Determines if this analyzer is enabled * - * @return true if the analyzer is enabled; otherwise false + * @return true if the analyzer is enabled; otherwise + * false */ private boolean checkEnabled() { /* Enable this analyzer ONLY if the Nexus URL has been set to something @@ -131,10 +137,10 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer { /** * Initializes the analyzer once before any analysis is performed. * - * @throws Exception if there's an error during initialization + * @throws InitializationException if there's an error during initialization */ @Override - public void initializeFileTypeAnalyzer() throws Exception { + public void initializeFileTypeAnalyzer() throws InitializationException { LOGGER.debug("Initializing Nexus Analyzer"); LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled()); if (isEnabled()) { @@ -143,14 +149,12 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer { try { searcher = new NexusSearch(new URL(searchUrl)); if (!searcher.preflightRequest()) { - LOGGER.warn("There was an issue getting Nexus status. Disabling analyzer."); setEnabled(false); + throw new InitializationException("There was an issue getting Nexus status. Disabling analyzer."); } } catch (MalformedURLException mue) { - // I know that initialize can throw an exception, but we'll - // just disable the analyzer if the URL isn't valid - LOGGER.warn("Property {} not a valid URL. Nexus Analyzer disabled", searchUrl); setEnabled(false); + throw new InitializationException("Malformed URL to Nexus: " + searchUrl, mue); } } } @@ -166,7 +170,8 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Returns the key used in the properties file to reference the analyzer's enabled property. + * Returns the key used in the properties file to reference the analyzer's + * enabled property. * * @return the analyzer's enabled property setting key */ diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.java index 52b9afe11..50d20b38e 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NodePackageAnalyzer.java @@ -38,10 +38,11 @@ import javax.json.JsonObject; import javax.json.JsonReader; import javax.json.JsonString; import javax.json.JsonValue; +import org.owasp.dependencycheck.exception.InitializationException; /** - * Used to analyze Node Package Manager (npm) package.json files, and collect information that can be used to determine the - * associated CPE. + * Used to analyze Node Package Manager (npm) package.json files, and collect + * information that can be used to determine the associated CPE. * * @author Dale Visser */ @@ -84,7 +85,7 @@ public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { } @Override - protected void initializeFileTypeAnalyzer() throws Exception { + protected void initializeFileTypeAnalyzer() throws InitializationException { // NO-OP } @@ -109,7 +110,8 @@ public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Returns the key used in the properties file to reference the analyzer's enabled property. + * Returns the key used in the properties file to reference the analyzer's + * enabled property. * * @return the analyzer's enabled property setting key */ @@ -155,7 +157,8 @@ public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Adds information to an evidence collection from the node json configuration. + * Adds information to an evidence collection from the node json + * configuration. * * @param json information from node.js * @param collection a set of evidence about a dependency diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.java index d3950c793..b5d5de5b2 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/NuspecAnalyzer.java @@ -34,6 +34,7 @@ import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import org.owasp.dependencycheck.exception.InitializationException; /** * Analyzer which will parse a Nuspec file to gather module information. @@ -65,10 +66,10 @@ public class NuspecAnalyzer extends AbstractFileTypeAnalyzer { /** * Initializes the analyzer once before any analysis is performed. * - * @throws Exception if there's an error during initialization + * @throws InitializationException if there's an error during initialization */ @Override - public void initializeFileTypeAnalyzer() throws Exception { + public void initializeFileTypeAnalyzer() throws InitializationException { } /** @@ -82,7 +83,8 @@ public class NuspecAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Returns the key used in the properties file to reference the analyzer's enabled property. + * Returns the key used in the properties file to reference the analyzer's + * enabled property. * * @return the analyzer's enabled property setting key */ 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 249dd4855..fa0061f6a 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 @@ -27,6 +27,8 @@ import org.owasp.dependencycheck.data.nvdcve.DatabaseException; import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.dependency.Identifier; import org.owasp.dependencycheck.dependency.Vulnerability; +import org.owasp.dependencycheck.exception.InitializationException; +import org.slf4j.LoggerFactory; /** * NvdCveAnalyzer is a utility class that takes a project dependency and attempts to discern if there is an associated @@ -35,7 +37,10 @@ import org.owasp.dependencycheck.dependency.Vulnerability; * @author Jeremy Long */ public class NvdCveAnalyzer implements Analyzer { - + /** + * The Logger for use throughout the class + */ + private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(NvdCveAnalyzer.class); /** * The maximum number of query results to return. */ @@ -79,7 +84,7 @@ public class NvdCveAnalyzer implements Analyzer { /** * Ensures that the CVE Database is closed. * - * @throws Throwable when a throwable is thrown. + * @throws Throwable an exception raised by this method */ @Override protected void finalize() throws Throwable { @@ -94,7 +99,7 @@ public class NvdCveAnalyzer implements Analyzer { * * @param dependency The Dependency to analyze * @param engine The analysis engine - * @throws AnalysisException is thrown if there is an issue analyzing the dependency + * @throws AnalysisException thrown if there is an issue analyzing the dependency */ @Override public void analyze(Dependency dependency, Engine engine) throws AnalysisException { @@ -145,10 +150,24 @@ public class NvdCveAnalyzer implements Analyzer { /** * Opens the database used to gather NVD CVE data. * - * @throws Exception is thrown if there is an issue opening the index. + * @throws InitializationException is thrown if there is an issue opening the index. */ @Override - public void initialize() throws Exception { - this.open(); + public void initialize() throws InitializationException { + try { + this.open(); + } catch (SQLException ex) { + LOGGER.debug("SQL Exception initializing NvdCveAnalyzer", ex); + throw new InitializationException(ex); + } catch (IOException ex) { + LOGGER.debug("IO Exception initializing NvdCveAnalyzer", ex); + throw new InitializationException(ex); + } catch (DatabaseException ex) { + LOGGER.debug("Database Exception initializing NvdCveAnalyzer", ex); + throw new InitializationException(ex); + } catch (ClassNotFoundException ex) { + LOGGER.debug("Exception initializing NvdCveAnalyzer", ex); + throw new InitializationException(ex); + } } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java index bcc7728d7..c886814b6 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/OpenSSLAnalyzer.java @@ -31,6 +31,7 @@ import java.io.IOException; import java.nio.charset.Charset; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.owasp.dependencycheck.exception.InitializationException; /** * Used to analyze OpenSSL source code present in the file system. @@ -145,10 +146,10 @@ public class OpenSSLAnalyzer extends AbstractFileTypeAnalyzer { /** * No-op initializer implementation. * - * @throws Exception never thrown + * @throws InitializationException never thrown */ @Override - protected void initializeFileTypeAnalyzer() throws Exception { + protected void initializeFileTypeAnalyzer() throws InitializationException { // Nothing to do here. } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.java index 5fdadf0e6..30cf1ed13 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonDistributionAnalyzer.java @@ -23,6 +23,7 @@ import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FilenameFilter; +import java.io.IOException; import org.apache.commons.io.filefilter.NameFileFilter; import org.apache.commons.io.filefilter.SuffixFileFilter; import org.apache.commons.io.input.AutoCloseInputStream; @@ -37,6 +38,7 @@ import org.slf4j.LoggerFactory; import javax.mail.MessagingException; import javax.mail.internet.InternetHeaders; +import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.utils.ExtractionException; import org.owasp.dependencycheck.utils.ExtractionUtil; import org.owasp.dependencycheck.utils.FileFilterBuilder; @@ -45,8 +47,9 @@ import org.owasp.dependencycheck.utils.Settings; import org.owasp.dependencycheck.utils.UrlStringUtils; /** - * Used to analyze a Wheel or egg distribution files, or their contents in unzipped form, and collect information that can be used - * to determine the associated CPE. + * Used to analyze a Wheel or egg distribution files, or their contents in + * unzipped form, and collect information that can be used to determine the + * associated CPE. * * @author Dale Visser */ @@ -70,7 +73,8 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { .getLogger(PythonDistributionAnalyzer.class); /** - * The count of directories created during analysis. This is used for creating temporary directories. + * The count of directories created during analysis. This is used for + * creating temporary directories. */ private static int dirCount = 0; @@ -104,7 +108,8 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { private File tempFileLocation; /** - * Filter that detects *.dist-info files (but doesn't verify they are directories. + * Filter that detects *.dist-info files (but doesn't verify they are + * directories. */ private static final FilenameFilter DIST_INFO_FILTER = new SuffixFileFilter( ".dist-info"); @@ -164,7 +169,8 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Returns the key used in the properties file to reference the analyzer's enabled property. + * Returns the key used in the properties file to reference the analyzer's + * enabled property. * * @return the analyzer's enabled property setting key */ @@ -206,7 +212,8 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { * @param dependency the archive being scanned * @param folderFilter the filter to apply to the folder * @param metadataFilter the filter to apply to the meta data - * @throws AnalysisException thrown when there is a problem analyzing the dependency + * @throws AnalysisException thrown when there is a problem analyzing the + * dependency */ private void collectMetadataFromArchiveFormat(Dependency dependency, FilenameFilter folderFilter, FilenameFilter metadataFilter) @@ -230,23 +237,31 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { /** * Makes sure a usable temporary directory is available. * - * @throws Exception an AnalyzeException is thrown when the temp directory cannot be created + * @throws InitializationException an AnalyzeException is thrown when the + * temp directory cannot be created */ @Override - protected void initializeFileTypeAnalyzer() throws Exception { - final File baseDir = Settings.getTempDirectory(); - tempFileLocation = File.createTempFile("check", "tmp", baseDir); - if (!tempFileLocation.delete()) { - final String msg = String.format( - "Unable to delete temporary file '%s'.", - tempFileLocation.getAbsolutePath()); - throw new AnalysisException(msg); - } - if (!tempFileLocation.mkdirs()) { - final String msg = String.format( - "Unable to create directory '%s'.", - tempFileLocation.getAbsolutePath()); - throw new AnalysisException(msg); + protected void initializeFileTypeAnalyzer() throws InitializationException { + try { + final File baseDir = Settings.getTempDirectory(); + tempFileLocation = File.createTempFile("check", "tmp", baseDir); + if (!tempFileLocation.delete()) { + setEnabled(false); + final String msg = String.format( + "Unable to delete temporary file '%s'.", + tempFileLocation.getAbsolutePath()); + throw new InitializationException(msg); + } + if (!tempFileLocation.mkdirs()) { + setEnabled(false); + final String msg = String.format( + "Unable to create directory '%s'.", + tempFileLocation.getAbsolutePath()); + throw new InitializationException(msg); + } + } catch (IOException ex) { + setEnabled(false); + throw new InitializationException("Unable to create a temporary file", ex); } } @@ -312,7 +327,8 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Returns a list of files that match the given filter, this does not recursively scan the directory. + * Returns a list of files that match the given filter, this does not + * recursively scan the directory. * * @param folder the folder to filter * @param filter the filter to apply to the files in the directory @@ -351,7 +367,8 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer { } /** - * Retrieves the next temporary destination directory for extracting an archive. + * Retrieves the next temporary destination directory for extracting an + * archive. * * @return a directory * @throws AnalysisException thrown if unable to create temporary directory diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java index e0b8aa9ab..df532e051 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/PythonPackageAnalyzer.java @@ -37,6 +37,7 @@ import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import org.owasp.dependencycheck.exception.InitializationException; /** * Used to analyze a Python package, and collect information that can be used to @@ -144,10 +145,10 @@ public class PythonPackageAnalyzer extends AbstractFileTypeAnalyzer { /** * No-op initializer implementation. * - * @throws Exception never thrown + * @throws InitializationException never thrown */ @Override - protected void initializeFileTypeAnalyzer() throws Exception { + protected void initializeFileTypeAnalyzer() throws InitializationException { // Nothing to do here. } 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 087184bdd..9b63eaa6c 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 @@ -22,6 +22,7 @@ import java.io.File; import java.io.FileFilter; import java.io.IOException; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -40,6 +41,7 @@ import org.owasp.dependencycheck.utils.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.owasp.dependencycheck.data.nvdcve.DatabaseException; +import org.owasp.dependencycheck.exception.InitializationException; /** * Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party @@ -126,10 +128,10 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { * Initialize the analyzer. In this case, extract GrokAssembly.exe to a * temporary location. * - * @throws Exception if anything goes wrong + * @throws InitializationException if anything goes wrong */ @Override - public void initializeFileTypeAnalyzer() throws Exception { + public void initializeFileTypeAnalyzer() throws InitializationException { try { cvedb = new CveDB(); cvedb.open(); @@ -137,25 +139,36 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { LOGGER.warn("Exception opening the database"); LOGGER.debug("error", ex); setEnabled(false); - throw ex; + throw new InitializationException("Error connecting to the database", ex); } // Now, need to see if bundle-audit actually runs from this location. Process process = null; try { process = launchBundleAudit(Settings.getTempDirectory()); } catch (AnalysisException ae) { - LOGGER.warn("Exception from bundle-audit process: {}. Disabling {}", ae.getCause(), ANALYZER_NAME); + setEnabled(false); cvedb.close(); cvedb = null; - throw ae; + String msg = String.format("Exception from bundle-audit process: %s. Disabling %s", ae.getCause(), ANALYZER_NAME); + throw new InitializationException(msg, ae); + } catch (IOException ex) { + setEnabled(false); + throw new InitializationException("Unable to create temporary file, the Ruby Bundle Audit Analyzer will be disabled", ex); } - final int exitValue = process.waitFor(); - if (0 == exitValue) { - LOGGER.warn("Unexpected exit code from bundle-audit process. Disabling {}: {}", ANALYZER_NAME, exitValue); + final int exitValue; + try { + exitValue = process.waitFor(); + } catch (InterruptedException ex) { setEnabled(false); - throw new AnalysisException("Unexpected exit code from bundle-audit process."); + String msg = String.format("Bundle-audit process was interupted. Disabling %s", ANALYZER_NAME); + throw new InitializationException(msg); + } + if (0 == exitValue) { + setEnabled(false); + String msg = String.format("Unexpected exit code from bundle-audit process. Disabling %s: %s", ANALYZER_NAME, exitValue); + throw new InitializationException(msg); } else { BufferedReader reader = null; try { @@ -163,18 +176,28 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer { if (!reader.ready()) { LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME); setEnabled(false); - throw new AnalysisException("Bundle-audit error stream unexpectedly not ready."); + throw new InitializationException("Bundle-audit error stream unexpectedly not ready."); } else { final String line = reader.readLine(); if (line == null || !line.contains("Errno::ENOENT")) { LOGGER.warn("Unexpected bundle-audit output. Disabling {}: {}", ANALYZER_NAME, line); setEnabled(false); - throw new AnalysisException("Unexpected bundle-audit output."); + throw new InitializationException("Unexpected bundle-audit output."); } } + } catch (UnsupportedEncodingException ex) { + setEnabled(false); + throw new InitializationException("Unexpected bundle-audit encoding.", ex); + } catch (IOException ex) { + setEnabled(false); + throw new InitializationException("Unable to read bundle-audit output.", ex); } finally { if (null != reader) { - reader.close(); + try { + reader.close(); + } catch (IOException ex) { + LOGGER.debug("Error closing reader", ex); + } } } } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java index 56faf90a6..9b158531e 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyGemspecAnalyzer.java @@ -32,6 +32,7 @@ import org.owasp.dependencycheck.analyzer.exception.AnalysisException; import org.owasp.dependencycheck.dependency.Confidence; import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.dependency.EvidenceCollection; +import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.utils.FileFilterBuilder; import org.owasp.dependencycheck.utils.Settings; import org.slf4j.Logger; @@ -88,7 +89,7 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer { } @Override - protected void initializeFileTypeAnalyzer() throws Exception { + protected void initializeFileTypeAnalyzer() throws InitializationException { // NO-OP } diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/exception/InitializationException.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/exception/InitializationException.java new file mode 100644 index 000000000..f818ebff6 --- /dev/null +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/exception/InitializationException.java @@ -0,0 +1,66 @@ +/* + * This file is part of dependency-check-core. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * Copyright (c) 2016 Jeremy Long. All Rights Reserved. + */ +package org.owasp.dependencycheck.exception; + +/** + * An exception used when initializing analyzers. + * + * @author Jeremy Long + */ +public class InitializationException extends Exception { + + /** + * The serial version uid. + */ + private static final long serialVersionUID = 1L; + + /** + * Creates a new InitializationException. + */ + public InitializationException() { + super(); + } + + /** + * Creates a new InitializationException. + * + * @param msg a message for the exception. + */ + public InitializationException(String msg) { + super(msg); + } + + /** + * Creates a new InitializationException. + * + * @param ex the cause of the exception. + */ + public InitializationException(Throwable ex) { + super(ex); + } + + /** + * Creates a new InitializationException. + * + * @param msg a message for the exception. + * @param ex the cause of the exception. + */ + public InitializationException(String msg, Throwable ex) { + super(msg, ex); + } +} diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java index 866a99a53..ddb075af2 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AbstractSuppressionAnalyzerTest.java @@ -23,7 +23,6 @@ import org.owasp.dependencycheck.BaseTest; import org.owasp.dependencycheck.Engine; import org.owasp.dependencycheck.analyzer.exception.AnalysisException; import org.owasp.dependencycheck.dependency.Dependency; -import org.owasp.dependencycheck.xml.suppression.SuppressionParseException; import org.owasp.dependencycheck.xml.suppression.SuppressionRule; import org.owasp.dependencycheck.utils.Settings; import org.slf4j.LoggerFactory; @@ -35,6 +34,7 @@ import java.util.Set; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import org.owasp.dependencycheck.exception.InitializationException; /** * @author Jeremy Long @@ -49,7 +49,8 @@ public class AbstractSuppressionAnalyzerTest extends BaseTest { } /** - * Test of getSupportedExtensions method, of class AbstractSuppressionAnalyzer. + * Test of getSupportedExtensions method, of class + * AbstractSuppressionAnalyzer. */ @Test public void testGetSupportedExtensions() { @@ -58,7 +59,8 @@ public class AbstractSuppressionAnalyzerTest extends BaseTest { } /** - * Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL. + * Test of getRules method, of class AbstractSuppressionAnalyzer for + * suppression file declared as URL. */ @Test public void testGetRulesFromSuppressionFileFromURL() throws Exception { @@ -70,7 +72,8 @@ public class AbstractSuppressionAnalyzerTest extends BaseTest { } /** - * Test of getRules method, of class AbstractSuppressionAnalyzer for suppression file declared as URL. + * Test of getRules method, of class AbstractSuppressionAnalyzer for + * suppression file declared as URL. */ @Test public void testGetRulesFromSuppressionFileInClasspath() throws Exception { @@ -81,7 +84,7 @@ public class AbstractSuppressionAnalyzerTest extends BaseTest { assertTrue(expCount <= currentSize); } - @Test(expected = SuppressionParseException.class) + @Test(expected = InitializationException.class) public void testFailureToLocateSuppressionFileAnywhere() throws Exception { Settings.setString(Settings.KEYS.SUPPRESSION_FILE, "doesnotexist.xml"); instance.initialize(); diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java index 6cdbae18a..f6508b203 100644 --- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java +++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/AssemblyAnalyzerTest.java @@ -31,6 +31,7 @@ import org.owasp.dependencycheck.analyzer.exception.AnalysisException; import org.owasp.dependencycheck.dependency.Confidence; import org.owasp.dependencycheck.dependency.Dependency; import org.owasp.dependencycheck.dependency.Evidence; +import org.owasp.dependencycheck.exception.InitializationException; import org.owasp.dependencycheck.utils.Settings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -157,8 +158,8 @@ public class AssemblyAnalyzerTest extends BaseTest { AssemblyAnalyzer aanalyzer = new AssemblyAnalyzer(); aanalyzer.accept(new File("test.dll")); // trick into "thinking it is active" aanalyzer.initialize(); - fail("Expected an AnalysisException"); - } catch (AnalysisException ae) { + fail("Expected an InitializationException"); + } catch (InitializationException ae) { assertEquals("An error occurred with the .NET AssemblyAnalyzer", ae.getMessage()); } finally { System.setProperty(LOG_KEY, oldProp);