diff --git a/.github/issue_template.md b/.github/issue_template.md
new file mode 100644
index 000000000..f2a77a5bc
--- /dev/null
+++ b/.github/issue_template.md
@@ -0,0 +1,18 @@
+### Reporting Bugs/Errors
+When reporting errors, 99% of the time log file output is required. Please post the log file as a [gist](https://gist.github.com/) and provide a link in the new issue.
+
+### Reporting False Positives
+When reporting a false positive please include:
+- The location of the dependency (Maven GAV, URL to download the dependency, etc.)
+- The CPE that is believed to be false positive
+ - Please report the CPE not the CVE
+
+#### Example
+False positive on library foo.jar - reported as cpe:/a:apache:tomcat:7.0
+```xml
+
- * 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}.Example:
*
@@ -138,7 +141,8 @@ public class DependencyCheckScanAgent {
}
/**
- * Specifies the destination directory for the generated Dependency-Check report.
+ * Specifies the destination directory for the generated Dependency-Check
+ * report.
*/
private String reportOutputDirectory;
@@ -161,9 +165,11 @@ public class DependencyCheckScanAgent {
}
/**
- * Specifies if the build should be failed if a CVSS score above a specified level is identified. The default is 11 which
- * means since the CVSS scores are 0-10, by default the build will never fail and the CVSS score is set to 11. The valid range
- * for the fail build on CVSS is 0 to 11, where anything above 10 will not cause the build to fail.
+ * Specifies if the build should be failed if a CVSS score above a specified
+ * level is identified. The default is 11 which means since the CVSS scores
+ * are 0-10, by default the build will never fail and the CVSS score is set
+ * to 11. The valid range for the fail build on CVSS is 0 to 11, where
+ * anything above 10 will not cause the build to fail.
*/
private float failBuildOnCVSS = 11;
@@ -186,8 +192,8 @@ public class DependencyCheckScanAgent {
}
/**
- * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not recommended that this be turned to false. Default
- * is true.
+ * Sets whether auto-updating of the NVD CVE/CPE data is enabled. It is not
+ * recommended that this be turned to false. Default is true.
*/
private boolean autoUpdate = true;
@@ -233,8 +239,9 @@ public class DependencyCheckScanAgent {
}
/**
- * The report format to be generated (HTML, XML, VULN, ALL). This configuration option has no affect if using this within the
- * Site plugin unless the externalReport is set to true. Default is HTML.
+ * The report format to be generated (HTML, XML, VULN, ALL). This
+ * configuration option has no affect if using this within the Site plugin
+ * unless the externalReport is set to true. Default is HTML.
*/
private ReportGenerator.Format reportFormat = ReportGenerator.Format.HTML;
@@ -283,7 +290,9 @@ public class DependencyCheckScanAgent {
* Get the value of proxyServer.
*
* @return the value of proxyServer
- * @deprecated use {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#getProxyServer()} instead
+ * @deprecated use
+ * {@link org.owasp.dependencycheck.agent.DependencyCheckScanAgent#getProxyServer()}
+ * instead
*/
@Deprecated
public String getProxyUrl() {
@@ -694,8 +703,8 @@ public class DependencyCheckScanAgent {
}
/**
- * Additional ZIP File extensions to add analyze. This should be a comma-separated list of file extensions to treat like ZIP
- * files.
+ * Additional ZIP File extensions to add analyze. This should be a
+ * comma-separated list of file extensions to treat like ZIP files.
*/
private String zipExtensions;
@@ -836,11 +845,17 @@ public class DependencyCheckScanAgent {
* Executes the Dependency-Check on the dependent libraries.
*
* @return the Engine used to scan the dependencies.
- * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException thrown if there is an exception connecting to the database
+ * @throws ExceptionCollection a collection of one or more exceptions that
+ * occurred during analysis.
*/
- private Engine executeDependencyCheck() throws DatabaseException {
+ private Engine executeDependencyCheck() throws ExceptionCollection {
populateSettings();
- final Engine engine = new Engine();
+ final Engine engine;
+ try {
+ engine = new Engine();
+ } catch (DatabaseException ex) {
+ throw new ExceptionCollection(ex, true);
+ }
engine.setDependencies(this.dependencies);
engine.analyzeDependencies();
return engine;
@@ -881,8 +896,9 @@ public class DependencyCheckScanAgent {
}
/**
- * Takes the properties supplied and updates the dependency-check settings. Additionally, this sets the system properties
- * required to change the proxy server, port, and connection timeout.
+ * Takes the properties supplied and updates the dependency-check settings.
+ * Additionally, this sets the system properties required to change the
+ * proxy server, port, and connection timeout.
*/
private void populateSettings() {
Settings.initialize();
@@ -925,7 +941,8 @@ public class DependencyCheckScanAgent {
* Executes the dependency-check and generates the report.
*
* @return a reference to the engine used to perform the scan.
- * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if there is an exception executing the scan.
+ * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if
+ * there is an exception executing the scan.
*/
public Engine execute() throws ScanAgentException {
Engine engine = null;
@@ -940,10 +957,12 @@ public class DependencyCheckScanAgent {
if (this.failBuildOnCVSS <= 10) {
checkForFailure(engine.getDependencies());
}
- } catch (DatabaseException ex) {
- LOGGER.error(
- "Unable to connect to the dependency-check database; analysis has stopped");
- LOGGER.debug("", ex);
+ } catch (ExceptionCollection ex) {
+ if (ex.isFatal()) {
+ LOGGER.error("A fatal exception occurred during analysis; analysis has stopped. Please see the debug log for more details.");
+ LOGGER.debug("", ex);
+ }
+ throw new ScanAgentException("One or more exceptions occurred during analysis; please see the debug log for more details.", ex);
} finally {
Settings.cleanup(true);
if (engine != null) {
@@ -954,11 +973,12 @@ public class DependencyCheckScanAgent {
}
/**
- * Checks to see if a vulnerability has been identified with a CVSS score that is above the threshold set in the
- * configuration.
+ * Checks to see if a vulnerability has been identified with a CVSS score
+ * that is above the threshold set in the configuration.
*
* @param dependencies the list of dependency objects
- * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if there is an exception executing the scan.
+ * @throws org.owasp.dependencycheck.exception.ScanAgentException thrown if
+ * there is an exception executing the scan.
*/
private void checkForFailure(List
- * 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 812f70394..4667d5f78 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,9 +25,10 @@ import java.net.URL; import java.util.List; import java.util.Set; import java.util.regex.Pattern; -import org.owasp.dependencycheck.suppression.SuppressionParseException; -import org.owasp.dependencycheck.suppression.SuppressionParser; -import org.owasp.dependencycheck.suppression.SuppressionRule; +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; import org.owasp.dependencycheck.utils.DownloadFailedException; import org.owasp.dependencycheck.utils.Downloader; import org.owasp.dependencycheck.utils.FileUtils; @@ -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) { @@ -129,29 +130,37 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer { } } else { file = new File(suppressionFilePath); + InputStream suppressionsFromClasspath = null; if (!file.exists()) { - final InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath); - if (suppressionsFromClasspath != null) { - deleteTempFile = true; - file = FileUtils.getTempFile("suppression", "xml"); - try { - org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file); - } catch (IOException ex) { - throwSuppressionParseException("Unable to locate suppressions file in classpath", ex); + try { + suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath); + if (suppressionsFromClasspath != null) { + deleteTempFile = true; + file = FileUtils.getTempFile("suppression", "xml"); + try { + org.apache.commons.io.FileUtils.copyInputStreamToFile(suppressionsFromClasspath, file); + } catch (IOException ex) { + throwSuppressionParseException("Unable to locate suppressions file in classpath", ex); + } + } + } finally { + if (suppressionsFromClasspath != null) { + try { + suppressionsFromClasspath.close(); + } catch (IOException ex) { + LOGGER.debug("Failed to close stream", ex); + } } } } } - 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..e8110eede 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); } } @@ -349,6 +357,12 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { */ private void extractFiles(File archive, File destination, Engine engine) throws AnalysisException { if (archive != null && destination != null) { + String archiveExt = FileUtils.getFileExtension(archive.getName()); + if (archiveExt == null) { + return; + } + archiveExt = archiveExt.toLowerCase(); + FileInputStream fis; try { fis = new FileInputStream(archive); @@ -356,10 +370,9 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { LOGGER.debug("", ex); throw new AnalysisException("Archive file was not found.", ex); } - final String archiveExt = FileUtils.getFileExtension(archive.getName()).toLowerCase(); try { if (ZIPPABLES.contains(archiveExt)) { - BufferedInputStream in = new BufferedInputStream(fis); + final BufferedInputStream in = new BufferedInputStream(fis); ensureReadableJar(archiveExt, in); extractArchive(new ZipArchiveInputStream(in), destination, engine); } else if ("tar".equals(archiveExt)) { @@ -405,9 +418,10 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { private void ensureReadableJar(final String archiveExt, BufferedInputStream in) throws IOException { if ("jar".equals(archiveExt) && in.markSupported()) { in.mark(7); - byte[] b = new byte[7]; - in.read(b); - if (b[0] == '#' + final byte[] b = new byte[7]; + final int read = in.read(b); + if (read == 7 + && b[0] == '#' && b[1] == '!' && b[2] == '/' && b[3] == 'b' @@ -433,6 +447,8 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer { } } } + } else { + in.reset(); } } } 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..9501da8e6 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,13 @@ 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; +import org.apache.commons.lang3.SystemUtils; /** - * 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 * @@ -82,18 +86,19 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer { * * @return the list of arguments to begin populating the ProcessBuilder */ - private Listtrue if the file exists; otherwise
+ * false
+ */
+ private boolean isInPath(String file) {
+ final ProcessBuilder pb = new ProcessBuilder("which", file);
+ try {
+ final Process proc = pb.start();
+ final int retCode = proc.waitFor();
+ if (retCode == 0) {
+ return true;
+ }
+ } catch (IOException ex) {
+ LOGGER.debug("Path seach failed for " + file);
+ } catch (InterruptedException ex) {
+ LOGGER.debug("Path seach failed for " + file);
+ }
+ return false;
+ }
}
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..3220b30a8 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,13 +188,17 @@ 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 * @param contents the version information */ + @edu.umd.cs.findbugs.annotations.SuppressFBWarnings( + value = "DM_DEFAULT_ENCODING", + justification = "Default encoding is only used if UTF-8 is not available") private void analyzeSetVersionCommand(Dependency dependency, Engine engine, String contents) { Dependency currentDep = dependency; 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..cd1a194bd 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 @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.List; import java.util.Set; import java.util.StringTokenizer; +import org.apache.commons.lang3.builder.CompareToBuilder; import org.apache.lucene.document.Document; import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.queryparser.classic.ParseException; @@ -45,6 +46,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 +125,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); + } } /** @@ -540,7 +551,7 @@ public class CPEAnalyzer implements Analyzer { final Listtrue 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.
*/
@@ -219,7 +229,8 @@ public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
LOGGER.warn("Unable to download pom.xml for {} from Central; "
+ "this could result in undetected CPE/CVEs.", dependency.getFileName());
} finally {
- if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) {
+ if (pomFile != null && pomFile.exists() && !FileUtils.deleteQuietly(pomFile)) {
+ LOGGER.debug("Failed to delete temporary pom file {}", pomFile.toString());
pomFile.deleteOnExit();
}
}
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CocoaPodsAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CocoaPodsAnalyzer.java
new file mode 100644
index 000000000..1108d5e6a
--- /dev/null
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CocoaPodsAnalyzer.java
@@ -0,0 +1,205 @@
+/*
+ * 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 IBM Corporation. All Rights Reserved.
+ */
+package org.owasp.dependencycheck.analyzer;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.io.FileUtils;
+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.EvidenceCollection;
+import org.owasp.dependencycheck.utils.FileFilterBuilder;
+import org.owasp.dependencycheck.utils.Settings;
+
+/**
+ * This analyzer is used to analyze SWIFT and Objective-C packages by collecting
+ * information from .podspec files. CocoaPods dependency manager see
+ * https://cocoapods.org/.
+ *
+ * @author Bianca Jiang (https://twitter.com/biancajiang)
+ */
+@Experimental
+public class CocoaPodsAnalyzer extends AbstractFileTypeAnalyzer {
+
+ /**
+ * The logger.
+ */
+// private static final Logger LOGGER = LoggerFactory.getLogger(CocoaPodsAnalyzer.class);
+ /**
+ * The name of the analyzer.
+ */
+ private static final String ANALYZER_NAME = "CocoaPods Package Analyzer";
+
+ /**
+ * The phase that this analyzer is intended to run in.
+ */
+ private static final AnalysisPhase ANALYSIS_PHASE = AnalysisPhase.INFORMATION_COLLECTION;
+
+ /**
+ * The file name to scan.
+ */
+ public static final String PODSPEC = "podspec";
+ /**
+ * Filter that detects files named "*.podspec".
+ */
+ private static final FileFilter PODSPEC_FILTER = FileFilterBuilder.newInstance().addExtensions(PODSPEC).build();
+
+ /**
+ * The capture group #1 is the block variable. e.g. "Pod::Spec.new do
+ * |spec|"
+ */
+ private static final Pattern PODSPEC_BLOCK_PATTERN = Pattern.compile("Pod::Spec\\.new\\s+?do\\s+?\\|(.+?)\\|");
+
+ /**
+ * Returns the FileFilter
+ *
+ * @return the FileFilter
+ */
+ @Override
+ protected FileFilter getFileFilter() {
+ return PODSPEC_FILTER;
+ }
+
+ @Override
+ protected void initializeFileTypeAnalyzer() {
+ // NO-OP
+ }
+
+ /**
+ * Returns the name of the analyzer.
+ *
+ * @return the name of the analyzer.
+ */
+ @Override
+ public String getName() {
+ return ANALYZER_NAME;
+ }
+
+ /**
+ * Returns the phase that the analyzer is intended to run in.
+ *
+ * @return the phase that the analyzer is intended to run in.
+ */
+ @Override
+ public AnalysisPhase getAnalysisPhase() {
+ return ANALYSIS_PHASE;
+ }
+
+ /**
+ * Returns the key used in the properties file to reference the analyzer's
+ * enabled property.
+ *
+ * @return the analyzer's enabled property setting key
+ */
+ @Override
+ protected String getAnalyzerEnabledSettingKey() {
+ return Settings.KEYS.ANALYZER_COCOAPODS_ENABLED;
+ }
+
+ @Override
+ protected void analyzeFileType(Dependency dependency, Engine engine)
+ throws AnalysisException {
+
+ String contents;
+ try {
+ contents = FileUtils.readFileToString(dependency.getActualFile(), Charset.defaultCharset());
+ } catch (IOException e) {
+ throw new AnalysisException(
+ "Problem occurred while reading dependency file.", e);
+ }
+ final Matcher matcher = PODSPEC_BLOCK_PATTERN.matcher(contents);
+ if (matcher.find()) {
+ contents = contents.substring(matcher.end());
+ final String blockVariable = matcher.group(1);
+
+ final EvidenceCollection vendor = dependency.getVendorEvidence();
+ final EvidenceCollection product = dependency.getProductEvidence();
+ final EvidenceCollection version = dependency.getVersionEvidence();
+
+ final String name = addStringEvidence(product, contents, blockVariable, "name", "name", Confidence.HIGHEST);
+ if (!name.isEmpty()) {
+ vendor.addEvidence(PODSPEC, "name_project", name, Confidence.HIGHEST);
+ }
+ addStringEvidence(product, contents, blockVariable, "summary", "summary", Confidence.HIGHEST);
+
+ addStringEvidence(vendor, contents, blockVariable, "author", "authors?", Confidence.HIGHEST);
+ addStringEvidence(vendor, contents, blockVariable, "homepage", "homepage", Confidence.HIGHEST);
+ addStringEvidence(vendor, contents, blockVariable, "license", "licen[cs]es?", Confidence.HIGHEST);
+
+ addStringEvidence(version, contents, blockVariable, "version", "version", Confidence.HIGHEST);
+ }
+
+ setPackagePath(dependency);
+ }
+
+ /**
+ * Extracts evidence from the contents and adds it to the given evidence
+ * collection.
+ *
+ * @param evidences the evidence collection to update
+ * @param contents the text to extract evidence from
+ * @param blockVariable the block variable within the content to search for
+ * @param field the name of the field being searched for
+ * @param fieldPattern the field pattern within the contents to search for
+ * @param confidence the confidence level of the evidence if found
+ * @return the string that was added as evidence
+ */
+ private String addStringEvidence(EvidenceCollection evidences, String contents,
+ String blockVariable, String field, String fieldPattern, Confidence confidence) {
+ String value = "";
+
+ //capture array value between [ ]
+ final Matcher arrayMatcher = Pattern.compile(
+ String.format("\\s*?%s\\.%s\\s*?=\\s*?\\{\\s*?(.*?)\\s*?\\}", blockVariable, fieldPattern),
+ Pattern.CASE_INSENSITIVE).matcher(contents);
+ if (arrayMatcher.find()) {
+ value = arrayMatcher.group(1);
+ } else { //capture single value between quotes
+ final Matcher matcher = Pattern.compile(
+ String.format("\\s*?%s\\.%s\\s*?=\\s*?(['\"])(.*?)\\1", blockVariable, fieldPattern),
+ Pattern.CASE_INSENSITIVE).matcher(contents);
+ if (matcher.find()) {
+ value = matcher.group(2);
+ }
+ }
+ if (value.length() > 0) {
+ evidences.addEvidence(PODSPEC, field, value, confidence);
+ }
+ return value;
+ }
+
+ /**
+ * Sets the package path on the given dependency.
+ *
+ * @param dep the dependency to update
+ */
+ private void setPackagePath(Dependency dep) {
+ final File file = new File(dep.getFilePath());
+ final String parent = file.getParent();
+ if (parent != null) {
+ dep.setPackagePath(parent);
+ }
+ }
+}
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/CpeSuppressionAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.java
index a256c46f1..537fa731c 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/CpeSuppressionAnalyzer.java
@@ -20,7 +20,7 @@ package org.owasp.dependencycheck.analyzer;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.dependency.Dependency;
-import org.owasp.dependencycheck.suppression.SuppressionRule;
+import org.owasp.dependencycheck.xml.suppression.SuppressionRule;
/**
* The suppression analyzer processes an externally defined XML document that complies with the suppressions.xsd schema.
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java
index 419eacb09..946194ab9 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/DependencyBundlingAnalyzer.java
@@ -117,6 +117,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer implements Anal
final ListIteratortrue if the dependencies appear to be the same;
+ * otherwise false
+ */
+ private boolean isSameSwiftPackage(Dependency dependency1, Dependency dependency2) {
+ if (dependency1 == null || dependency2 == null
+ || (!dependency1.getFileName().endsWith(".podspec")
+ && !dependency1.getFileName().equals("Package.swift"))
+ || (!dependency2.getFileName().endsWith(".podspec")
+ && !dependency2.getFileName().equals("Package.swift"))
+ || dependency1.getPackagePath() == null
+ || dependency2.getPackagePath() == null) {
+ return false;
+ }
+ if (dependency1.getPackagePath().equalsIgnoreCase(dependency2.getPackagePath())) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Determines which of the swift dependencies should be considered the
+ * primary.
+ *
+ * @param dependency1 the first swift dependency to compare
+ * @param dependency2 the second swift dependency to compare
+ * @return the primary swift dependency
+ */
+ private Dependency getMainSwiftDependency(Dependency dependency1, Dependency dependency2) {
+ if (isSameSwiftPackage(dependency1, dependency2)) {
+ if (dependency1.getFileName().endsWith(".podspec")) {
+ return dependency1;
+ }
+ return dependency2;
+ }
+ return null;
+ }
+
/**
* This is likely a very broken attempt at determining if the 'left'
* dependency is the 'core' library in comparison to the 'right' library.
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java
index fcaaeb102..2aded7eb1 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/FileNameAnalyzer.java
@@ -70,11 +70,12 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
/**
* Python init files
*/
+ //CSOFF: WhitespaceAfter
private static final NameFileFilter IGNORED_FILES = new NameFileFilter(new String[]{
"__init__.py",
"__init__.pyc",
- "__init__.pyo",
- });
+ "__init__.pyo",});
+ //CSON: WhitespaceAfter
/**
* Collects information about the file name.
@@ -93,26 +94,27 @@ public class FileNameAnalyzer extends AbstractAnalyzer implements Analyzer {
//add version evidence
final DependencyVersion version = DependencyVersionUtil.parseVersion(fileName);
+ final String packageName = DependencyVersionUtil.parsePreVersion(fileName);
if (version != null) {
// If the version number is just a number like 2 or 23, reduce the confidence
// a shade. This should hopefully correct for cases like log4j.jar or
// struts2-core.jar
if (version.getVersionParts() == null || version.getVersionParts().size() < 2) {
- dependency.getVersionEvidence().addEvidence("file", "name",
+ dependency.getVersionEvidence().addEvidence("file", "version",
version.toString(), Confidence.MEDIUM);
} else {
dependency.getVersionEvidence().addEvidence("file", "version",
version.toString(), Confidence.HIGHEST);
}
dependency.getVersionEvidence().addEvidence("file", "name",
- fileName, Confidence.MEDIUM);
+ packageName, Confidence.MEDIUM);
}
if (!IGNORED_FILES.accept(f)) {
dependency.getProductEvidence().addEvidence("file", "name",
- fileName, Confidence.HIGH);
+ packageName, Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("file", "name",
- fileName, Confidence.HIGH);
+ packageName, Confidence.HIGH);
}
}
}
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 7279d11b8..beddaf39f 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,13 @@ 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.suppression.PropertyType;
-import org.owasp.dependencycheck.suppression.SuppressionParseException;
-import org.owasp.dependencycheck.suppression.SuppressionParser;
+import org.owasp.dependencycheck.exception.InitializationException;
+import org.owasp.dependencycheck.xml.suppression.PropertyType;
import org.owasp.dependencycheck.utils.DownloadFailedException;
import org.owasp.dependencycheck.utils.Downloader;
import org.owasp.dependencycheck.utils.FileUtils;
@@ -49,6 +46,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 +86,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);
+ }
}
//%s in this where the SHA-1 will get entered.%s in this where the SHA-1 will get entered.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
*/
@@ -240,7 +245,8 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
LOGGER.warn("Unable to download pom.xml for {} from Nexus repository; "
+ "this could result in undetected CPE/CVEs.", dependency.getFileName());
} finally {
- if (pomFile != null && !FileUtils.deleteQuietly(pomFile)) {
+ if (pomFile != null && pomFile.exists() && !FileUtils.deleteQuietly(pomFile)) {
+ LOGGER.debug("Failed to delete temporary pom file {}", pomFile.toString());
pomFile.deleteOnExit();
}
}
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..a82b0ebd9 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,9 +23,10 @@ import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
import org.apache.commons.io.filefilter.NameFileFilter;
import org.apache.commons.io.filefilter.SuffixFileFilter;
-import org.apache.commons.io.input.AutoCloseInputStream;
import org.apache.commons.lang3.StringUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
@@ -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)
@@ -221,32 +228,43 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
throw new AnalysisException(ex);
}
- collectWheelMetadata(
- dependency,
- getMatchingFile(getMatchingFile(temp, folderFilter),
- metadataFilter));
+ File matchingFile = getMatchingFile(temp, folderFilter);
+ if (matchingFile != null) {
+ matchingFile = getMatchingFile(matchingFile, metadataFilter);
+ if (matchingFile != null) {
+ collectWheelMetadata(dependency, matchingFile);
+ }
+ }
}
/**
* 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 +330,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
@@ -338,20 +357,30 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
if (null == manifest) {
LOGGER.debug("Manifest file not found.");
} else {
+ InputStream in = null;
try {
- result.load(new AutoCloseInputStream(new BufferedInputStream(
- new FileInputStream(manifest))));
+ in = new BufferedInputStream(new FileInputStream(manifest));
+ result.load(in);
} catch (MessagingException e) {
LOGGER.warn(e.getMessage(), e);
} catch (FileNotFoundException e) {
LOGGER.warn(e.getMessage(), e);
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException ex) {
+ LOGGER.debug("failed to close input stream", ex);
+ }
+ }
}
}
return result;
}
/**
- * 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..bca567fa5 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,24 +22,27 @@ import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.nio.charset.Charset;
+
import org.apache.commons.io.FileUtils;
import org.owasp.dependencycheck.Engine;
import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
+import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Reference;
import org.owasp.dependencycheck.dependency.Vulnerability;
+import org.owasp.dependencycheck.exception.InitializationException;
import org.owasp.dependencycheck.utils.FileFilterBuilder;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
/**
* Used to analyze Ruby Bundler Gemspec.lock files utilizing the 3rd party
@@ -50,6 +53,9 @@ import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
@Experimental
public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
+ /**
+ * The logger.
+ */
private static final Logger LOGGER = LoggerFactory.getLogger(RubyBundleAuditAnalyzer.class);
/**
@@ -126,10 +132,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 +143,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;
+ final String msg = String.format("Exception from bundle-audit process: %s. Disabling %s", ae.getCause(), ANALYZER_NAME);
+ throw new InitializationException(msg, ae);
+ } catch (IOException ex) {
+ 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.");
+ final String msg = String.format("Bundle-audit process was interupted. Disabling %s", ANALYZER_NAME);
+ throw new InitializationException(msg);
+ }
+ if (0 == exitValue) {
+ setEnabled(false);
+ final 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 +180,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);
+ }
}
}
}
@@ -253,11 +280,16 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
}
final File parentFile = dependency.getActualFile().getParentFile();
final Process process = launchBundleAudit(parentFile);
+ final int exitValue;
try {
- process.waitFor();
+ exitValue = process.waitFor();
} catch (InterruptedException ie) {
throw new AnalysisException("bundle-audit process interrupted", ie);
}
+ if (exitValue != 0) {
+ final String msg = String.format("Unexpected exit code from bundle-audit process; exit code: %s", exitValue);
+ throw new AnalysisException(msg);
+ }
BufferedReader rdr = null;
BufferedReader errReader = null;
try {
@@ -456,7 +488,9 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
*/
private Dependency createDependencyForGem(Engine engine, String parentName, String fileName, String filePath, String gem) throws IOException {
final File gemFile = new File(Settings.getTempDirectory(), gem + "_Gemfile.lock");
- gemFile.createNewFile();
+ if (!gemFile.createNewFile()) {
+ throw new IOException("Unable to create temporary gem file");
+ }
final String displayFileName = String.format("%s%c%s:%s", parentName, File.separatorChar, fileName, gem);
FileUtils.write(gemFile, displayFileName, Charset.defaultCharset()); // unique contents to avoid dependency bundling
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java
index ebe77e7b8..df394760f 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/analyzer/RubyBundlerAnalyzer.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*
- * Copyright (c) 2016 Bianca Jiang. All Rights Reserved.
+ * Copyright (c) 2016 IBM Corporation. All Rights Reserved.
*/
package org.owasp.dependencycheck.analyzer;
@@ -43,7 +43,7 @@ import org.owasp.dependencycheck.dependency.Dependency;
* {@link RubyGemspecAnalyzer}, so it will enabled/disabled with
* {@link RubyGemspecAnalyzer}.
*
- * @author Bianca Jiang (biancajiang@gmail.com)
+ * @author Bianca Jiang (https://twitter.com/biancajiang)
*/
@Experimental
public class RubyBundlerAnalyzer extends RubyGemspecAnalyzer {
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..020f15434 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
}
@@ -216,6 +217,9 @@ public class RubyGemspecAnalyzer extends AbstractFileTypeAnalyzer {
return name.contains(VERSION_FILE_NAME);
}
});
+ if (matchingFiles == null) {
+ return;
+ }
for (File f : matchingFiles) {
try {
final ListMavenArtifact is
- * populated with the GAV.
+ * Searches the configured Central URL for the given sha1 hash. If the
+ * artifact is found, a MavenArtifact is populated with the
+ * GAV.
*
* @param sha1 the SHA-1 hash string for which to search
* @return the populated Maven GAV.
- * @throws IOException if it's unable to connect to the specified repository or if the specified artifact is not found.
+ * @throws IOException if it's unable to connect to the specified repository
+ * or if the specified artifact is not found.
*/
public Listtrue if a newer version of the database has been released; otherwise false
- * @throws UpdateException thrown if there is an error connecting to the github documentation site or accessing the local
- * database.
+ * @return true if a newer version of the database has been
+ * released; otherwise false
+ * @throws UpdateException thrown if there is an error connecting to the
+ * github documentation site or accessing the local database.
*/
protected boolean shouldUpdate(final long lastChecked, final long now, final DatabaseProperties properties,
String currentVersion) throws UpdateException {
@@ -185,7 +200,8 @@ public class EngineVersionCheck implements CachedWebDataSource {
}
/**
- * Retrieves the current released version number from the github documentation site.
+ * Retrieves the current released version number from the github
+ * documentation site.
*
* @return the current released version number
*/
@@ -204,11 +220,11 @@ public class EngineVersionCheck implements CachedWebDataSource {
return releaseVersion.trim();
}
} catch (MalformedURLException ex) {
- LOGGER.debug("unable to retrieve current release version of dependency-check", ex);
+ LOGGER.debug("Unable to retrieve current release version of dependency-check - malformed url?");
} catch (URLConnectionFailureException ex) {
- LOGGER.debug("unable to retrieve current release version of dependency-check", ex);
+ LOGGER.debug("Unable to retrieve current release version of dependency-check - connection failed");
} catch (IOException ex) {
- LOGGER.debug("unable to retrieve current release version of dependency-check", ex);
+ LOGGER.debug("Unable to retrieve current release version of dependency-check - i/o exception");
} finally {
if (conn != null) {
conn.disconnect();
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java
index 8aa06c797..b28209af0 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/update/NvdCveUpdater.java
@@ -50,7 +50,7 @@ import org.slf4j.LoggerFactory;
public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource {
/**
- * The logger
+ * The logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(NvdCveUpdater.class);
/**
@@ -59,9 +59,8 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource {
public static final int MAX_THREAD_POOL_SIZE = Settings.getInt(Settings.KEYS.MAX_DOWNLOAD_THREAD_POOL_SIZE, 3);
/**
- * * Downloads the latest NVD CVE XML file from the web and imports it into - * the current CVE Database.
+ * the current CVE Database. * * @throws UpdateException is thrown if there is an error updating the * database @@ -78,15 +77,13 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { } if (autoUpdate && checkUpdate()) { final UpdateableNvdCve updateable = getUpdatesNeeded(); - getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); if (updateable.isUpdateNeeded()) { performUpdate(updateable); } + getProperties().save(DatabaseProperties.LAST_CHECKED, Long.toString(System.currentTimeMillis())); } } catch (MalformedURLException ex) { - LOGGER.warn( - "NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data."); - LOGGER.debug("", ex); + throw new UpdateException("NVD CVE properties files contain an invalid URL, unable to update the data to use the most current data.", ex); } catch (DownloadFailedException ex) { LOGGER.warn( "Unable to download the NVD CVE data; the results may not include the most recent CPE/CVEs from the NVD."); @@ -94,7 +91,7 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { LOGGER.info( "If you are behind a proxy you may need to configure dependency-check to use the proxy."); } - LOGGER.debug("", ex); + throw new UpdateException("Unable to download the NVD CVE data.", ex); } finally { closeDataStores(); } @@ -107,9 +104,9 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { * checking again. A database property stores the timestamp of the last * check. * - * @return true to proceed with the check, or false to skip. + * @return true to proceed with the check, or false to skip * @throws UpdateException thrown when there is an issue checking for - * updates. + * updates */ private boolean checkUpdate() throws UpdateException { boolean proceed = true; @@ -159,94 +156,86 @@ public class NvdCveUpdater extends BaseUpdater implements CachedWebDataSource { * @throws UpdateException is thrown if there is an error updating the * database */ - public void performUpdate(UpdateableNvdCve updateable) throws UpdateException { + private void performUpdate(UpdateableNvdCve updateable) throws UpdateException { int maxUpdates = 0; - try { - for (NvdCveInfo cve : updateable) { - if (cve.getNeedsUpdate()) { - maxUpdates += 1; + for (NvdCveInfo cve : updateable) { + if (cve.getNeedsUpdate()) { + maxUpdates += 1; + } + } + if (maxUpdates <= 0) { + return; + } + if (maxUpdates > 3) { + LOGGER.info("NVD CVE requires several updates; this could take a couple of minutes."); + } + + final int poolSize = (MAX_THREAD_POOL_SIZE < maxUpdates) ? MAX_THREAD_POOL_SIZE : maxUpdates; + + final ExecutorService downloadExecutors = Executors.newFixedThreadPool(poolSize); + final ExecutorService processExecutor = Executors.newSingleThreadExecutor(); + final Set- * A utility class to extract version numbers from file names (or other strings containing version numbers.
+ * A utility class to extract version numbers from file names (or other strings + * containing version numbers. * * @author Jeremy Long */ @@ -35,11 +36,19 @@ public final class DependencyVersionUtil { */ private static final Pattern RX_VERSION = Pattern.compile("\\d+(\\.\\d{1,6})+(\\.?([_-](release|beta|alpha|\\d+)|[a-zA-Z_-]{1,3}\\d{0,8}))?"); /** - * Regular expression to extract a single version number without periods. This is a last ditch effort just to check in case we - * are missing a version number using the previous regex. + * Regular expression to extract a single version number without periods. + * This is a last ditch effort just to check in case we are missing a + * version number using the previous regex. */ private static final Pattern RX_SINGLE_VERSION = Pattern.compile("\\d+(\\.?([_-](release|beta|alpha)|[a-zA-Z_-]{1,3}\\d{1,8}))?"); + /** + * Regular expression to extract the part before the version numbers if + * there are any based on RX_VERSION. In most cases, this part represents a + * more accurate name. + */ + private static final Pattern RX_PRE_VERSION = Pattern.compile("^(.+)[_-](\\d+\\.\\d{1,6})+"); + /** * Private constructor for utility class. */ @@ -48,7 +57,8 @@ public final class DependencyVersionUtil { /** *- * A utility class to extract version numbers from file names (or other strings containing version numbers.
+ * A utility class to extract version numbers from file names (or other + * strings containing version numbers. *
* Example:
* Give the file name: library-name-1.4.1r2-release.jar
@@ -95,4 +105,30 @@ public final class DependencyVersionUtil {
}
return new DependencyVersion(version);
}
+
+ /**
+ *
+ * A utility class to extract the part before version numbers from file
+ * names (or other strings containing version numbers. In most cases, this
+ * part represents a more accurate name than the full file name.
+ *
+ * Example:
+ * Give the file name: library-name-1.4.1r2-release.jar
+ * This function would return: library-name
+ *
+ * @param text the text being analyzed
+ * @return the part before the version numbers if any, otherwise return the
+ * text itself.
+ */
+ public static String parsePreVersion(String text) {
+ if (parseVersion(text) == null) {
+ return text;
+ }
+
+ final Matcher matcher = RX_PRE_VERSION.matcher(text);
+ if (matcher.find()) {
+ return matcher.group(1);
+ }
+ return text;
+ }
}
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintHandler.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintHandler.java
index bd1477e63..0608f5fa1 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintHandler.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintHandler.java
@@ -20,7 +20,7 @@ package org.owasp.dependencycheck.xml.hints;
import java.util.ArrayList;
import java.util.List;
import org.owasp.dependencycheck.dependency.Confidence;
-import org.owasp.dependencycheck.suppression.PropertyType;
+import org.owasp.dependencycheck.xml.suppression.PropertyType;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
@@ -62,9 +62,17 @@ public class HintHandler extends DefaultHandler {
*/
private static final String DUPLICATE = "duplicate";
/**
- * Attribute name.
+ * Attribute value.
*/
private static final String VENDOR = "vendor";
+ /**
+ * Attribute value.
+ */
+ private static final String PRODUCT = "product";
+ /**
+ * Attribute value.
+ */
+ private static final String VERSION = "version";
/**
* Attribute name.
*/
@@ -168,16 +176,25 @@ public class HintHandler extends DefaultHandler {
attr.getValue(VALUE),
Confidence.valueOf(attr.getValue(CONFIDENCE)));
}
- } else if (inAddNode) {
- rule.addAddProduct(attr.getValue(SOURCE),
- attr.getValue(NAME),
- attr.getValue(VALUE),
- Confidence.valueOf(attr.getValue(CONFIDENCE)));
- } else {
- rule.addGivenProduct(attr.getValue(SOURCE),
- attr.getValue(NAME),
- attr.getValue(VALUE),
- Confidence.valueOf(attr.getValue(CONFIDENCE)));
+ } else if (PRODUCT.equals(hintType)) {
+ if (inAddNode) {
+ rule.addAddProduct(attr.getValue(SOURCE),
+ attr.getValue(NAME),
+ attr.getValue(VALUE),
+ Confidence.valueOf(attr.getValue(CONFIDENCE)));
+ } else {
+ rule.addGivenProduct(attr.getValue(SOURCE),
+ attr.getValue(NAME),
+ attr.getValue(VALUE),
+ Confidence.valueOf(attr.getValue(CONFIDENCE)));
+ }
+ } else if (VERSION.equals(hintType)) {
+ if (inAddNode) {
+ rule.addAddVersion(attr.getValue(SOURCE),
+ attr.getValue(NAME),
+ attr.getValue(VALUE),
+ Confidence.valueOf(attr.getValue(CONFIDENCE)));
+ }
}
} else if (FILE_NAME.equals(qName)) {
final PropertyType pt = new PropertyType();
@@ -197,11 +214,11 @@ public class HintHandler extends DefaultHandler {
vendorDuplicatingHintRules.add(new VendorDuplicatingHintRule(attr.getValue(VALUE), attr.getValue(DUPLICATE)));
}
}
-
+
/**
* Handles the end element event.
*
- * @param uri the element's uri
+ * @param uri the element's URI
* @param localName the local name
* @param qName the qualified name
* @throws SAXException thrown if there is an exception processing the
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintParser.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintParser.java
index 5eb0aa6bb..96a35bdc9 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintParser.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintParser.java
@@ -64,7 +64,7 @@ public class HintParser {
/**
* The schema for the hint XML files.
*/
- private static final String HINT_SCHEMA = "schema/dependency-hint.1.0.xsd";
+ private static final String HINT_SCHEMA = "schema/dependency-hint.1.1.xsd";
/**
* Parses the given XML file and returns a list of the hints contained.
@@ -104,8 +104,9 @@ public class HintParser {
* @throws SAXException thrown if the XML cannot be parsed
*/
public Hints parseHints(InputStream inputStream) throws HintParseException, SAXException {
+ InputStream schemaStream = null;
try {
- final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(HINT_SCHEMA);
+ schemaStream = this.getClass().getClassLoader().getResourceAsStream(HINT_SCHEMA);
final HintHandler handler = new HintHandler();
final SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
@@ -141,6 +142,14 @@ public class HintParser {
} catch (IOException ex) {
LOGGER.debug("", ex);
throw new HintParseException(ex);
+ } finally {
+ if (schemaStream != null) {
+ try {
+ schemaStream.close();
+ } catch (IOException ex) {
+ LOGGER.debug("Error closing hint file stream", ex);
+ }
+ }
}
}
}
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintRule.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintRule.java
index 0ab10091d..7290ba26e 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintRule.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/HintRule.java
@@ -21,7 +21,7 @@ import java.util.ArrayList;
import java.util.List;
import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Evidence;
-import org.owasp.dependencycheck.suppression.PropertyType;
+import org.owasp.dependencycheck.xml.suppression.PropertyType;
/**
* A collection of product and vendor evidence to match; if any evidence is
@@ -72,9 +72,9 @@ public class HintRule {
}
/**
- * Get the value of givenProduct
+ * Get the value of givenProduct.
*
- * @return the value of givenProduct.
+ * @return the value of givenProduct
*/
public List getGivenProduct() {
return givenProduct;
@@ -85,6 +85,15 @@ public class HintRule {
*/
private final List givenVendor = new ArrayList();
+ /**
+ * The list of product evidence to add.
+ */
+ private final List addProduct = new ArrayList();
+ /**
+ * The list of version evidence to add.
+ */
+ private final List addVersion = new ArrayList();
+
/**
* Adds a given vendors to the list of evidence to matched.
*
@@ -106,11 +115,6 @@ public class HintRule {
return givenVendor;
}
- /**
- * The list of product evidence to add.
- */
- private final List addProduct = new ArrayList();
-
/**
* Adds a given product to the list of evidence to add when matched.
*
@@ -132,6 +136,27 @@ public class HintRule {
return addProduct;
}
+ /**
+ * Adds a given version to the list of evidence to add when matched.
+ *
+ * @param source the source of the evidence
+ * @param name the name of the evidence
+ * @param value the value of the evidence
+ * @param confidence the confidence of the evidence
+ */
+ public void addAddVersion(String source, String name, String value, Confidence confidence) {
+ addVersion.add(new Evidence(source, name, value, confidence));
+ }
+
+ /**
+ * Get the value of addVersion.
+ *
+ * @return the value of addVersion
+ */
+ public List getAddVersion() {
+ return addVersion;
+ }
+
/**
* The list of vendor hints to add.
*/
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/Hints.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/Hints.java
index 0240d2fc1..34e465004 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/Hints.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/hints/Hints.java
@@ -32,7 +32,7 @@ public class Hints {
private List hintRules;
/**
- * Get the value of hintRules
+ * Get the value of hintRules.
*
* @return the value of hintRules
*/
@@ -41,7 +41,7 @@ public class Hints {
}
/**
- * Set the value of hintRules
+ * Set the value of hintRules.
*
* @param hintRules new value of hintRules
*/
@@ -55,7 +55,7 @@ public class Hints {
private List vendorDuplicatingHintRules;
/**
- * Get the value of vendorDuplicatingHintRules
+ * Get the value of vendorDuplicatingHintRules.
*
* @return the value of vendorDuplicatingHintRules
*/
@@ -64,12 +64,11 @@ public class Hints {
}
/**
- * Set the value of vendorDuplicatingHintRules
+ * Set the value of vendorDuplicatingHintRules.
*
* @param vendorDuplicatingHintRules new value of vendorDuplicatingHintRules
*/
public void setVendorDuplicatingHintRules(List vendorDuplicatingHintRules) {
this.vendorDuplicatingHintRules = vendorDuplicatingHintRules;
}
-
}
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomUtils.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomUtils.java
index f3ea0b0e9..6f3aa4987 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomUtils.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/pom/PomUtils.java
@@ -48,13 +48,17 @@ public final class PomUtils {
*
* @param file the pom.xml file
* @return returns a
- * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM {@link Model} object
+ * @throws AnalysisException is thrown if there is an exception extracting
+ * or parsing the POM {@link Model} object
*/
public static Model readPom(File file) throws AnalysisException {
- Model model = null;
try {
final PomParser parser = new PomParser();
- model = parser.parse(file);
+ final Model model = parser.parse(file);
+ if (model == null) {
+ throw new AnalysisException(String.format("Unable to parse pom '%s'", file.getPath()));
+ }
+ return model;
} catch (PomParseException ex) {
LOGGER.warn("Unable to parse pom '{}'", file.getPath());
LOGGER.debug("", ex);
@@ -68,7 +72,6 @@ public final class PomUtils {
LOGGER.debug("", ex);
throw new AnalysisException(ex);
}
- return model;
}
/**
@@ -77,7 +80,8 @@ public final class PomUtils {
* @param path the path to the pom.xml file within the jar file
* @param jar the jar file to extract the pom from
* @return returns a
- * @throws AnalysisException is thrown if there is an exception extracting or parsing the POM {@link Model} object
+ * @throws AnalysisException is thrown if there is an exception extracting
+ * or parsing the POM {@link Model} object
*/
public static Model readPom(String path, JarFile jar) throws AnalysisException {
final ZipEntry entry = jar.getEntry(path);
@@ -86,7 +90,9 @@ public final class PomUtils {
try {
final PomParser parser = new PomParser();
model = parser.parse(jar.getInputStream(entry));
- LOGGER.debug("Read POM {}", path);
+ if (model == null) {
+ throw new AnalysisException(String.format("Unable to parse pom '%s/%s'", jar.getName(), path));
+ }
} catch (SecurityException ex) {
LOGGER.warn("Unable to parse pom '{}' in jar '{}'; invalid signature", path, jar.getName());
LOGGER.debug("", ex);
@@ -105,11 +111,13 @@ public final class PomUtils {
}
/**
- * Reads in the pom file and adds elements as evidence to the given dependency.
+ * Reads in the pom file and adds elements as evidence to the given
+ * dependency.
*
* @param dependency the dependency being analyzed
* @param pomFile the pom file to read
- * @throws AnalysisException is thrown if there is an exception parsing the pom
+ * @throws AnalysisException is thrown if there is an exception parsing the
+ * pom
*/
public static void analyzePOM(Dependency dependency, File pomFile) throws AnalysisException {
final Model pom = PomUtils.readPom(pomFile);
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/PropertyType.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/PropertyType.java
similarity index 98%
rename from dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/PropertyType.java
rename to dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/PropertyType.java
index 4ecd66323..772f338fb 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/PropertyType.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/PropertyType.java
@@ -15,7 +15,7 @@
*
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
*/
-package org.owasp.dependencycheck.suppression;
+package org.owasp.dependencycheck.xml.suppression;
import java.util.regex.Pattern;
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionErrorHandler.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionErrorHandler.java
similarity index 91%
rename from dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionErrorHandler.java
rename to dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionErrorHandler.java
index 5d8b8733a..07d4b661e 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionErrorHandler.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionErrorHandler.java
@@ -15,10 +15,8 @@
*
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
*/
-package org.owasp.dependencycheck.suppression;
+package org.owasp.dependencycheck.xml.suppression;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
@@ -33,7 +31,7 @@ public class SuppressionErrorHandler implements ErrorHandler {
/**
* The logger.
*/
- private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionErrorHandler.class);
+ //private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionErrorHandler.class);
/**
* Builds a prettier exception message.
@@ -70,7 +68,7 @@ public class SuppressionErrorHandler implements ErrorHandler {
*/
@Override
public void warning(SAXParseException ex) throws SAXException {
- LOGGER.debug("", ex);
+ //LOGGER.debug("", ex);
}
/**
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionHandler.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.java
similarity index 99%
rename from dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionHandler.java
rename to dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.java
index ddb414e6f..b07909653 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionHandler.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandler.java
@@ -15,7 +15,7 @@
*
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
*/
-package org.owasp.dependencycheck.suppression;
+package org.owasp.dependencycheck.xml.suppression;
import java.util.ArrayList;
import java.util.List;
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParseException.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionParseException.java
similarity index 97%
rename from dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParseException.java
rename to dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionParseException.java
index 6c8e938de..d0d5c87df 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParseException.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionParseException.java
@@ -15,7 +15,7 @@
*
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
*/
-package org.owasp.dependencycheck.suppression;
+package org.owasp.dependencycheck.xml.suppression;
import java.io.IOException;
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParser.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionParser.java
similarity index 89%
rename from dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParser.java
rename to dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionParser.java
index 945388a7a..d6e863f55 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionParser.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionParser.java
@@ -15,7 +15,7 @@
*
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
*/
-package org.owasp.dependencycheck.suppression;
+package org.owasp.dependencycheck.xml.suppression;
import java.io.File;
import java.io.FileInputStream;
@@ -121,8 +121,9 @@ public class SuppressionParser {
* @throws SAXException thrown if the XML cannot be parsed
*/
public List parseSuppressionRules(InputStream inputStream) throws SuppressionParseException, SAXException {
+ InputStream schemaStream = null;
try {
- final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(SUPPRESSION_SCHEMA);
+ schemaStream = this.getClass().getClassLoader().getResourceAsStream(SUPPRESSION_SCHEMA);
final SuppressionHandler handler = new SuppressionHandler();
final SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
@@ -157,6 +158,14 @@ public class SuppressionParser {
} catch (IOException ex) {
LOGGER.debug("", ex);
throw new SuppressionParseException(ex);
+ } finally {
+ if (schemaStream != null) {
+ try {
+ schemaStream.close();
+ } catch (IOException ex) {
+ LOGGER.debug("Error closing suppression file stream", ex);
+ }
+ }
}
}
@@ -169,8 +178,9 @@ public class SuppressionParser {
* @throws SuppressionParseException if the XML cannot be parsed
*/
private List parseOldSuppressionRules(InputStream inputStream) throws SuppressionParseException {
+ InputStream schemaStream = null;
try {
- final InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(OLD_SUPPRESSION_SCHEMA);
+ schemaStream = this.getClass().getClassLoader().getResourceAsStream(OLD_SUPPRESSION_SCHEMA);
final SuppressionHandler handler = new SuppressionHandler();
final SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
@@ -200,6 +210,14 @@ public class SuppressionParser {
} catch (IOException ex) {
LOGGER.debug("", ex);
throw new SuppressionParseException(ex);
+ } finally {
+ if (schemaStream != null) {
+ try {
+ schemaStream.close();
+ } catch (IOException ex) {
+ LOGGER.debug("Error closing old suppression file stream", ex);
+ }
+ }
}
}
}
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionRule.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRule.java
similarity index 99%
rename from dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionRule.java
rename to dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRule.java
index 1a2353fdf..80e78bdd2 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/SuppressionRule.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/SuppressionRule.java
@@ -15,7 +15,7 @@
*
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
*/
-package org.owasp.dependencycheck.suppression;
+package org.owasp.dependencycheck.xml.suppression;
import java.util.ArrayList;
import java.util.Iterator;
diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/package-info.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/package-info.java
similarity index 51%
rename from dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/package-info.java
rename to dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/package-info.java
index f8974043d..0abc2af40 100644
--- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/suppression/package-info.java
+++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/xml/suppression/package-info.java
@@ -1,4 +1,4 @@
/**
* Contains classes used to suppress findings.
*/
-package org.owasp.dependencycheck.suppression;
+package org.owasp.dependencycheck.xml.suppression;
diff --git a/dependency-check-core/src/main/resources/GrokAssembly.exe b/dependency-check-core/src/main/resources/GrokAssembly.exe
index 5b2104a54..a68ce50e1 100644
Binary files a/dependency-check-core/src/main/resources/GrokAssembly.exe and b/dependency-check-core/src/main/resources/GrokAssembly.exe differ
diff --git a/dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer b/dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer
index 7f67a3d84..674d1d0f7 100644
--- a/dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer
+++ b/dependency-check-core/src/main/resources/META-INF/services/org.owasp.dependencycheck.analyzer.Analyzer
@@ -22,3 +22,5 @@ org.owasp.dependencycheck.analyzer.RubyGemspecAnalyzer
org.owasp.dependencycheck.analyzer.RubyBundlerAnalyzer
org.owasp.dependencycheck.analyzer.RubyBundleAuditAnalyzer
org.owasp.dependencycheck.analyzer.ComposerLockAnalyzer
+org.owasp.dependencycheck.analyzer.CocoaPodsAnalyzer
+org.owasp.dependencycheck.analyzer.SwiftPackageManagerAnalyzer
diff --git a/dependency-check-core/src/main/resources/dependencycheck-base-hint.xml b/dependency-check-core/src/main/resources/dependencycheck-base-hint.xml
index 4e1d870a6..5d3dacdaa 100644
--- a/dependency-check-core/src/main/resources/dependencycheck-base-hint.xml
+++ b/dependency-check-core/src/main/resources/dependencycheck-base-hint.xml
@@ -1,75 +1,120 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml
index 97c9b0967..b06cc702d 100644
--- a/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml
+++ b/dependency-check-core/src/main/resources/dependencycheck-base-suppression.xml
@@ -410,7 +410,7 @@
- org.eclipse.aether:aether.*
+ org\.eclipse\.aether:aether.*
cpe:/a:eclipse:eclipse_ide
@@ -420,4 +420,11 @@
.*\.(jar|ear|war|pom)
cpe:/a:services_project:services
+
+
+ com\.offbytwo\.jenkins:jenkins-client:.*
+ cpe:/a:jenkins:jenkins
+
diff --git a/dependency-check-core/src/main/resources/dependencycheck.properties b/dependency-check-core/src/main/resources/dependencycheck.properties
index def5b8d86..fe567580e 100644
--- a/dependency-check-core/src/main/resources/dependencycheck.properties
+++ b/dependency-check-core/src/main/resources/dependencycheck.properties
@@ -96,6 +96,8 @@ analyzer.nuspec.enabled=true
analyzer.openssl.enabled=true
analyzer.central.enabled=true
analyzer.nexus.enabled=false
+analyzer.cocoapods.enabled=true
+analyzer.swift.package.manager.enabled=true
#whether the nexus analyzer uses the proxy
analyzer.nexus.proxy=true
diff --git a/dependency-check-core/src/main/resources/schema/dependency-hint.1.1.xsd b/dependency-check-core/src/main/resources/schema/dependency-hint.1.1.xsd
new file mode 100644
index 000000000..63390044a
--- /dev/null
+++ b/dependency-check-core/src/main/resources/schema/dependency-hint.1.1.xsd
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java
index 1e12e6a82..bceefc23b 100644
--- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java
+++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/EngineIntegrationTest.java
@@ -17,12 +17,19 @@
*/
package org.owasp.dependencycheck;
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
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.exception.ExceptionCollection;
+import org.owasp.dependencycheck.exception.ReportException;
import org.owasp.dependencycheck.reporting.ReportGenerator;
+import org.owasp.dependencycheck.utils.InvalidSettingException;
import org.owasp.dependencycheck.utils.Settings;
/**
@@ -34,10 +41,14 @@ public class EngineIntegrationTest extends BaseDBTestCase {
/**
* Test running the entire engine.
*
- * @throws Exception is thrown when an exception occurs.
+ * @throws java.io.IOException
+ * @throws org.owasp.dependencycheck.utils.InvalidSettingException
+ * @throws org.owasp.dependencycheck.data.nvdcve.DatabaseException
+ * @throws org.owasp.dependencycheck.exception.ReportException
+ * @throws org.owasp.dependencycheck.exception.ExceptionCollection
*/
@Test
- public void testEngine() throws Exception {
+ public void testEngine() throws IOException, InvalidSettingException, DatabaseException, ReportException, ExceptionCollection {
String testClasses = "target/test-classes";
boolean autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
@@ -45,7 +56,23 @@ public class EngineIntegrationTest extends BaseDBTestCase {
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, autoUpdate);
instance.scan(testClasses);
assertTrue(instance.getDependencies().size() > 0);
- instance.analyzeDependencies();
+ try {
+ instance.analyzeDependencies();
+ } catch (ExceptionCollection ex) {
+ if (ex.getExceptions().size()==1 &&
+ (ex.getExceptions().get(0).getMessage().contains("bundle-audit") ||
+ ex.getExceptions().get(0).getMessage().contains("AssemblyAnalyzer"))) {
+ //this is fine to ignore
+ } else if (ex.getExceptions().size()==2 &&
+ ((ex.getExceptions().get(0).getMessage().contains("bundle-audit") &&
+ ex.getExceptions().get(1).getMessage().contains("AssemblyAnalyzer")) ||
+ (ex.getExceptions().get(1).getMessage().contains("bundle-audit") &&
+ ex.getExceptions().get(0).getMessage().contains("AssemblyAnalyzer")))) {
+ //this is fine to ignore
+ } else {
+ throw ex;
+ }
+ }
CveDB cveDB = new CveDB();
cveDB.open();
DatabaseProperties dbProp = cveDB.getDatabaseProperties();
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 27527b2c2..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,8 +23,7 @@ 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.suppression.SuppressionParseException;
-import org.owasp.dependencycheck.suppression.SuppressionRule;
+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..d00d83285 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
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Assume;
import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeNotNull;
import org.junit.Before;
import org.junit.Test;
import org.owasp.dependencycheck.BaseTest;
@@ -31,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.Evidence;
+import org.owasp.dependencycheck.exception.InitializationException;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,6 +62,7 @@ public class AssemblyAnalyzerTest extends BaseTest {
analyzer = new AssemblyAnalyzer();
analyzer.accept(new File("test.dll")); // trick into "thinking it is active"
analyzer.initialize();
+ Assume.assumeTrue("Mono is not installed, skipping tests.", analyzer.buildArgumentList() == null);
} catch (Exception e) {
if (e.getMessage().contains("Could not execute .NET AssemblyAnalyzer")) {
LOGGER.warn("Exception setting up AssemblyAnalyzer. Tests will be incomplete");
@@ -80,7 +83,7 @@ public class AssemblyAnalyzerTest extends BaseTest {
@Test
public void testAnalysis() throws Exception {
- //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("GrokAssembly.exe").getPath());
+ assumeNotNull(analyzer.buildArgumentList());
File f = BaseTest.getResourceAsFile(this, "GrokAssembly.exe");
Dependency d = new Dependency(f);
analyzer.analyze(d, null);
@@ -103,7 +106,7 @@ public class AssemblyAnalyzerTest extends BaseTest {
@Test
public void testLog4Net() throws Exception {
- //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath());
+ assumeNotNull(analyzer.buildArgumentList());
File f = BaseTest.getResourceAsFile(this, "log4net.dll");
Dependency d = new Dependency(f);
@@ -115,9 +118,10 @@ public class AssemblyAnalyzerTest extends BaseTest {
@Test
public void testNonexistent() {
+ assumeNotNull(analyzer.buildArgumentList());
+
// Tweak the log level so the warning doesn't show in the console
String oldProp = System.getProperty(LOG_KEY, "info");
- //File f = new File(AssemblyAnalyzerTest.class.getClassLoader().getResource("log4net.dll").getPath());
File f = BaseTest.getResourceAsFile(this, "log4net.dll");
File test = new File(f.getParent(), "nonexistent.dll");
Dependency d = new Dependency(test);
@@ -157,8 +161,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);
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.java
index 552ec2abc..0eef5db5e 100644
--- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.java
+++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/CPEAnalyzerIntegrationTest.java
@@ -189,6 +189,7 @@ public class CPEAnalyzerIntegrationTest extends BaseDBTestCase {
instance.determineCPE(spring);
instance.determineCPE(spring3);
instance.close();
+
String expResult = "cpe:/a:apache:struts:2.1.2";
Identifier expIdentifier = new Identifier("cpe", expResult, expResult);
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java
index d1f9101c3..c1b57ab66 100644
--- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java
+++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/RubyBundleAuditAnalyzerTest.java
@@ -26,6 +26,7 @@ import java.io.File;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.logging.Level;
import org.junit.After;
import org.junit.Assume;
@@ -40,6 +41,7 @@ import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Evidence;
import org.owasp.dependencycheck.dependency.Identifier;
import org.owasp.dependencycheck.dependency.Vulnerability;
+import org.owasp.dependencycheck.exception.ExceptionCollection;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -115,7 +117,6 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
final Engine engine = new Engine();
analyzer.analyze(result, engine);
int size = engine.getDependencies().size();
-
assertTrue(size >= 1);
Dependency dependency = engine.getDependencies().get(0);
@@ -176,6 +177,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
* Test Ruby dependencies and their paths.
*
* @throws AnalysisException is thrown when an exception occurs.
+ * @throws DatabaseException thrown when an exception occurs
*/
@Test
public void testDependenciesPath() throws AnalysisException, DatabaseException {
@@ -187,6 +189,8 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
} catch (NullPointerException ex) {
LOGGER.error("NPE", ex);
throw ex;
+ } catch (ExceptionCollection ex) {
+ Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", ex);
}
List dependencies = engine.getDependencies();
LOGGER.info(dependencies.size() + " dependencies found.");
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/SwiftAnalyzersTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/SwiftAnalyzersTest.java
new file mode 100644
index 000000000..94e4b020d
--- /dev/null
+++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/analyzer/SwiftAnalyzersTest.java
@@ -0,0 +1,123 @@
+package org.owasp.dependencycheck.analyzer;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.owasp.dependencycheck.BaseTest;
+import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
+import org.owasp.dependencycheck.dependency.Dependency;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+import java.io.File;
+
+/**
+ * Unit tests for CocoaPodsAnalyzer.
+ *
+ * @author Bianca Jiang
+ */
+public class SwiftAnalyzersTest extends BaseTest {
+
+ /**
+ * The analyzer to test.
+ */
+ CocoaPodsAnalyzer podsAnalyzer;
+ SwiftPackageManagerAnalyzer spmAnalyzer;
+
+ /**
+ * Correctly setup the analyzer for testing.
+ *
+ * @throws Exception thrown if there is a problem
+ */
+ @Before
+ public void setUp() throws Exception {
+ podsAnalyzer = new CocoaPodsAnalyzer();
+ podsAnalyzer.setFilesMatched(true);
+ podsAnalyzer.initialize();
+
+ spmAnalyzer = new SwiftPackageManagerAnalyzer();
+ spmAnalyzer.setFilesMatched(true);
+ spmAnalyzer.initialize();
+ }
+
+ /**
+ * Cleanup the analyzer's temp files, etc.
+ *
+ * @throws Exception thrown if there is a problem
+ */
+ @After
+ public void tearDown() throws Exception {
+ podsAnalyzer.close();
+ podsAnalyzer = null;
+
+ spmAnalyzer.close();
+ spmAnalyzer = null;
+ }
+
+ /**
+ * Test of getName method, of class CocoaPodsAnalyzer.
+ */
+ @Test
+ public void testPodsGetName() {
+ assertThat(podsAnalyzer.getName(), is("CocoaPods Package Analyzer"));
+ }
+
+ /**
+ * Test of getName method, of class SwiftPackageManagerAnalyzer.
+ */
+ @Test
+ public void testSPMGetName() {
+ assertThat(spmAnalyzer.getName(), is("SWIFT Package Manager Analyzer"));
+ }
+
+ /**
+ * Test of supportsFiles method, of class CocoaPodsAnalyzer.
+ */
+ @Test
+ public void testPodsSupportsFiles() {
+ assertThat(podsAnalyzer.accept(new File("test.podspec")), is(true));
+ }
+
+ /**
+ * Test of supportsFiles method, of class SwiftPackageManagerAnalyzer.
+ */
+ @Test
+ public void testSPMSupportsFiles() {
+ assertThat(spmAnalyzer.accept(new File("Package.swift")), is(true));
+ }
+
+ /**
+ * Test of analyze method, of class CocoaPodsAnalyzer.
+ *
+ * @throws AnalysisException is thrown when an exception occurs.
+ */
+ @Test
+ public void testCocoaPodsAnalyzer() throws AnalysisException {
+ final Dependency result = new Dependency(BaseTest.getResourceAsFile(this,
+ "swift/cocoapods/EasyPeasy.podspec"));
+ podsAnalyzer.analyze(result, null);
+ final String vendorString = result.getVendorEvidence().toString();
+
+ assertThat(vendorString, containsString("Carlos Vidal"));
+ assertThat(vendorString, containsString("https://github.com/nakiostudio/EasyPeasy"));
+ assertThat(vendorString, containsString("MIT"));
+ assertThat(result.getProductEvidence().toString(), containsString("EasyPeasy"));
+ assertThat(result.getVersionEvidence().toString(), containsString("0.2.3"));
+ }
+
+ /**
+ * Test of analyze method, of class SwiftPackageManagerAnalyzer.
+ *
+ * @throws AnalysisException is thrown when an exception occurs.
+ */
+ @Test
+ public void testSPMAnalyzer() throws AnalysisException {
+ final Dependency result = new Dependency(BaseTest.getResourceAsFile(this,
+ "swift/Gloss/Package.swift"));
+ spmAnalyzer.analyze(result, null);
+
+ assertThat(result.getProductEvidence().toString(), containsString("Gloss"));
+ }
+}
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.java
index 8f43f1a09..d666c9772 100644
--- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.java
+++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/NvdCveUpdaterIntegrationTest.java
@@ -40,12 +40,11 @@ public class NvdCveUpdaterIntegrationTest extends BaseTest {
// /**
// * Test of update method, of class StandardUpdate.
// */
-// @Test
-// public void testUpdate() throws Exception {
-// StandardUpdate instance = getStandardUpdateTask();
-// instance.update();
-// //TODO make this an actual test
-// }
+ @Test
+ public void testUpdate() throws Exception {
+ NvdCveUpdater instance = getUpdater();
+ instance.update();
+ }
/**
* Test of updatesNeeded method, of class StandardUpdate.
*/
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCveUpdaterIntegrationTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCveUpdaterIntegrationTest.java
deleted file mode 100644
index d93fbce6b..000000000
--- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/data/update/nvd/NvdCveUpdaterIntegrationTest.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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) 2013 Jeremy Long. All Rights Reserved.
- */
-package org.owasp.dependencycheck.data.update.nvd;
-
-import java.io.File;
-import java.util.Calendar;
-import org.junit.Before;
-import org.junit.Test;
-import org.owasp.dependencycheck.BaseTest;
-import org.owasp.dependencycheck.data.update.NvdCveUpdater;
-import org.owasp.dependencycheck.utils.Settings;
-
-/**
- *
- * @author Jeremy Long
- */
-public class NvdCveUpdaterIntegrationTest extends BaseTest {
-
- @Before
- public void setUp() throws Exception {
- int year = Calendar.getInstance().get(Calendar.YEAR);
- if (year <= 2014) {
- //File f = new File(NvdCveUpdaterIntegrationTest.class.getClassLoader().getResource("nvdcve-2.0-2014.xml").getPath());
- File f = BaseTest.getResourceAsFile(this, "nvdcve-2.0-2014.xml");
- String baseURL = f.toURI().toURL().toString();
- String modified12 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-modified.xml");
- String modified20 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-2.0-modified.xml");
- String full12 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-%d.xml");
- String full20 = baseURL.replace("nvdcve-2.0-2014.xml", "nvdcve-2.0-%d.xml");
-// cve.url-1.2.modified=http://nvd.nist.gov/download/nvdcve-modified.xml
-// cve.url-2.0.modified=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
-// cve.startyear=2014
-// cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
-// cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
-
- Settings.setString(Settings.KEYS.CVE_MODIFIED_12_URL, modified12);
- Settings.setString(Settings.KEYS.CVE_MODIFIED_20_URL, modified20);
- Settings.setString(Settings.KEYS.CVE_SCHEMA_1_2, full12);
- Settings.setString(Settings.KEYS.CVE_SCHEMA_2_0, full20);
- Settings.setString(Settings.KEYS.CVE_START_YEAR, "2014");
- } else {
- System.err.println("Consider updating the local data files to make the NvdCveUpdaterIntegrationTest perform faster");
- }
- }
-
- /**
- * Test of update method, of class NvdCveUpdater.
- */
- @Test
- public void testUpdate() throws Exception {
- NvdCveUpdater instance = new NvdCveUpdater();
- instance.update();
- }
-}
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintHandlerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintHandlerTest.java
index dd71ebf4b..2d06c3a69 100644
--- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintHandlerTest.java
+++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/hints/HintHandlerTest.java
@@ -32,10 +32,10 @@ import javax.xml.parsers.SAXParserFactory;
import org.junit.Test;
import static org.junit.Assert.*;
import org.owasp.dependencycheck.BaseTest;
-import org.owasp.dependencycheck.suppression.SuppressionErrorHandler;
-import org.owasp.dependencycheck.suppression.SuppressionHandler;
-import org.owasp.dependencycheck.suppression.SuppressionParser;
-import org.owasp.dependencycheck.suppression.SuppressionRule;
+import org.owasp.dependencycheck.xml.suppression.SuppressionErrorHandler;
+import org.owasp.dependencycheck.xml.suppression.SuppressionHandler;
+import org.owasp.dependencycheck.xml.suppression.SuppressionParser;
+import org.owasp.dependencycheck.xml.suppression.SuppressionRule;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
@@ -52,7 +52,7 @@ public class HintHandlerTest extends BaseTest {
@Test
public void testHandler() throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException, SAXException, FileNotFoundException, UnsupportedEncodingException, IOException {
File file = BaseTest.getResourceAsFile(this, "hints.xml");
- File schema = BaseTest.getResourceAsFile(this, "schema/dependency-hint.1.0.xsd");
+ File schema = BaseTest.getResourceAsFile(this, "schema/dependency-hint.1.1.xsd");
HintHandler handler = new HintHandler();
SAXParserFactory factory = SAXParserFactory.newInstance();
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/PropertyTypeTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/PropertyTypeTest.java
similarity index 98%
rename from dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/PropertyTypeTest.java
rename to dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/PropertyTypeTest.java
index 2502ee4fd..9ad49e0f1 100644
--- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/PropertyTypeTest.java
+++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/PropertyTypeTest.java
@@ -15,7 +15,7 @@
*
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
*/
-package org.owasp.dependencycheck.suppression;
+package org.owasp.dependencycheck.xml.suppression;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.java
similarity index 98%
rename from dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.java
rename to dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.java
index 45fd9240b..9517a1a7f 100644
--- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionHandlerTest.java
+++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionHandlerTest.java
@@ -15,7 +15,7 @@
*
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
*/
-package org.owasp.dependencycheck.suppression;
+package org.owasp.dependencycheck.xml.suppression;
import java.io.File;
import java.io.FileInputStream;
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionParserTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.java
similarity index 96%
rename from dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionParserTest.java
rename to dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.java
index d911c9cb2..d09ac9ee9 100644
--- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionParserTest.java
+++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionParserTest.java
@@ -15,7 +15,7 @@
*
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
*/
-package org.owasp.dependencycheck.suppression;
+package org.owasp.dependencycheck.xml.suppression;
import java.io.File;
import java.util.List;
diff --git a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionRuleTest.java b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionRuleTest.java
similarity index 99%
rename from dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionRuleTest.java
rename to dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionRuleTest.java
index 0a73d13a1..56982887a 100644
--- a/dependency-check-core/src/test/java/org/owasp/dependencycheck/suppression/SuppressionRuleTest.java
+++ b/dependency-check-core/src/test/java/org/owasp/dependencycheck/xml/suppression/SuppressionRuleTest.java
@@ -15,7 +15,7 @@
*
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
*/
-package org.owasp.dependencycheck.suppression;
+package org.owasp.dependencycheck.xml.suppression;
import java.io.File;
import java.util.ArrayList;
diff --git a/dependency-check-core/src/test/resources/hints.xml b/dependency-check-core/src/test/resources/hints.xml
index 000028414..bf739a083 100644
--- a/dependency-check-core/src/test/resources/hints.xml
+++ b/dependency-check-core/src/test/resources/hints.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/dependency-check-core/src/test/resources/swift/Gloss/Gloss.podspec b/dependency-check-core/src/test/resources/swift/Gloss/Gloss.podspec
new file mode 100644
index 000000000..3d05500ca
--- /dev/null
+++ b/dependency-check-core/src/test/resources/swift/Gloss/Gloss.podspec
@@ -0,0 +1,17 @@
+Pod::Spec.new do |s|
+ s.name = "Gloss"
+ s.version = "0.7.2"
+ s.summary = "A shiny JSON parsing library in Swift"
+ s.description = "A shiny JSON parsing library in Swift. Features include mapping JSON to objects, mapping objects to JSON, handling of nested objects and custom transformations."
+ s.homepage = "https://github.com/hkellaway/Gloss"
+ s.license = { :type => "MIT", :file => "LICENSE" }
+ s.author = { "Harlan Kellaway" => "hello@harlankellaway.com" }
+ s.social_media_url = "http://twitter.com/HarlanKellaway"
+ s.source = { :git => "https://github.com/hkellaway/Gloss.git", :tag => s.version.to_s }
+
+ s.platforms = { :ios => "8.0", :osx => "10.9", :tvos => "9.0", :watchos => "2.0" }
+ s.requires_arc = true
+
+ s.source_files = 'Sources/*.{swift}'
+
+end
diff --git a/dependency-check-core/src/test/resources/swift/Gloss/Package.swift b/dependency-check-core/src/test/resources/swift/Gloss/Package.swift
new file mode 100644
index 000000000..ac1039468
--- /dev/null
+++ b/dependency-check-core/src/test/resources/swift/Gloss/Package.swift
@@ -0,0 +1,30 @@
+//
+// Package.swift
+// Gloss
+//
+// Copyright (c) 2015 Harlan Kellaway
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+import PackageDescription
+
+let package = Package(
+ name: "Gloss"
+)
diff --git a/dependency-check-core/src/test/resources/swift/cocoapods/EasyPeasy.podspec b/dependency-check-core/src/test/resources/swift/cocoapods/EasyPeasy.podspec
new file mode 100644
index 000000000..52d0ef7a8
--- /dev/null
+++ b/dependency-check-core/src/test/resources/swift/cocoapods/EasyPeasy.podspec
@@ -0,0 +1,25 @@
+Pod::Spec.new do |s|
+ s.name = "EasyPeasy"
+ s.version = "0.2.3"
+ s.summary = "EasyPeasy is a Swift framework that eases the creation of
+ Autolayout constraints programmatically"
+ s.description = <<-DESC
+ EasyPeasy is a Swift framework that lets you create Autolayout constraints
+ programmatically without headaches and never ending boilerplate code. Besides the
+ basics, **EasyPeasy** resolves most of the constraint conflicts for you and lets
+ you attach to a constraint conditional closures that are evaluated before applying
+ a constraint, this lets you apply (or not) a constraint depending on platform, size
+ classes, orientation... or the state of your controller, easy peasy!
+ DESC
+ s.homepage = "https://github.com/nakiostudio/EasyPeasy"
+ s.license = 'MIT'
+ s.author = { "Carlos Vidal" => "nakioparkour@gmail.com" }
+ s.source = { :git => "https://github.com/nakiostudio/EasyPeasy.git", :tag => s.version.to_s }
+ s.social_media_url = 'https://twitter.com/carlostify'
+
+ s.platform = :ios, '8.0'
+ s.requires_arc = true
+
+ s.source_files = 'EasyPeasy/**/*'
+ s.frameworks = 'UIKit'
+end
diff --git a/dependency-check-maven/pom.xml b/dependency-check-maven/pom.xml
index aa33ce2f8..c1fe6aa74 100644
--- a/dependency-check-maven/pom.xml
+++ b/dependency-check-maven/pom.xml
@@ -20,7 +20,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
org.owasp
dependency-check-parent
- 1.4.1-SNAPSHOT
+ 1.4.4-SNAPSHOT
dependency-check-maven
@@ -208,6 +208,10 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
org.sonatype.plexus
plexus-sec-dispatcher
+
+ org.apache.maven.shared
+ maven-dependency-tree
+
org.jmockit
jmockit
diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java
index f801f000d..75ae844bb 100644
--- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java
+++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/AggregateMojo.java
@@ -19,10 +19,8 @@ package org.owasp.dependencycheck.maven;
import java.io.File;
import java.io.IOException;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
-import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.apache.maven.plugin.MojoExecutionException;
@@ -32,22 +30,21 @@ import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
-import org.owasp.dependencycheck.analyzer.DependencyBundlingAnalyzer;
-import org.owasp.dependencycheck.analyzer.exception.AnalysisException;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
-import org.owasp.dependencycheck.dependency.Dependency;
+import org.owasp.dependencycheck.exception.ExceptionCollection;
+import org.owasp.dependencycheck.exception.ReportException;
import org.owasp.dependencycheck.utils.Settings;
/**
- * Maven Plugin that checks project dependencies and the dependencies of all child modules to see if they have any known published
- * vulnerabilities.
+ * Maven Plugin that checks project dependencies and the dependencies of all
+ * child modules to see if they have any known published vulnerabilities.
*
* @author Jeremy Long
*/
@Mojo(
name = "aggregate",
defaultPhase = LifecyclePhase.VERIFY,
- /*aggregator = true,*/
+ aggregator = true,
threadSafe = false,
requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME,
requiresOnline = true
@@ -55,104 +52,91 @@ import org.owasp.dependencycheck.utils.Settings;
public class AggregateMojo extends BaseDependencyCheckMojo {
/**
- * Executes the aggregate dependency-check goal. This runs dependency-check and generates the subsequent reports.
+ * Executes the aggregate dependency-check goal. This runs dependency-check
+ * and generates the subsequent reports.
*
- * @throws MojoExecutionException thrown if there is ane exception running the mojo
- * @throws MojoFailureException thrown if dependency-check is configured to fail the build
+ * @throws MojoExecutionException thrown if there is ane exception running
+ * the mojo
+ * @throws MojoFailureException thrown if dependency-check is configured to
+ * fail the build
*/
@Override
public void runCheck() throws MojoExecutionException, MojoFailureException {
- final Engine engine = generateDataFile();
+ final MavenEngine engine = loadEngine();
+ if (engine == null) {
+ return;
+ }
- //if (getProject() == getReactorProjects().get(getReactorProjects().size() - 1)) {
- if (getProject() == getLastProject()) {
+ ExceptionCollection exCol = scanArtifacts(getProject(), engine);
- //ensure that the .ser file was created for each.
- for (MavenProject current : getReactorProjects()) {
- final File dataFile = getDataFile(current);
- if (dataFile == null && !skipProject(current)) { //dc was never run on this project. write the ser to the target.
- getLog().error(String.format("Module '%s' did not execute dependency-check; an attempt will be made to perform "
- + "the check but dependencies may be missed resulting in false negatives.", current.getName()));
- generateDataFile(engine, current);
+ for (MavenProject childProject : getDescendants(this.getProject())) {
+ final ExceptionCollection ex = scanArtifacts(childProject, engine);
+ if (ex != null) {
+ if (exCol == null) {
+ exCol = ex;
}
- }
-
- for (MavenProject current : getReactorProjects()) {
- List dependencies = readDataFile(current);
- if (dependencies == null) {
- dependencies = new ArrayList();
+ exCol.getExceptions().addAll(ex.getExceptions());
+ if (ex.isFatal()) {
+ exCol.setFatal(true);
}
- final Set childProjects = getDescendants(current);
- for (MavenProject reportOn : childProjects) {
- final List childDeps = readDataFile(reportOn);
- if (childDeps != null && !childDeps.isEmpty()) {
- if (getLog().isDebugEnabled()) {
- getLog().debug(String.format("Adding %d dependencies from %s", childDeps.size(), reportOn.getName()));
- }
- dependencies.addAll(childDeps);
- } else {
- if (getLog().isDebugEnabled()) {
- getLog().debug(String.format("No dependencies read for %s", reportOn.getName()));
- }
- }
- }
- engine.getDependencies().clear();
- engine.getDependencies().addAll(dependencies);
- final DependencyBundlingAnalyzer bundler = new DependencyBundlingAnalyzer();
- try {
- if (getLog().isDebugEnabled()) {
- getLog().debug(String.format("Dependency count pre-bundler: %s", engine.getDependencies().size()));
- }
- bundler.analyze(null, engine);
- if (getLog().isDebugEnabled()) {
- getLog().debug(String.format("Dependency count post-bundler: %s", engine.getDependencies().size()));
- }
- } catch (AnalysisException ex) {
- getLog().warn("An error occurred grouping the dependencies; duplicate entries may exist in the report", ex);
- getLog().debug("Bundling Exception", ex);
- }
-
- File outputDir = getCorrectOutputDirectory(current);
- if (outputDir == null) {
- //in some regards we shouldn't be writting this, but we are anyway.
- //we shouldn't write this because nothing is configured to generate this report.
- outputDir = new File(current.getBuild().getDirectory());
- }
- writeReports(engine, current, outputDir);
}
}
+
+ try {
+ engine.analyzeDependencies();
+ } catch (ExceptionCollection ex) {
+ if (exCol == null) {
+ exCol = ex;
+ } else if (ex.isFatal()) {
+ exCol.setFatal(true);
+ exCol.getExceptions().addAll(ex.getExceptions());
+ }
+ if (exCol.isFatal()) {
+ final String msg = String.format("Fatal exception(s) analyzing %s", getProject().getName());
+ if (this.isFailOnError()) {
+ throw new MojoExecutionException(msg, exCol);
+ }
+ getLog().error(msg);
+ if (getLog().isDebugEnabled()) {
+ getLog().debug(exCol);
+ }
+ return;
+ } else {
+ final String msg = String.format("Exception(s) analyzing %s", getProject().getName());
+ if (getLog().isDebugEnabled()) {
+ getLog().debug(msg, exCol);
+ }
+ }
+ }
+ File outputDir = getCorrectOutputDirectory(this.getProject());
+ if (outputDir == null) {
+ //in some regards we shouldn't be writting this, but we are anyway.
+ //we shouldn't write this because nothing is configured to generate this report.
+ outputDir = new File(this.getProject().getBuild().getDirectory());
+ }
+ try {
+ writeReports(engine, this.getProject(), outputDir);
+ } catch (ReportException ex) {
+ if (exCol == null) {
+ exCol = new ExceptionCollection("Error writing aggregate report", ex);
+ } else {
+ exCol.addException(ex);
+ }
+ if (this.isFailOnError()) {
+ throw new MojoExecutionException("One or more exceptions occured during dependency-check analysis", exCol);
+ } else {
+ getLog().debug("One or more exceptions occured during dependency-check analysis", exCol);
+ }
+ }
+ showSummary(this.getProject(), engine.getDependencies());
+ checkForFailure(engine.getDependencies());
engine.cleanup();
Settings.cleanup();
}
/**
- * Gets the last project in the reactor - taking into account skipped projects.
- *
- * @return the last project in the reactor
- */
- private MavenProject getLastProject() {
- for (int x = getReactorProjects().size() - 1; x >= 0; x--) {
- final MavenProject p = getReactorProjects().get(x);
- if (!skipProject(p)) {
- return p;
- }
- }
- return null;
- }
-
- /**
- * Tests if the project is being skipped in the Maven site report.
- *
- * @param project a project in the reactor
- * @return true if the project is skipped; otherwise false
- */
- private boolean skipProject(MavenProject project) {
- final String skip = (String) project.getProperties().get("maven.site.skip");
- return "true".equalsIgnoreCase(skip) && isGeneratingSite();
- }
-
- /**
- * Returns a set containing all the descendant projects of the given project.
+ * Returns a set containing all the descendant projects of the given
+ * project.
*
* @param project the project for which all descendants will be returned
* @return the set of descendant projects
@@ -232,53 +216,36 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
* Test if the project has pom packaging
*
* @param mavenProject Project to test
- * @return true if it has a pom packaging; otherwise false
+ * @return true if it has a pom packaging; otherwise
+ * false
*/
protected boolean isMultiModule(MavenProject mavenProject) {
return "pom".equals(mavenProject.getPackaging());
}
/**
- * Initializes the engine, runs a scan, and writes the serialized dependencies to disk.
+ * Initializes the engine.
*
- * @return the Engine used to execute dependency-check
- * @throws MojoExecutionException thrown if there is an exception running the mojo
- * @throws MojoFailureException thrown if dependency-check is configured to fail the build if severe CVEs are identified.
+ * @return the MavenEngine used to execute dependency-check
+ * @throws MojoExecutionException thrown if there is an exception running
+ * the Mojo
+ * @throws MojoFailureException thrown if dependency-check is configured to
+ * fail the build if severe CVEs are identified.
*/
- protected Engine generateDataFile() throws MojoExecutionException, MojoFailureException {
- final Engine engine;
+ protected MavenEngine loadEngine() throws MojoExecutionException, MojoFailureException {
+ MavenEngine engine = null;
try {
engine = initializeEngine();
} catch (DatabaseException ex) {
if (getLog().isDebugEnabled()) {
getLog().debug("Database connection error", ex);
}
- throw new MojoExecutionException("An exception occured connecting to the local database. Please see the log file for more details.", ex);
+ final String msg = "An exception occured connecting to the local database. Please see the log file for more details.";
+ if (this.isFailOnError()) {
+ throw new MojoExecutionException(msg, ex);
+ }
+ getLog().error(msg, ex);
}
- return generateDataFile(engine, getProject());
- }
-
- /**
- * Runs dependency-check's Engine and writes the serialized dependencies to disk.
- *
- * @param engine the Engine to use when scanning.
- * @param project the project to scan and generate the data file for
- * @return the Engine used to execute dependency-check
- * @throws MojoExecutionException thrown if there is an exception running the mojo
- * @throws MojoFailureException thrown if dependency-check is configured to fail the build if severe CVEs are identified.
- */
- protected Engine generateDataFile(Engine engine, MavenProject project) throws MojoExecutionException, MojoFailureException {
- if (getLog().isDebugEnabled()) {
- getLog().debug(String.format("Begin Scanning: %s", project.getName()));
- }
- engine.getDependencies().clear();
- engine.resetFileTypeAnalyzers();
- scanArtifacts(project, engine);
- engine.analyzeDependencies();
- final File target = new File(project.getBuild().getDirectory());
- writeDataFile(project, target, engine.getDependencies());
- showSummary(project, engine.getDependencies());
- checkForFailure(engine.getDependencies());
return engine;
}
@@ -306,7 +273,8 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
}
/**
- * Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page.
+ * Gets the description of the Dependency-Check report to be displayed in
+ * the Maven Generated Reports page.
*
* @param locale The Locale to get the description for
* @return the description
diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java
index aff052420..e492589b9 100644
--- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java
+++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java
@@ -27,7 +27,7 @@ import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import java.util.Locale;
-import org.apache.maven.artifact.Artifact;
+import org.eclipse.aether.artifact.Artifact;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
@@ -39,6 +39,16 @@ import org.apache.maven.reporting.MavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Server;
+import org.apache.maven.shared.dependency.graph.DependencyGraphBuilder;
+import org.apache.maven.shared.dependency.graph.DependencyGraphBuilderException;
+import org.apache.maven.shared.dependency.graph.DependencyNode;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.ArtifactRequest;
+import org.eclipse.aether.resolution.ArtifactResolutionException;
+import org.eclipse.aether.resolution.ArtifactResult;
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
@@ -47,6 +57,8 @@ import org.owasp.dependencycheck.dependency.Confidence;
import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Identifier;
import org.owasp.dependencycheck.dependency.Vulnerability;
+import org.owasp.dependencycheck.exception.ExceptionCollection;
+import org.owasp.dependencycheck.exception.ReportException;
import org.owasp.dependencycheck.reporting.ReportGenerator;
import org.owasp.dependencycheck.utils.ExpectedOjectInputStream;
import org.owasp.dependencycheck.utils.Settings;
@@ -69,14 +81,28 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
* System specific new line character.
*/
private static final String NEW_LINE = System.getProperty("line.separator", "\n").intern();
+ // Engine that can be used for scanning.
+ * Initializes a new MavenEngine that can be used for scanning.
*
- * @return a newly instantiated Engine
+ * @return a newly instantiated MavenEngine
* @throws DatabaseException thrown if there is a database exception
*/
- protected Engine initializeEngine() throws DatabaseException {
+ protected MavenEngine initializeEngine() throws DatabaseException {
populateSettings();
- return new Engine(this.project,
- this.reactorProjects);
+ return new MavenEngine(this.project, this.reactorProjects);
}
/**
@@ -822,18 +958,18 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
* Tests is the artifact should be included in the scan (i.e. is the
* dependency in a scope that is being scanned).
*
- * @param a the Artifact to test
+ * @param scope the scope of the artifact to test
* @return true if the artifact is in an excluded scope;
* otherwise false
*/
- protected boolean excludeFromScan(Artifact a) {
- if (skipTestScope && Artifact.SCOPE_TEST.equals(a.getScope())) {
+ protected boolean excludeFromScan(String scope) {
+ if (skipTestScope && org.apache.maven.artifact.Artifact.SCOPE_TEST.equals(scope)) {
return true;
}
- if (skipProvidedScope && Artifact.SCOPE_PROVIDED.equals(a.getScope())) {
+ if (skipProvidedScope && org.apache.maven.artifact.Artifact.SCOPE_PROVIDED.equals(scope)) {
return true;
}
- if (skipRuntimeScope && !Artifact.SCOPE_RUNTIME.equals(a.getScope())) {
+ if (skipRuntimeScope && !org.apache.maven.artifact.Artifact.SCOPE_RUNTIME.equals(scope)) {
return true;
}
return false;
@@ -875,10 +1011,11 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
* Generates the reports for a given dependency-check engine.
*
* @param engine a dependency-check engine
- * @param p the maven project
- * @param outputDir the directory path to write the report(s).
+ * @param p the Maven project
+ * @param outputDir the directory path to write the report(s)
+ * @throws ReportException thrown if there is an error writing the report
*/
- protected void writeReports(Engine engine, MavenProject p, File outputDir) {
+ protected void writeReports(MavenEngine engine, MavenProject p, File outputDir) throws ReportException {
DatabaseProperties prop = null;
CveDB cve = null;
try {
@@ -897,19 +1034,11 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
final ReportGenerator r = new ReportGenerator(p.getName(), engine.getDependencies(), engine.getAnalyzers(), prop);
try {
r.generateReports(outputDir.getAbsolutePath(), format);
- } catch (IOException ex) {
- getLog().error(
- "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
- if (getLog().isDebugEnabled()) {
- getLog().debug("", ex);
- }
- } catch (Throwable ex) {
- getLog().error(
- "Unexpected exception occurred during analysis; please see the verbose error log for more details.");
- if (getLog().isDebugEnabled()) {
- getLog().debug("", ex);
- }
+ } catch (ReportException ex) {
+ final String msg = String.format("Error generating the report for %s", p.getName());
+ throw new ReportException(msg, ex);
}
+
}
//Engine object populated with dependencies if the
- * serialized data file exists; otherwise null is returned
+ * @return a MavenEngine object populated with dependencies if
+ * the serialized data file exists; otherwise null is returned
*/
protected Listtrue if the report can be generated; otherwise false
+ * @return true if the report can be generated; otherwise
+ * false
*/
@Override
public boolean canGenerateReport() {
boolean isCapable = false;
for (Artifact a : getProject().getArtifacts()) {
- if (!excludeFromScan(a)) {
+ if (!excludeFromScan(a.getScope())) {
isCapable = true;
break;
}
@@ -60,33 +64,64 @@ public class CheckMojo extends BaseDependencyCheckMojo {
}
/**
- * Executes the dependency-check engine on the project's dependencies and generates the report.
+ * Executes the dependency-check engine on the project's dependencies and
+ * generates the report.
*
- * @throws MojoExecutionException thrown if there is an exception executing the goal
- * @throws MojoFailureException thrown if dependency-check is configured to fail the build
+ * @throws MojoExecutionException thrown if there is an exception executing
+ * the goal
+ * @throws MojoFailureException thrown if dependency-check is configured to
+ * fail the build
*/
@Override
public void runCheck() throws MojoExecutionException, MojoFailureException {
- final Engine engine;
+ MavenEngine engine = null;
try {
engine = initializeEngine();
} catch (DatabaseException ex) {
if (getLog().isDebugEnabled()) {
getLog().debug("Database connection error", ex);
}
- throw new MojoExecutionException("An exception occured connecting to the local database. Please see the log file for more details.", ex);
+ final String msg = "An exception occured connecting to the local database. Please see the log file for more details.";
+ if (this.isFailOnError()) {
+ throw new MojoExecutionException(msg, ex);
+ }
+ getLog().error(msg);
}
- scanArtifacts(getProject(), engine);
- if (engine.getDependencies().isEmpty()) {
- getLog().info("No dependencies were identified that could be analyzed by dependency-check");
- } else {
- engine.analyzeDependencies();
- writeReports(engine, getProject(), getCorrectOutputDirectory());
- writeDataFile(getProject(), null, engine.getDependencies());
- showSummary(getProject(), engine.getDependencies());
- checkForFailure(engine.getDependencies());
+ if (engine != null) {
+ ExceptionCollection exCol = scanArtifacts(getProject(), engine);
+ if (engine.getDependencies().isEmpty()) {
+ getLog().info("No dependencies were identified that could be analyzed by dependency-check");
+ } else {
+ try {
+ engine.analyzeDependencies();
+ } catch (ExceptionCollection ex) {
+ if (this.isFailOnError() && ex.isFatal()) {
+ throw new MojoExecutionException("One or more exceptions occured during analysis", ex);
+ }
+ exCol = ex;
+ }
+ if (exCol == null || !exCol.isFatal()) {
+ try {
+ writeReports(engine, getProject(), getCorrectOutputDirectory());
+ } catch (ReportException ex) {
+ if (this.isFailOnError()) {
+ if (exCol != null) {
+ exCol.addException(ex);
+ } else {
+ exCol = new ExceptionCollection("Unable to write the dependency-check report", ex);
+ }
+ }
+ }
+ writeDataFile(getProject(), null, engine.getDependencies());
+ showSummary(getProject(), engine.getDependencies());
+ checkForFailure(engine.getDependencies());
+ if (exCol != null && this.isFailOnError()) {
+ throw new MojoExecutionException("One or more exceptions occured during dependency-check analysis", exCol);
+ }
+ }
+ }
+ engine.cleanup();
}
- engine.cleanup();
Settings.cleanup();
}
@@ -109,7 +144,8 @@ public class CheckMojo extends BaseDependencyCheckMojo {
}
/**
- * Gets the description of the Dependency-Check report to be displayed in the Maven Generated Reports page.
+ * Gets the description of the Dependency-Check report to be displayed in
+ * the Maven Generated Reports page.
*
* @param locale The Locale to get the description for
* @return the description
diff --git a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/Engine.java b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/MavenEngine.java
similarity index 81%
rename from dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/Engine.java
rename to dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/MavenEngine.java
index f849c8a7e..9edf53ae4 100644
--- a/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/Engine.java
+++ b/dependency-check-maven/src/main/java/org/owasp/dependencycheck/maven/MavenEngine.java
@@ -23,22 +23,25 @@ import org.owasp.dependencycheck.analyzer.Analyzer;
import org.owasp.dependencycheck.analyzer.CPEAnalyzer;
import org.owasp.dependencycheck.analyzer.FileTypeAnalyzer;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
+import org.owasp.dependencycheck.data.update.exception.UpdateException;
+import org.owasp.dependencycheck.exception.ExceptionCollection;
+import org.owasp.dependencycheck.exception.InitializationException;
import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
- * A modified version of the core engine specifically designed to persist some data between multiple executions of a multi-module
- * Maven project.
+ * A modified version of the core engine specifically designed to persist some
+ * data between multiple executions of a multi-module Maven project.
*
* @author Jeremy Long
*/
-public class Engine extends org.owasp.dependencycheck.Engine {
+public class MavenEngine extends org.owasp.dependencycheck.Engine {
/**
* The logger.
*/
- private static final transient Logger LOGGER = LoggerFactory.getLogger(Engine.class);
+ private static final transient Logger LOGGER = LoggerFactory.getLogger(MavenEngine.class);
/**
* A key used to persist an object in the MavenProject.
*/
@@ -52,18 +55,21 @@ public class Engine extends org.owasp.dependencycheck.Engine {
*/
private List-Dprop=value argument this method will return the value from the system properties before the values in the
- * contained configuration file.
+ * Returns a boolean value from the properties file. If the value was
+ * specified as a system property or passed in via the
+ * -Dprop=value argument this method will return the value from
+ * the system properties before the values in the contained configuration
+ * file.
*
* @param key the key to lookup within the properties file
* @return the property from the properties file
- * @throws InvalidSettingException is thrown if there is an error retrieving the setting
+ * @throws InvalidSettingException is thrown if there is an error retrieving
+ * the setting
*/
public static boolean getBoolean(String key) throws InvalidSettingException {
return Boolean.parseBoolean(Settings.getString(key));
}
/**
- * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the
- * -Dprop=value argument this method will return the value from the system properties before the values in the
- * contained configuration file.
+ * Returns a boolean value from the properties file. If the value was
+ * specified as a system property or passed in via the
+ * -Dprop=value argument this method will return the value from
+ * the system properties before the values in the contained configuration
+ * file.
*
* @param key the key to lookup within the properties file
- * @param defaultValue the default value to return if the setting does not exist
+ * @param defaultValue the default value to return if the setting does not
+ * exist
* @return the property from the properties file
- * @throws InvalidSettingException is thrown if there is an error retrieving the setting
+ * @throws InvalidSettingException is thrown if there is an error retrieving
+ * the setting
*/
public static boolean getBoolean(String key, boolean defaultValue) throws InvalidSettingException {
return Boolean.parseBoolean(Settings.getString(key, Boolean.toString(defaultValue)));
}
/**
- * Returns a connection string from the configured properties. If the connection string contains a %s, this method will
- * determine the 'data' directory and replace the %s with the path to the data directory. If the data directory does not
- * exists it will be created.
+ * Returns a connection string from the configured properties. If the
+ * connection string contains a %s, this method will determine the 'data'
+ * directory and replace the %s with the path to the data directory. If the
+ * data directory does not exists it will be created.
*
- * @param connectionStringKey the property file key for the connection string
+ * @param connectionStringKey the property file key for the connection
+ * string
* @param dbFileNameKey the settings key for the db filename
* @return the connection string
* @throws IOException thrown the data directory cannot be created
@@ -852,8 +916,9 @@ public final class Settings {
}
/**
- * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory for the
- * embedded H2 database. This is public solely for some unit tests; otherwise this should be private.
+ * Retrieves the directory that the JAR file exists in so that we can ensure
+ * we always use a common data directory for the embedded H2 database. This
+ * is public solely for some unit tests; otherwise this should be private.
*
* @return the data directory to store data files
* @throws IOException is thrown if an IOException occurs of course...
diff --git a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/URLConnectionFactory.java b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/URLConnectionFactory.java
index cbeb00a64..1d0f9db2f 100644
--- a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/URLConnectionFactory.java
+++ b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/URLConnectionFactory.java
@@ -28,15 +28,27 @@ import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.SocketAddress;
import java.net.URL;
+import java.net.URLConnection;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import javax.net.ssl.HttpsURLConnection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
- * A URLConnection Factory to create new connections. This encapsulates several configuration checks to ensure that the connection
- * uses the correct proxy settings.
+ * A URLConnection Factory to create new connections. This encapsulates several
+ * configuration checks to ensure that the connection uses the correct proxy
+ * settings.
*
* @author Jeremy Long
*/
public final class URLConnectionFactory {
+ /**
+ * The logger.
+ */
+ private static final Logger LOGGER = LoggerFactory.getLogger(URLConnectionFactory.class);
+
/**
* Private constructor for this factory.
*/
@@ -44,8 +56,9 @@ public final class URLConnectionFactory {
}
/**
- * Utility method to create an HttpURLConnection. If the application is configured to use a proxy this method will retrieve
- * the proxy settings and use them when setting up the connection.
+ * Utility method to create an HttpURLConnection. If the application is
+ * configured to use a proxy this method will retrieve the proxy settings
+ * and use them when setting up the connection.
*
* @param url the url to connect to
* @return an HttpURLConnection
@@ -95,6 +108,7 @@ public final class URLConnectionFactory {
}
throw new URLConnectionFailureException("Error getting connection.", ex);
}
+ configureTLS(url, conn);
return conn;
}
@@ -140,8 +154,10 @@ public final class URLConnectionFactory {
}
/**
- * Utility method to create an HttpURLConnection. The use of a proxy here is optional as there may be cases where a proxy is
- * configured but we don't want to use it (for example, if there's an internal repository configured)
+ * Utility method to create an HttpURLConnection. The use of a proxy here is
+ * optional as there may be cases where a proxy is configured but we don't
+ * want to use it (for example, if there's an internal repository
+ * configured)
*
* @param url the URL to connect to
* @param proxy whether to use the proxy (if configured)
@@ -161,6 +177,29 @@ public final class URLConnectionFactory {
} catch (IOException ioe) {
throw new URLConnectionFailureException("Error getting connection.", ioe);
}
+ configureTLS(url, conn);
return conn;
}
+
+ /**
+ * If the protocol is HTTPS, this will configure the cipher suites so that
+ * connections can be made to the NVD, and others, using older versions of
+ * Java.
+ *
+ * @param url the URL
+ * @param conn the connection
+ */
+ private static void configureTLS(URL url, URLConnection conn) {
+ if ("https".equals(url.getProtocol())) {
+ try {
+ final HttpsURLConnection secCon = (HttpsURLConnection) conn;
+ final SSLSocketFactoryEx factory = new SSLSocketFactoryEx();
+ secCon.setSSLSocketFactory(factory);
+ } catch (NoSuchAlgorithmException ex) {
+ LOGGER.debug("Unsupported algorithm in SSLSocketFactoryEx", ex);
+ } catch (KeyManagementException ex) {
+ LOGGER.debug("Key mnagement eception in SSLSocketFactoryEx", ex);
+ }
+ }
+ }
}
diff --git a/pom.xml b/pom.xml
index 0576d574c..c44d75cd0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -20,7 +20,7 @@ Copyright (c) 2012 - Jeremy Long