mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-04-09 18:33:54 +02:00
Merge pull request #681 from jeremylong/java7_updates_and_cleanup
Java7 updates and cleanup
This commit is contained in:
@@ -288,7 +288,7 @@ Copyright (c) 2013 - Jeremy Long. All Rights Reserved.
|
|||||||
<version>${reporting.pmd-plugin.version}</version>
|
<version>${reporting.pmd-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetJdk>1.6</targetJdk>
|
<targetJdk>1.6</targetJdk>
|
||||||
<linkXref>true</linkXref>
|
<linkXRef>true</linkXRef>
|
||||||
<sourceEncoding>utf-8</sourceEncoding>
|
<sourceEncoding>utf-8</sourceEncoding>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/generated/*.java</exclude>
|
<exclude>**/generated/*.java</exclude>
|
||||||
|
|||||||
@@ -69,9 +69,8 @@ public class Check extends Update {
|
|||||||
* Whether the CMake analyzer should be enabled.
|
* Whether the CMake analyzer should be enabled.
|
||||||
*/
|
*/
|
||||||
private Boolean cmakeAnalyzerEnabled;
|
private Boolean cmakeAnalyzerEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether or not the openssl analyzer is enabled.
|
* Whether or not the Open SSL analyzer is enabled.
|
||||||
*/
|
*/
|
||||||
private Boolean opensslAnalyzerEnabled;
|
private Boolean opensslAnalyzerEnabled;
|
||||||
/**
|
/**
|
||||||
@@ -90,7 +89,6 @@ public class Check extends Update {
|
|||||||
* Whether or not the nexus analyzer is enabled.
|
* Whether or not the nexus analyzer is enabled.
|
||||||
*/
|
*/
|
||||||
private Boolean nexusAnalyzerEnabled;
|
private Boolean nexusAnalyzerEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The URL of a Nexus server's REST API end point
|
* The URL of a Nexus server's REST API end point
|
||||||
* (http://domain/nexus/service/local).
|
* (http://domain/nexus/service/local).
|
||||||
@@ -121,7 +119,6 @@ public class Check extends Update {
|
|||||||
* The name of the project being analyzed.
|
* The name of the project being analyzed.
|
||||||
*/
|
*/
|
||||||
private String projectName = "dependency-check";
|
private String projectName = "dependency-check";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies the destination directory for the generated Dependency-Check
|
* Specifies the destination directory for the generated Dependency-Check
|
||||||
* report.
|
* report.
|
||||||
@@ -189,7 +186,8 @@ public class Check extends Update {
|
|||||||
/**
|
/**
|
||||||
* Whether or not the .NET Assembly Analyzer is enabled.
|
* Whether or not the .NET Assembly Analyzer is enabled.
|
||||||
*/
|
*/
|
||||||
private Boolean assemblyAnalyzerEnabled; /**
|
private Boolean assemblyAnalyzerEnabled;
|
||||||
|
/**
|
||||||
* Whether the autoconf analyzer should be enabled.
|
* Whether the autoconf analyzer should be enabled.
|
||||||
*/
|
*/
|
||||||
private Boolean autoconfAnalyzerEnabled;
|
private Boolean autoconfAnalyzerEnabled;
|
||||||
@@ -213,9 +211,9 @@ public class Check extends Update {
|
|||||||
*/
|
*/
|
||||||
private Resources path = null;
|
private Resources path = null;
|
||||||
/**
|
/**
|
||||||
* Reference to path/fileset to convert
|
* Reference to path/file set to convert
|
||||||
*/
|
*/
|
||||||
private Reference refid = null;
|
private Reference refId = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an arbitrary ResourceCollection.
|
* Add an arbitrary ResourceCollection.
|
||||||
@@ -225,7 +223,7 @@ public class Check extends Update {
|
|||||||
*/
|
*/
|
||||||
public void add(ResourceCollection rc) {
|
public void add(ResourceCollection rc) {
|
||||||
if (isReference()) {
|
if (isReference()) {
|
||||||
throw new BuildException("Nested elements are not allowed when using the refid attribute.");
|
throw new BuildException("Nested elements are not allowed when using the refId attribute.");
|
||||||
}
|
}
|
||||||
getPath().add(rc);
|
getPath().add(rc);
|
||||||
}
|
}
|
||||||
@@ -245,12 +243,12 @@ public class Check extends Update {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Learn whether the refid attribute of this element been set.
|
* Learn whether the refId attribute of this element been set.
|
||||||
*
|
*
|
||||||
* @return true if refid is valid.
|
* @return true if refId is valid.
|
||||||
*/
|
*/
|
||||||
public boolean isReference() {
|
public boolean isReference() {
|
||||||
return refid != null;
|
return refId != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -259,11 +257,11 @@ public class Check extends Update {
|
|||||||
*
|
*
|
||||||
* @param r the reference to a path, fileset, dirset or filelist.
|
* @param r the reference to a path, fileset, dirset or filelist.
|
||||||
*/
|
*/
|
||||||
public void setRefid(Reference r) {
|
public synchronized void setRefId(Reference r) {
|
||||||
if (path != null) {
|
if (path != null) {
|
||||||
throw new BuildException("Nested elements are not allowed when using the refid attribute.");
|
throw new BuildException("Nested elements are not allowed when using the refId attribute.");
|
||||||
}
|
}
|
||||||
refid = r;
|
refId = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -274,9 +272,9 @@ public class Check extends Update {
|
|||||||
*/
|
*/
|
||||||
private void dealWithReferences() throws BuildException {
|
private void dealWithReferences() throws BuildException {
|
||||||
if (isReference()) {
|
if (isReference()) {
|
||||||
final Object o = refid.getReferencedObject(getProject());
|
final Object o = refId.getReferencedObject(getProject());
|
||||||
if (!(o instanceof ResourceCollection)) {
|
if (!(o instanceof ResourceCollection)) {
|
||||||
throw new BuildException("refid '" + refid.getRefId()
|
throw new BuildException("refId '" + refId.getRefId()
|
||||||
+ "' does not refer to a resource collection.");
|
+ "' does not refer to a resource collection.");
|
||||||
}
|
}
|
||||||
getPath().add((ResourceCollection) o);
|
getPath().add((ResourceCollection) o);
|
||||||
@@ -284,7 +282,6 @@ public class Check extends Update {
|
|||||||
}
|
}
|
||||||
// END COPY from org.apache.tools.ant.taskdefs
|
// END COPY from org.apache.tools.ant.taskdefs
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Construct a new DependencyCheckTask.
|
* Construct a new DependencyCheckTask.
|
||||||
*/
|
*/
|
||||||
@@ -317,6 +314,7 @@ public class Check extends Update {
|
|||||||
public void setApplicationName(String applicationName) {
|
public void setApplicationName(String applicationName) {
|
||||||
this.applicationName = applicationName;
|
this.applicationName = applicationName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of projectName.
|
* Get the value of projectName.
|
||||||
*
|
*
|
||||||
@@ -470,6 +468,7 @@ public class Check extends Update {
|
|||||||
public void setHintsFile(String hintsFile) {
|
public void setHintsFile(String hintsFile) {
|
||||||
this.hintsFile = hintsFile;
|
this.hintsFile = hintsFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of showSummary.
|
* Get the value of showSummary.
|
||||||
*
|
*
|
||||||
@@ -670,9 +669,9 @@ public class Check extends Update {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if the cocoapods analyyzer is enabled.
|
* Returns if the cocoapods analyzer is enabled.
|
||||||
*
|
*
|
||||||
* @return if the cocoapods analyyzer is enabled
|
* @return if the cocoapods analyzer is enabled
|
||||||
*/
|
*/
|
||||||
public boolean isCocoapodsAnalyzerEnabled() {
|
public boolean isCocoapodsAnalyzerEnabled() {
|
||||||
return cocoapodsAnalyzerEnabled;
|
return cocoapodsAnalyzerEnabled;
|
||||||
@@ -924,7 +923,7 @@ public class Check extends Update {
|
|||||||
log(ex.getMessage(), Project.MSG_ERR);
|
log(ex.getMessage(), Project.MSG_ERR);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (Resource resource : path) {
|
for (Resource resource : getPath()) {
|
||||||
final FileProvider provider = resource.as(FileProvider.class);
|
final FileProvider provider = resource.as(FileProvider.class);
|
||||||
if (provider != null) {
|
if (provider != null) {
|
||||||
final File file = provider.getFile();
|
final File file = provider.getFile();
|
||||||
@@ -942,7 +941,7 @@ public class Check extends Update {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
DatabaseProperties prop = null;
|
DatabaseProperties prop = null;
|
||||||
CveDB cve = null;
|
CveDB cve;
|
||||||
try {
|
try {
|
||||||
cve = CveDB.getInstance();
|
cve = CveDB.getInstance();
|
||||||
prop = cve.getDatabaseProperties();
|
prop = cve.getDatabaseProperties();
|
||||||
@@ -988,7 +987,7 @@ public class Check extends Update {
|
|||||||
* @throws BuildException if the task was not configured correctly.
|
* @throws BuildException if the task was not configured correctly.
|
||||||
*/
|
*/
|
||||||
private void validateConfiguration() throws BuildException {
|
private void validateConfiguration() throws BuildException {
|
||||||
if (path == null) {
|
if (getPath() == null) {
|
||||||
throw new BuildException("No project dependencies have been defined to analyze.");
|
throw new BuildException("No project dependencies have been defined to analyze.");
|
||||||
}
|
}
|
||||||
if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) {
|
if (failBuildOnCVSS < 0 || failBuildOnCVSS > 11) {
|
||||||
|
|||||||
@@ -95,6 +95,12 @@ public class Purge extends Task {
|
|||||||
this.failOnError = failOnError;
|
this.failOnError = failOnError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes the dependency-check purge to delete the existing local copy of
|
||||||
|
* the NVD CVE data.
|
||||||
|
*
|
||||||
|
* @throws BuildException thrown if there is a problem deleting the file(s)
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws BuildException {
|
public void execute() throws BuildException {
|
||||||
populateSettings();
|
populateSettings();
|
||||||
@@ -138,9 +144,7 @@ public class Purge extends Task {
|
|||||||
*/
|
*/
|
||||||
protected void populateSettings() throws BuildException {
|
protected void populateSettings() throws BuildException {
|
||||||
Settings.initialize();
|
Settings.initialize();
|
||||||
InputStream taskProperties = null;
|
try (InputStream taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE)) {
|
||||||
try {
|
|
||||||
taskProperties = this.getClass().getClassLoader().getResourceAsStream(PROPERTIES_FILE);
|
|
||||||
Settings.mergeProperties(taskProperties);
|
Settings.mergeProperties(taskProperties);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
final String msg = "Unable to load the dependency-check ant task.properties file.";
|
final String msg = "Unable to load the dependency-check ant task.properties file.";
|
||||||
@@ -148,14 +152,6 @@ public class Purge extends Task {
|
|||||||
throw new BuildException(msg, ex);
|
throw new BuildException(msg, ex);
|
||||||
}
|
}
|
||||||
log(msg, ex, Project.MSG_WARN);
|
log(msg, ex, Project.MSG_WARN);
|
||||||
} finally {
|
|
||||||
if (taskProperties != null) {
|
|
||||||
try {
|
|
||||||
taskProperties.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
log("", ex, Project.MSG_DEBUG);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (dataDirectory != null) {
|
if (dataDirectory != null) {
|
||||||
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
Settings.setString(Settings.KEYS.DATA_DIRECTORY, dataDirectory);
|
||||||
|
|||||||
@@ -61,11 +61,14 @@
|
|||||||
|
|
||||||
<target name="failCVSS">
|
<target name="failCVSS">
|
||||||
<dependency-check
|
<dependency-check
|
||||||
applicationName="test formatBAD"
|
applicationName="test failCVSS"
|
||||||
reportOutputDirectory="${project.build.directory}"
|
reportOutputDirectory="${project.build.directory}"
|
||||||
reportFormat="XML"
|
reportFormat="XML"
|
||||||
autoupdate="false"
|
autoupdate="false"
|
||||||
failBuildOnCVSS="8">
|
failBuildOnCVSS="3">
|
||||||
|
<fileset dir="${project.build.directory}/test-classes/jars">
|
||||||
|
<include name="axis-1.4.jar"/>
|
||||||
|
</fileset>
|
||||||
</dependency-check>
|
</dependency-check>
|
||||||
</target>
|
</target>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -196,7 +196,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
|
|||||||
<version>${reporting.pmd-plugin.version}</version>
|
<version>${reporting.pmd-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetJdk>1.6</targetJdk>
|
<targetJdk>1.6</targetJdk>
|
||||||
<linkXref>true</linkXref>
|
<linkXRef>true</linkXRef>
|
||||||
<sourceEncoding>utf-8</sourceEncoding>
|
<sourceEncoding>utf-8</sourceEncoding>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/generated/*.java</exclude>
|
<exclude>**/generated/*.java</exclude>
|
||||||
|
|||||||
@@ -223,13 +223,13 @@ public class App {
|
|||||||
int retCode = 0;
|
int retCode = 0;
|
||||||
try {
|
try {
|
||||||
engine = new Engine();
|
engine = new Engine();
|
||||||
final List<String> antStylePaths = new ArrayList<String>();
|
final List<String> antStylePaths = new ArrayList<>();
|
||||||
for (String file : files) {
|
for (String file : files) {
|
||||||
final String antPath = ensureCanonicalPath(file);
|
final String antPath = ensureCanonicalPath(file);
|
||||||
antStylePaths.add(antPath);
|
antStylePaths.add(antPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
final Set<File> paths = new HashSet<File>();
|
final Set<File> paths = new HashSet<>();
|
||||||
for (String file : antStylePaths) {
|
for (String file : antStylePaths) {
|
||||||
LOGGER.debug("Scanning {}", file);
|
LOGGER.debug("Scanning {}", file);
|
||||||
final DirectoryScanner scanner = new DirectoryScanner();
|
final DirectoryScanner scanner = new DirectoryScanner();
|
||||||
@@ -282,10 +282,8 @@ public class App {
|
|||||||
exCol = ex;
|
exCol = ex;
|
||||||
}
|
}
|
||||||
final List<Dependency> dependencies = engine.getDependencies();
|
final List<Dependency> dependencies = engine.getDependencies();
|
||||||
DatabaseProperties prop = null;
|
final CveDB cve = CveDB.getInstance();
|
||||||
CveDB cve = null;
|
final DatabaseProperties prop = cve.getDatabaseProperties();
|
||||||
cve = CveDB.getInstance();
|
|
||||||
prop = cve.getDatabaseProperties();
|
|
||||||
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
|
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, engine.getAnalyzers(), prop);
|
||||||
try {
|
try {
|
||||||
report.generateReports(reportDirectory, outputFormat);
|
report.generateReports(reportDirectory, outputFormat);
|
||||||
@@ -461,7 +459,7 @@ public class App {
|
|||||||
encoder.setPattern("%d %C:%L%n%-5level - %msg%n");
|
encoder.setPattern("%d %C:%L%n%-5level - %msg%n");
|
||||||
encoder.setContext(context);
|
encoder.setContext(context);
|
||||||
encoder.start();
|
encoder.start();
|
||||||
final FileAppender<ILoggingEvent> fa = new FileAppender<ILoggingEvent>();
|
final FileAppender<ILoggingEvent> fa = new FileAppender<>();
|
||||||
fa.setAppend(true);
|
fa.setAppend(true);
|
||||||
fa.setEncoder(encoder);
|
fa.setEncoder(encoder);
|
||||||
fa.setContext(context);
|
fa.setContext(context);
|
||||||
|
|||||||
@@ -249,7 +249,7 @@ public final class CliParser {
|
|||||||
|
|
||||||
final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE)
|
final Option excludes = Option.builder().argName("pattern").hasArg().longOpt(ARGUMENT.EXCLUDE)
|
||||||
.desc("Specify and exclusion pattern. This option can be specified multiple times"
|
.desc("Specify and exclusion pattern. This option can be specified multiple times"
|
||||||
+ " and it accepts Ant style excludsions.")
|
+ " and it accepts Ant style exclusions.")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP)
|
final Option props = Option.builder(ARGUMENT.PROP_SHORT).argName("file").hasArg().longOpt(ARGUMENT.PROP)
|
||||||
@@ -286,7 +286,7 @@ public final class CliParser {
|
|||||||
.build();
|
.build();
|
||||||
|
|
||||||
final Option experimentalEnabled = Option.builder().longOpt(ARGUMENT.EXPERIMENTAL)
|
final Option experimentalEnabled = Option.builder().longOpt(ARGUMENT.EXPERIMENTAL)
|
||||||
.desc("Enables the experimental analzers.")
|
.desc("Enables the experimental analyzers.")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
final Option failOnCVSS = Option.builder().argName("score").hasArg().longOpt(ARGUMENT.FAIL_ON_CVSS)
|
final Option failOnCVSS = Option.builder().argName("score").hasArg().longOpt(ARGUMENT.FAIL_ON_CVSS)
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
|||||||
<version>${reporting.pmd-plugin.version}</version>
|
<version>${reporting.pmd-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetJdk>1.6</targetJdk>
|
<targetJdk>1.6</targetJdk>
|
||||||
<linkXref>true</linkXref>
|
<linkXRef>true</linkXRef>
|
||||||
<sourceEncoding>utf-8</sourceEncoding>
|
<sourceEncoding>utf-8</sourceEncoding>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/generated/*.java</exclude>
|
<exclude>**/generated/*.java</exclude>
|
||||||
|
|||||||
@@ -86,7 +86,6 @@ public class AnalysisTask implements Callable<Void> {
|
|||||||
* Executes the analysis task.
|
* Executes the analysis task.
|
||||||
*
|
*
|
||||||
* @return null
|
* @return null
|
||||||
* @throws Exception thrown if unable to execute the analysis task
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Void call() {
|
public Void call() {
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class Engine implements FileFilter {
|
|||||||
/**
|
/**
|
||||||
* A Map of analyzers grouped by Analysis phase.
|
* A Map of analyzers grouped by Analysis phase.
|
||||||
*/
|
*/
|
||||||
private final Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<FileTypeAnalyzer>();
|
private final Set<FileTypeAnalyzer> fileTypeAnalyzers = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ClassLoader to use when dynamically loading Analyzer and Update
|
* The ClassLoader to use when dynamically loading Analyzer and Update
|
||||||
@@ -281,7 +281,7 @@ public class Engine implements FileFilter {
|
|||||||
* @since v1.4.4
|
* @since v1.4.4
|
||||||
*/
|
*/
|
||||||
public List<Dependency> scan(File[] files, String projectReference) {
|
public List<Dependency> scan(File[] files, String projectReference) {
|
||||||
final List<Dependency> deps = new ArrayList<Dependency>();
|
final List<Dependency> deps = new ArrayList<>();
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
final List<Dependency> d = scan(file, projectReference);
|
final List<Dependency> d = scan(file, projectReference);
|
||||||
if (d != null) {
|
if (d != null) {
|
||||||
@@ -316,7 +316,7 @@ public class Engine implements FileFilter {
|
|||||||
* @since v1.4.4
|
* @since v1.4.4
|
||||||
*/
|
*/
|
||||||
public List<Dependency> scan(Collection<File> files, String projectReference) {
|
public List<Dependency> scan(Collection<File> files, String projectReference) {
|
||||||
final List<Dependency> deps = new ArrayList<Dependency>();
|
final List<Dependency> deps = new ArrayList<>();
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
final List<Dependency> d = scan(file, projectReference);
|
final List<Dependency> d = scan(file, projectReference);
|
||||||
if (d != null) {
|
if (d != null) {
|
||||||
@@ -357,7 +357,7 @@ public class Engine implements FileFilter {
|
|||||||
} else {
|
} else {
|
||||||
final Dependency d = scanFile(file, projectReference);
|
final Dependency d = scanFile(file, projectReference);
|
||||||
if (d != null) {
|
if (d != null) {
|
||||||
final List<Dependency> deps = new ArrayList<Dependency>();
|
final List<Dependency> deps = new ArrayList<>();
|
||||||
deps.add(d);
|
deps.add(d);
|
||||||
return deps;
|
return deps;
|
||||||
}
|
}
|
||||||
@@ -626,11 +626,10 @@ public class Engine implements FileFilter {
|
|||||||
* Initializes the given analyzer.
|
* Initializes the given analyzer.
|
||||||
*
|
*
|
||||||
* @param analyzer the analyzer to initialize
|
* @param analyzer the analyzer to initialize
|
||||||
* @return the initialized analyzer
|
|
||||||
* @throws InitializationException thrown when there is a problem
|
* @throws InitializationException thrown when there is a problem
|
||||||
* initializing the analyzer
|
* initializing the analyzer
|
||||||
*/
|
*/
|
||||||
protected Analyzer initializeAnalyzer(Analyzer analyzer) throws InitializationException {
|
protected void initializeAnalyzer(Analyzer analyzer) throws InitializationException {
|
||||||
try {
|
try {
|
||||||
LOGGER.debug("Initializing {}", analyzer.getName());
|
LOGGER.debug("Initializing {}", analyzer.getName());
|
||||||
analyzer.initialize();
|
analyzer.initialize();
|
||||||
@@ -653,7 +652,6 @@ public class Engine implements FileFilter {
|
|||||||
}
|
}
|
||||||
throw new InitializationException("Unexpected Exception", ex);
|
throw new InitializationException("Unexpected Exception", ex);
|
||||||
}
|
}
|
||||||
return analyzer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.owasp.dependencycheck.dependency.Dependency;
|
|||||||
import org.owasp.dependencycheck.dependency.Identifier;
|
import org.owasp.dependencycheck.dependency.Identifier;
|
||||||
import org.owasp.dependencycheck.dependency.Vulnerability;
|
import org.owasp.dependencycheck.dependency.Vulnerability;
|
||||||
import org.owasp.dependencycheck.exception.ExceptionCollection;
|
import org.owasp.dependencycheck.exception.ExceptionCollection;
|
||||||
|
import org.owasp.dependencycheck.exception.ReportException;
|
||||||
import org.owasp.dependencycheck.exception.ScanAgentException;
|
import org.owasp.dependencycheck.exception.ScanAgentException;
|
||||||
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
import org.owasp.dependencycheck.reporting.ReportGenerator;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
@@ -842,7 +843,7 @@ public class DependencyCheckScanAgent {
|
|||||||
*/
|
*/
|
||||||
private void generateExternalReports(Engine engine, File outDirectory) {
|
private void generateExternalReports(Engine engine, File outDirectory) {
|
||||||
DatabaseProperties prop = null;
|
DatabaseProperties prop = null;
|
||||||
CveDB cve = null;
|
CveDB cve;
|
||||||
try {
|
try {
|
||||||
cve = CveDB.getInstance();
|
cve = CveDB.getInstance();
|
||||||
prop = cve.getDatabaseProperties();
|
prop = cve.getDatabaseProperties();
|
||||||
@@ -853,13 +854,9 @@ public class DependencyCheckScanAgent {
|
|||||||
final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop);
|
final ReportGenerator r = new ReportGenerator(this.applicationName, engine.getDependencies(), engine.getAnalyzers(), prop);
|
||||||
try {
|
try {
|
||||||
r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name());
|
r.generateReports(outDirectory.getCanonicalPath(), this.reportFormat.name());
|
||||||
} catch (IOException ex) {
|
} catch (IOException | ReportException ex) {
|
||||||
LOGGER.error("Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
LOGGER.error("Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
} catch (Throwable ex) {
|
|
||||||
LOGGER.error(
|
|
||||||
"Unexpected exception occurred during analysis; please see the verbose error log for more details.");
|
|
||||||
LOGGER.debug("", ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,7 @@ public abstract class AbstractFileTypeAnalyzer extends AbstractAnalyzer implemen
|
|||||||
* @return a Set of strings.
|
* @return a Set of strings.
|
||||||
*/
|
*/
|
||||||
protected static Set<String> newHashSet(String... strings) {
|
protected static Set<String> newHashSet(String... strings) {
|
||||||
final Set<String> set = new HashSet<String>(strings.length);
|
final Set<String> set = new HashSet<>(strings.length);
|
||||||
Collections.addAll(set, strings);
|
Collections.addAll(set, strings);
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -130,10 +130,9 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
file = new File(suppressionFilePath);
|
file = new File(suppressionFilePath);
|
||||||
InputStream suppressionsFromClasspath = null;
|
|
||||||
if (!file.exists()) {
|
if (!file.exists()) {
|
||||||
try {
|
try (InputStream suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath)) {
|
||||||
suppressionsFromClasspath = this.getClass().getClassLoader().getResourceAsStream(suppressionFilePath);
|
|
||||||
if (suppressionsFromClasspath != null) {
|
if (suppressionsFromClasspath != null) {
|
||||||
deleteTempFile = true;
|
deleteTempFile = true;
|
||||||
file = FileUtils.getTempFile("suppression", "xml");
|
file = FileUtils.getTempFile("suppression", "xml");
|
||||||
@@ -143,14 +142,6 @@ public abstract class AbstractSuppressionAnalyzer extends AbstractAnalyzer {
|
|||||||
throwSuppressionParseException("Unable to locate suppressions file in classpath", 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,13 +57,13 @@ public class AnalyzerService {
|
|||||||
* @return a list of Analyzers.
|
* @return a list of Analyzers.
|
||||||
*/
|
*/
|
||||||
public List<Analyzer> getAnalyzers() {
|
public List<Analyzer> getAnalyzers() {
|
||||||
final List<Analyzer> analyzers = new ArrayList<Analyzer>();
|
final List<Analyzer> analyzers = new ArrayList<>();
|
||||||
final Iterator<Analyzer> iterator = service.iterator();
|
final Iterator<Analyzer> iterator = service.iterator();
|
||||||
boolean experimentalEnabled = false;
|
boolean experimentalEnabled = false;
|
||||||
try {
|
try {
|
||||||
experimentalEnabled = Settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false);
|
experimentalEnabled = Settings.getBoolean(Settings.KEYS.ANALYZER_EXPERIMENTAL_ENABLED, false);
|
||||||
} catch (InvalidSettingException ex) {
|
} catch (InvalidSettingException ex) {
|
||||||
LOGGER.error("invalide experimental setting", ex);
|
LOGGER.error("invalid experimental setting", ex);
|
||||||
}
|
}
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
final Analyzer a = iterator.next();
|
final Analyzer a = iterator.next();
|
||||||
|
|||||||
@@ -98,20 +98,21 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
/**
|
/**
|
||||||
* The set of things we can handle with Zip methods
|
* The set of things we can handle with Zip methods
|
||||||
*/
|
*/
|
||||||
private static final Set<String> ZIPPABLES = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg");
|
private static final Set<String> KNOWN_ZIP_EXT = newHashSet("zip", "ear", "war", "jar", "sar", "apk", "nupkg");
|
||||||
/**
|
/**
|
||||||
* The set of file extensions supported by this analyzer. Note for
|
* The set of file extensions supported by this analyzer. Note for
|
||||||
* developers, any additions to this list will need to be explicitly handled
|
* developers, any additions to this list will need to be explicitly handled
|
||||||
* in {@link #extractFiles(File, File, Engine)}.
|
* in {@link #extractFiles(File, File, Engine)}.
|
||||||
*/
|
*/
|
||||||
private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2");
|
private static final Set<String> EXTENSIONS = newHashSet("tar", "gz", "tgz", "bz2", "tbz2");
|
||||||
|
|
||||||
static {
|
static {
|
||||||
final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
|
final String additionalZipExt = Settings.getString(Settings.KEYS.ADDITIONAL_ZIP_EXTENSIONS);
|
||||||
if (additionalZipExt != null) {
|
if (additionalZipExt != null) {
|
||||||
final String[] ext = additionalZipExt.split("\\s*,\\s*");
|
final String[] ext = additionalZipExt.split("\\s*,\\s*");
|
||||||
Collections.addAll(ZIPPABLES, ext);
|
Collections.addAll(KNOWN_ZIP_EXT, ext);
|
||||||
}
|
}
|
||||||
EXTENSIONS.addAll(ZIPPABLES);
|
EXTENSIONS.addAll(KNOWN_ZIP_EXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -220,6 +221,8 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
* Does not support parallel processing as it both modifies and iterates
|
* Does not support parallel processing as it both modifies and iterates
|
||||||
* over the engine's list of dependencies.
|
* over the engine's list of dependencies.
|
||||||
*
|
*
|
||||||
|
* @return <code>true</code> if the analyzer supports parallel processing;
|
||||||
|
* otherwise <code>false</code>
|
||||||
* @see #analyzeDependency(Dependency, Engine)
|
* @see #analyzeDependency(Dependency, Engine)
|
||||||
* @see #findMoreDependencies(Engine, File)
|
* @see #findMoreDependencies(Engine, File)
|
||||||
*/
|
*/
|
||||||
@@ -300,11 +303,11 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private void addDisguisedJarsToDependencies(Dependency dependency, Engine engine) throws AnalysisException {
|
private void addDisguisedJarsToDependencies(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) {
|
if (ZIP_FILTER.accept(dependency.getActualFile()) && isZipFileActuallyJarFile(dependency)) {
|
||||||
final File tdir = getNextTempDirectory();
|
final File tempDir = getNextTempDirectory();
|
||||||
final String fileName = dependency.getFileName();
|
final String fileName = dependency.getFileName();
|
||||||
|
|
||||||
LOGGER.info("The zip file '{}' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName);
|
LOGGER.info("The zip file '{}' appears to be a JAR file, making a copy and analyzing it as a JAR.", fileName);
|
||||||
final File tmpLoc = new File(tdir, fileName.substring(0, fileName.length() - 3) + "jar");
|
final File tmpLoc = new File(tempDir, fileName.substring(0, fileName.length() - 3) + "jar");
|
||||||
//store the archives sha1 and change it so that the engine doesn't think the zip and jar file are the same
|
//store the archives sha1 and change it so that the engine doesn't think the zip and jar file are the same
|
||||||
// and add it is a related dependency.
|
// and add it is a related dependency.
|
||||||
final String archiveSha1 = dependency.getSha1sum();
|
final String archiveSha1 = dependency.getSha1sum();
|
||||||
@@ -344,8 +347,7 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
* @return any dependencies that weren't known to the engine before
|
* @return any dependencies that weren't known to the engine before
|
||||||
*/
|
*/
|
||||||
private static List<Dependency> findMoreDependencies(Engine engine, File file) {
|
private static List<Dependency> findMoreDependencies(Engine engine, File file) {
|
||||||
final List<Dependency> added = engine.scan(file);
|
return engine.scan(file);
|
||||||
return added;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -397,7 +399,7 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
GzipCompressorInputStream gin = null;
|
GzipCompressorInputStream gin = null;
|
||||||
BZip2CompressorInputStream bzin = null;
|
BZip2CompressorInputStream bzin = null;
|
||||||
try {
|
try {
|
||||||
if (ZIPPABLES.contains(archiveExt)) {
|
if (KNOWN_ZIP_EXT.contains(archiveExt)) {
|
||||||
in = new BufferedInputStream(fis);
|
in = new BufferedInputStream(fis);
|
||||||
ensureReadableJar(archiveExt, in);
|
ensureReadableJar(archiveExt, in);
|
||||||
zin = new ZipArchiveInputStream(in);
|
zin = new ZipArchiveInputStream(in);
|
||||||
@@ -517,7 +519,7 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
extractAcceptedFile(input, file);
|
extractAcceptedFile(input, file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable ex) {
|
} catch (IOException | AnalysisException ex) {
|
||||||
throw new ArchiveExtractionException(ex);
|
throw new ArchiveExtractionException(ex);
|
||||||
} finally {
|
} finally {
|
||||||
FileUtils.close(input);
|
FileUtils.close(input);
|
||||||
@@ -533,14 +535,12 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private static void extractAcceptedFile(ArchiveInputStream input, File file) throws AnalysisException {
|
private static void extractAcceptedFile(ArchiveInputStream input, File file) throws AnalysisException {
|
||||||
LOGGER.debug("Extracting '{}'", file.getPath());
|
LOGGER.debug("Extracting '{}'", file.getPath());
|
||||||
FileOutputStream fos = null;
|
final File parent = file.getParentFile();
|
||||||
try {
|
if (!parent.isDirectory() && !parent.mkdirs()) {
|
||||||
final File parent = file.getParentFile();
|
final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath());
|
||||||
if (!parent.isDirectory() && !parent.mkdirs()) {
|
throw new AnalysisException(msg);
|
||||||
final String msg = String.format("Unable to build directory '%s'.", parent.getAbsolutePath());
|
}
|
||||||
throw new AnalysisException(msg);
|
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||||
}
|
|
||||||
fos = new FileOutputStream(file);
|
|
||||||
IOUtils.copy(input, fos);
|
IOUtils.copy(input, fos);
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
@@ -550,8 +550,6 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
|
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
|
||||||
throw new AnalysisException(msg, ex);
|
throw new AnalysisException(msg, ex);
|
||||||
} finally {
|
|
||||||
FileUtils.close(fos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,18 +563,11 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException {
|
private void decompressFile(CompressorInputStream inputStream, File outputFile) throws ArchiveExtractionException {
|
||||||
LOGGER.debug("Decompressing '{}'", outputFile.getPath());
|
LOGGER.debug("Decompressing '{}'", outputFile.getPath());
|
||||||
FileOutputStream out = null;
|
try (FileOutputStream out = new FileOutputStream(outputFile)) {
|
||||||
try {
|
|
||||||
out = new FileOutputStream(outputFile);
|
|
||||||
IOUtils.copy(inputStream, out);
|
IOUtils.copy(inputStream, out);
|
||||||
} catch (FileNotFoundException ex) {
|
|
||||||
LOGGER.debug("", ex);
|
|
||||||
throw new ArchiveExtractionException(ex);
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new ArchiveExtractionException(ex);
|
throw new ArchiveExtractionException(ex);
|
||||||
} finally {
|
|
||||||
FileUtils.close(out);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -610,7 +601,6 @@ public class ArchiveAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
} finally {
|
} finally {
|
||||||
ZipFile.closeQuietly(zip);
|
ZipFile.closeQuietly(zip);
|
||||||
}
|
}
|
||||||
|
|
||||||
return isJar;
|
return isJar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*/
|
*/
|
||||||
protected List<String> buildArgumentList() {
|
protected List<String> buildArgumentList() {
|
||||||
// Use file.separator as a wild guess as to whether this is Windows
|
// Use file.separator as a wild guess as to whether this is Windows
|
||||||
final List<String> args = new ArrayList<String>();
|
final List<String> args = new ArrayList<>();
|
||||||
if (!SystemUtils.IS_OS_WINDOWS) {
|
if (!SystemUtils.IS_OS_WINDOWS) {
|
||||||
if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) {
|
if (Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH) != null) {
|
||||||
args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH));
|
args.add(Settings.getString(Settings.KEYS.ANALYZER_ASSEMBLY_MONO_PATH));
|
||||||
@@ -144,7 +144,8 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
dependency.getActualFilePath());
|
dependency.getActualFilePath());
|
||||||
return;
|
return;
|
||||||
} else if (rc != 0) {
|
} else if (rc != 0) {
|
||||||
LOGGER.debug("Return code {} from GrokAssembly; dependency-check is unable to analyze the library: {}", rc, dependency.getActualFilePath());
|
LOGGER.debug("Return code {} from GrokAssembly; dependency-check is unable to analyze the library: {}",
|
||||||
|
rc, dependency.getActualFilePath());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,18 +177,17 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
|
|
||||||
} catch (ParserConfigurationException pce) {
|
} catch (ParserConfigurationException pce) {
|
||||||
throw new AnalysisException("Error initializing the assembly analyzer", pce);
|
throw new AnalysisException("Error initializing the assembly analyzer", pce);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException | XPathExpressionException ioe) {
|
||||||
throw new AnalysisException(ioe);
|
throw new AnalysisException(ioe);
|
||||||
} catch (SAXException saxe) {
|
} catch (SAXException saxe) {
|
||||||
LOGGER.error("----------------------------------------------------");
|
LOGGER.error("----------------------------------------------------");
|
||||||
LOGGER.error("Failed to read the Assembly Analyzer results. "
|
LOGGER.error("Failed to read the Assembly Analyzer results. "
|
||||||
+ "On some systems mono-runtime and mono-devel need to be installed.");
|
+ "On some systems mono-runtime and mono-devel need to be installed.");
|
||||||
LOGGER.error("----------------------------------------------------");
|
LOGGER.error("----------------------------------------------------");
|
||||||
throw new AnalysisException("Couldn't parse Assembly Analzyzer results (GrokAssembly)", saxe);
|
throw new AnalysisException("Couldn't parse Assembly Analyzer results (GrokAssembly)", saxe);
|
||||||
} catch (XPathExpressionException xpe) {
|
|
||||||
// This shouldn't happen
|
|
||||||
throw new AnalysisException(xpe);
|
|
||||||
}
|
}
|
||||||
|
// This shouldn't happen
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -199,46 +199,27 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
@Override
|
@Override
|
||||||
public void initializeFileTypeAnalyzer() throws InitializationException {
|
public void initializeFileTypeAnalyzer() throws InitializationException {
|
||||||
final File tempFile;
|
final File tempFile;
|
||||||
|
final String cfg;
|
||||||
try {
|
try {
|
||||||
tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory());
|
tempFile = File.createTempFile("GKA", ".exe", Settings.getTempDirectory());
|
||||||
|
cfg = tempFile.getPath() + ".config";
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
throw new InitializationException("Unable to create temporary file for the assembly analyzerr", ex);
|
throw new InitializationException("Unable to create temporary file for the assembly analyzer", ex);
|
||||||
}
|
}
|
||||||
FileOutputStream fos = null;
|
try (FileOutputStream fos = new FileOutputStream(tempFile);
|
||||||
InputStream is = null;
|
InputStream is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe");
|
||||||
try {
|
FileOutputStream fosCfg = new FileOutputStream(cfg);
|
||||||
fos = new FileOutputStream(tempFile);
|
InputStream isCfg = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe.config")) {
|
||||||
is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe");
|
|
||||||
IOUtils.copy(is, fos);
|
IOUtils.copy(is, fos);
|
||||||
|
|
||||||
grokAssemblyExe = tempFile;
|
grokAssemblyExe = tempFile;
|
||||||
LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath());
|
LOGGER.debug("Extracted GrokAssembly.exe to {}", grokAssemblyExe.getPath());
|
||||||
|
IOUtils.copy(isCfg, fosCfg);
|
||||||
String cfg = grokAssemblyExe.getPath() + ".config";
|
|
||||||
fos = new FileOutputStream(cfg);
|
|
||||||
is = AssemblyAnalyzer.class.getClassLoader().getResourceAsStream("GrokAssembly.exe.config");
|
|
||||||
IOUtils.copy(is, fos);
|
|
||||||
LOGGER.debug("Extracted GrokAssembly.exe.config to {}", cfg);
|
LOGGER.debug("Extracted GrokAssembly.exe.config to {}", cfg);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
this.setEnabled(false);
|
this.setEnabled(false);
|
||||||
LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage());
|
LOGGER.warn("Could not extract GrokAssembly.exe: {}", ioe.getMessage());
|
||||||
throw new InitializationException("Could not extract GrokAssembly.exe", ioe);
|
throw new InitializationException("Could not extract GrokAssembly.exe", ioe);
|
||||||
} finally {
|
|
||||||
if (fos != null) {
|
|
||||||
try {
|
|
||||||
fos.close();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
LOGGER.debug("Error closing output stream");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is != null) {
|
|
||||||
try {
|
|
||||||
is.close();
|
|
||||||
} catch (Throwable e) {
|
|
||||||
LOGGER.debug("Error closing input stream");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now, need to see if GrokAssembly actually runs from this location.
|
// Now, need to see if GrokAssembly actually runs from this location.
|
||||||
@@ -249,7 +230,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
//
|
//
|
||||||
// We need to create a non-fatal warning error type that will
|
// We need to create a non-fatal warning error type that will
|
||||||
// get added to the report.
|
// get added to the report.
|
||||||
//TOOD this idea needs to get replicated to the bundle audit analyzer.
|
//TODO this idea needs to get replicated to the bundle audit analyzer.
|
||||||
if (args == null) {
|
if (args == null) {
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
LOGGER.error("----------------------------------------------------");
|
LOGGER.error("----------------------------------------------------");
|
||||||
@@ -280,7 +261,7 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
} catch (InitializationException e) {
|
} catch (InitializationException e) {
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
throw e;
|
throw e;
|
||||||
} catch (Throwable e) {
|
} catch (IOException | ParserConfigurationException | SAXException | XPathExpressionException | InterruptedException e) {
|
||||||
LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n"
|
LOGGER.warn("An error occurred with the .NET AssemblyAnalyzer;\n"
|
||||||
+ "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details.");
|
+ "this can be ignored unless you are scanning .NET DLLs. Please see the log for more details.");
|
||||||
LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage());
|
LOGGER.debug("Could not execute GrokAssembly {}", e.getMessage());
|
||||||
@@ -366,10 +347,8 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
if (retCode == 0) {
|
if (retCode == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException | InterruptedException ex) {
|
||||||
LOGGER.debug("Path seach failed for " + file);
|
LOGGER.debug("Path search failed for " + file, ex);
|
||||||
} catch (InterruptedException ex) {
|
|
||||||
LOGGER.debug("Path seach failed for " + file);
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -188,6 +188,11 @@ public class CPEAnalyzer extends AbstractAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the analyzer is open.
|
||||||
|
*
|
||||||
|
* @return <code>true</code> if the analyzer is open
|
||||||
|
*/
|
||||||
public boolean isOpen() {
|
public boolean isOpen() {
|
||||||
return cpe != null && cpe.isOpen();
|
return cpe != null && cpe.isOpen();
|
||||||
}
|
}
|
||||||
@@ -203,7 +208,7 @@ public class CPEAnalyzer extends AbstractAnalyzer {
|
|||||||
* @throws ParseException is thrown when the Lucene query cannot be parsed.
|
* @throws ParseException is thrown when the Lucene query cannot be parsed.
|
||||||
*/
|
*/
|
||||||
protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
|
protected void determineCPE(Dependency dependency) throws CorruptIndexException, IOException, ParseException {
|
||||||
//TODO test dojo-war against this. we shold get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit
|
//TODO test dojo-war against this. we should get dojo-toolkit:dojo-toolkit AND dojo-toolkit:toolkit
|
||||||
String vendors = "";
|
String vendors = "";
|
||||||
String products = "";
|
String products = "";
|
||||||
for (Confidence confidence : Confidence.values()) {
|
for (Confidence confidence : Confidence.values()) {
|
||||||
@@ -291,7 +296,7 @@ public class CPEAnalyzer extends AbstractAnalyzer {
|
|||||||
protected List<IndexEntry> searchCPE(String vendor, String product,
|
protected List<IndexEntry> searchCPE(String vendor, String product,
|
||||||
Set<String> vendorWeightings, Set<String> productWeightings) {
|
Set<String> vendorWeightings, Set<String> productWeightings) {
|
||||||
|
|
||||||
final List<IndexEntry> ret = new ArrayList<IndexEntry>(MAX_QUERY_RESULTS);
|
final List<IndexEntry> ret = new ArrayList<>(MAX_QUERY_RESULTS);
|
||||||
|
|
||||||
final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
|
final String searchString = buildSearch(vendor, product, vendorWeightings, productWeightings);
|
||||||
if (searchString == null) {
|
if (searchString == null) {
|
||||||
@@ -477,7 +482,7 @@ public class CPEAnalyzer extends AbstractAnalyzer {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final String[] words = text.split("[\\s_-]");
|
final String[] words = text.split("[\\s_-]");
|
||||||
final List<String> list = new ArrayList<String>();
|
final List<String> list = new ArrayList<>();
|
||||||
String tempWord = null;
|
String tempWord = null;
|
||||||
for (String word : words) {
|
for (String word : words) {
|
||||||
/*
|
/*
|
||||||
@@ -555,7 +560,7 @@ public class CPEAnalyzer extends AbstractAnalyzer {
|
|||||||
DependencyVersion bestGuess = new DependencyVersion("-");
|
DependencyVersion bestGuess = new DependencyVersion("-");
|
||||||
Confidence bestGuessConf = null;
|
Confidence bestGuessConf = null;
|
||||||
boolean hasBroadMatch = false;
|
boolean hasBroadMatch = false;
|
||||||
final List<IdentifierMatch> collected = new ArrayList<IdentifierMatch>();
|
final List<IdentifierMatch> collected = new ArrayList<>();
|
||||||
|
|
||||||
//TODO the following algorithm incorrectly identifies things as a lower version
|
//TODO the following algorithm incorrectly identifies things as a lower version
|
||||||
// if there lower confidence evidence when the current (highest) version number
|
// if there lower confidence evidence when the current (highest) version number
|
||||||
|
|||||||
@@ -103,14 +103,14 @@ public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
* <code>false</code>
|
* <code>false</code>
|
||||||
*/
|
*/
|
||||||
private boolean checkEnabled() {
|
private boolean checkEnabled() {
|
||||||
boolean retval = false;
|
boolean retVal = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) {
|
if (Settings.getBoolean(Settings.KEYS.ANALYZER_CENTRAL_ENABLED)) {
|
||||||
if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)
|
if (!Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_ENABLED)
|
||||||
|| NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) {
|
|| NexusAnalyzer.DEFAULT_URL.equals(Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL))) {
|
||||||
LOGGER.debug("Enabling the Central analyzer");
|
LOGGER.debug("Enabling the Central analyzer");
|
||||||
retval = true;
|
retVal = true;
|
||||||
} else {
|
} else {
|
||||||
LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer");
|
LOGGER.info("Nexus analyzer is enabled, disabling the Central Analyzer");
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ public class CentralAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
} catch (InvalidSettingException ise) {
|
} catch (InvalidSettingException ise) {
|
||||||
LOGGER.warn("Invalid setting. Disabling the Central analyzer");
|
LOGGER.warn("Invalid setting. Disabling the Central analyzer");
|
||||||
}
|
}
|
||||||
return retval;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.FileFilter;
|
import java.io.FileFilter;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
@@ -101,9 +101,7 @@ public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
FileInputStream fis = null;
|
try (FileInputStream fis = new FileInputStream(dependency.getActualFile())) {
|
||||||
try {
|
|
||||||
fis = new FileInputStream(dependency.getActualFile());
|
|
||||||
final ComposerLockParser clp = new ComposerLockParser(fis);
|
final ComposerLockParser clp = new ComposerLockParser(fis);
|
||||||
LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath());
|
LOGGER.info("Checking composer.lock file {}", dependency.getActualFilePath());
|
||||||
clp.process();
|
clp.process();
|
||||||
@@ -120,18 +118,10 @@ public class ComposerLockAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
LOGGER.info("Adding dependency {}", d);
|
LOGGER.info("Adding dependency {}", d);
|
||||||
engine.getDependencies().add(d);
|
engine.getDependencies().add(d);
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException fnfe) {
|
} catch (IOException ex) {
|
||||||
LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath());
|
LOGGER.warn("Error opening dependency {}", dependency.getActualFilePath());
|
||||||
} catch (ComposerException ce) {
|
} catch (ComposerException ce) {
|
||||||
LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce);
|
LOGGER.warn("Error parsing composer.json {}", dependency.getActualFilePath(), ce);
|
||||||
} finally {
|
|
||||||
if (fis != null) {
|
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
LOGGER.debug("Unable to close file", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
protected synchronized void analyzeDependency(Dependency ignore, Engine engine) throws AnalysisException {
|
protected synchronized void analyzeDependency(Dependency ignore, Engine engine) throws AnalysisException {
|
||||||
if (!analyzed) {
|
if (!analyzed) {
|
||||||
analyzed = true;
|
analyzed = true;
|
||||||
final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
|
final Set<Dependency> dependenciesToRemove = new HashSet<>();
|
||||||
final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
|
final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
|
||||||
//for (Dependency nextDependency : engine.getDependencies()) {
|
//for (Dependency nextDependency : engine.getDependencies()) {
|
||||||
while (mainIterator.hasNext()) {
|
while (mainIterator.hasNext()) {
|
||||||
@@ -499,7 +499,7 @@ public class DependencyBundlingAnalyzer extends AbstractAnalyzer {
|
|||||||
* @return true if the path contains '.war\' or '.ear\'.
|
* @return true if the path contains '.war\' or '.ear\'.
|
||||||
*/
|
*/
|
||||||
private boolean containedInWar(String filePath) {
|
private boolean containedInWar(String filePath) {
|
||||||
return filePath == null ? false : filePath.matches(".*\\.(ear|war)[\\\\/].*");
|
return filePath != null && filePath.matches(".*\\.(ear|war)[\\\\/].*");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,7 @@ public class DependencyMergingAnalyzer extends AbstractAnalyzer {
|
|||||||
protected synchronized void analyzeDependency(Dependency ignore, Engine engine) throws AnalysisException {
|
protected synchronized void analyzeDependency(Dependency ignore, Engine engine) throws AnalysisException {
|
||||||
if (!analyzed) {
|
if (!analyzed) {
|
||||||
analyzed = true;
|
analyzed = true;
|
||||||
final Set<Dependency> dependenciesToRemove = new HashSet<Dependency>();
|
final Set<Dependency> dependenciesToRemove = new HashSet<>();
|
||||||
final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
|
final ListIterator<Dependency> mainIterator = engine.getDependencies().listIterator();
|
||||||
//for (Dependency nextDependency : engine.getDependencies()) {
|
//for (Dependency nextDependency : engine.getDependencies()) {
|
||||||
while (mainIterator.hasNext()) {
|
while (mainIterator.hasNext()) {
|
||||||
@@ -138,7 +138,7 @@ public class DependencyMergingAnalyzer extends AbstractAnalyzer {
|
|||||||
final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
|
final ListIterator<Dependency> subIterator = engine.getDependencies().listIterator(mainIterator.nextIndex());
|
||||||
while (subIterator.hasNext()) {
|
while (subIterator.hasNext()) {
|
||||||
final Dependency nextDependency = subIterator.next();
|
final Dependency nextDependency = subIterator.next();
|
||||||
Dependency main = null;
|
Dependency main;
|
||||||
if ((main = getMainGemspecDependency(dependency, nextDependency)) != null) {
|
if ((main = getMainGemspecDependency(dependency, nextDependency)) != null) {
|
||||||
if (main == dependency) {
|
if (main == dependency) {
|
||||||
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
mergeDependencies(dependency, nextDependency, dependenciesToRemove);
|
||||||
|
|||||||
@@ -173,7 +173,7 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("null")
|
@SuppressWarnings("null")
|
||||||
private void removeSpuriousCPE(Dependency dependency) {
|
private void removeSpuriousCPE(Dependency dependency) {
|
||||||
final List<Identifier> ids = new ArrayList<Identifier>(dependency.getIdentifiers());
|
final List<Identifier> ids = new ArrayList<>(dependency.getIdentifiers());
|
||||||
Collections.sort(ids);
|
Collections.sort(ids);
|
||||||
final ListIterator<Identifier> mainItr = ids.listIterator();
|
final ListIterator<Identifier> mainItr = ids.listIterator();
|
||||||
while (mainItr.hasNext()) {
|
while (mainItr.hasNext()) {
|
||||||
@@ -440,34 +440,32 @@ public class FalsePositiveAnalyzer extends AbstractAnalyzer {
|
|||||||
* @param dependency the dependency that might be a duplicate
|
* @param dependency the dependency that might be a duplicate
|
||||||
* @param engine the engine used to scan all dependencies
|
* @param engine the engine used to scan all dependencies
|
||||||
*/
|
*/
|
||||||
private void removeDuplicativeEntriesFromJar(Dependency dependency, Engine engine) {
|
private synchronized void removeDuplicativeEntriesFromJar(Dependency dependency, Engine engine) {
|
||||||
if (dependency.getFileName().toLowerCase().endsWith("pom.xml")
|
if (dependency.getFileName().toLowerCase().endsWith("pom.xml")
|
||||||
|| DLL_EXE_FILTER.accept(dependency.getActualFile())) {
|
|| DLL_EXE_FILTER.accept(dependency.getActualFile())) {
|
||||||
String parentPath = dependency.getFilePath().toLowerCase();
|
String parentPath = dependency.getFilePath().toLowerCase();
|
||||||
if (parentPath.contains(".jar")) {
|
if (parentPath.contains(".jar")) {
|
||||||
parentPath = parentPath.substring(0, parentPath.indexOf(".jar") + 4);
|
parentPath = parentPath.substring(0, parentPath.indexOf(".jar") + 4);
|
||||||
final List<Dependency> dependencies = engine.getDependencies();
|
final List<Dependency> dependencies = engine.getDependencies();
|
||||||
synchronized (dependencies) {
|
final Dependency parent = findDependency(parentPath, dependencies);
|
||||||
final Dependency parent = findDependency(parentPath, dependencies);
|
if (parent != null) {
|
||||||
if (parent != null) {
|
boolean remove = false;
|
||||||
boolean remove = false;
|
for (Identifier i : dependency.getIdentifiers()) {
|
||||||
for (Identifier i : dependency.getIdentifiers()) {
|
if ("cpe".equals(i.getType())) {
|
||||||
if ("cpe".equals(i.getType())) {
|
final String trimmedCPE = trimCpeToVendor(i.getValue());
|
||||||
final String trimmedCPE = trimCpeToVendor(i.getValue());
|
for (Identifier parentId : parent.getIdentifiers()) {
|
||||||
for (Identifier parentId : parent.getIdentifiers()) {
|
if ("cpe".equals(parentId.getType()) && parentId.getValue().startsWith(trimmedCPE)) {
|
||||||
if ("cpe".equals(parentId.getType()) && parentId.getValue().startsWith(trimmedCPE)) {
|
remove |= true;
|
||||||
remove |= true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!remove) { //we can escape early
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (remove) {
|
if (!remove) { //we can escape early
|
||||||
dependencies.remove(dependency);
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (remove) {
|
||||||
|
dependencies.remove(dependency);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ import org.xml.sax.SAXException;
|
|||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class HintAnalyzer extends AbstractAnalyzer {
|
public class HintAnalyzer extends AbstractAnalyzer {
|
||||||
/**
|
|
||||||
|
/**
|
||||||
* The Logger for use throughout the class
|
* The Logger for use throughout the class
|
||||||
*/
|
*/
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(HintAnalyzer.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(HintAnalyzer.class);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import java.io.InputStreamReader;
|
|||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -254,28 +255,12 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
* @return whether or not evidence was added to the dependency
|
* @return whether or not evidence was added to the dependency
|
||||||
*/
|
*/
|
||||||
protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException {
|
protected boolean analyzePOM(Dependency dependency, List<ClassNameInformation> classes, Engine engine) throws AnalysisException {
|
||||||
JarFile jar = null;
|
try (JarFile jar = new JarFile(dependency.getActualFilePath())) {
|
||||||
List<String> pomEntries = null;
|
final List<String> pomEntries = retrievePomListing(jar);
|
||||||
try {
|
if (pomEntries != null && pomEntries.size() <= 1) {
|
||||||
jar = new JarFile(dependency.getActualFilePath());
|
String path;
|
||||||
pomEntries = retrievePomListing(jar);
|
File pomFile;
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath());
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
if (jar != null) {
|
|
||||||
try {
|
|
||||||
jar.close();
|
|
||||||
} catch (IOException ex1) {
|
|
||||||
LOGGER.trace("", ex1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (pomEntries != null && pomEntries.size() <= 1) {
|
|
||||||
try {
|
|
||||||
String path = null;
|
|
||||||
Properties pomProperties = null;
|
Properties pomProperties = null;
|
||||||
File pomFile = null;
|
|
||||||
if (pomEntries.size() == 1) {
|
if (pomEntries.size() == 1) {
|
||||||
path = pomEntries.get(0);
|
path = pomEntries.get(0);
|
||||||
pomFile = extractPom(path, jar);
|
pomFile = extractPom(path, jar);
|
||||||
@@ -289,55 +274,44 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
if (pom != null && pomProperties != null) {
|
if (pom != null && pomProperties != null) {
|
||||||
pom.processProperties(pomProperties);
|
pom.processProperties(pomProperties);
|
||||||
}
|
}
|
||||||
if (pom != null) {
|
return pom != null && setPomEvidence(dependency, pom, classes);
|
||||||
return setPomEvidence(dependency, pom, classes);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} finally {
|
}
|
||||||
|
|
||||||
|
//reported possible null dereference on pomEntries is on a non-feasible path
|
||||||
|
for (String path : pomEntries) {
|
||||||
|
//TODO - one of these is likely the pom for the main JAR we are analyzing
|
||||||
|
LOGGER.debug("Reading pom entry: {}", path);
|
||||||
try {
|
try {
|
||||||
jar.close();
|
//extract POM to its own directory and add it as its own dependency
|
||||||
} catch (IOException ex) {
|
final Properties pomProperties = retrievePomProperties(path, jar);
|
||||||
|
final File pomFile = extractPom(path, jar);
|
||||||
|
final Model pom = PomUtils.readPom(pomFile);
|
||||||
|
pom.processProperties(pomProperties);
|
||||||
|
|
||||||
|
final String displayPath = String.format("%s%s%s",
|
||||||
|
dependency.getFilePath(),
|
||||||
|
File.separator,
|
||||||
|
path);
|
||||||
|
final String displayName = String.format("%s%s%s",
|
||||||
|
dependency.getFileName(),
|
||||||
|
File.separator,
|
||||||
|
path);
|
||||||
|
final Dependency newDependency = new Dependency();
|
||||||
|
newDependency.setActualFilePath(pomFile.getAbsolutePath());
|
||||||
|
newDependency.setFileName(displayName);
|
||||||
|
newDependency.setFilePath(displayPath);
|
||||||
|
setPomEvidence(newDependency, pom, null);
|
||||||
|
engine.getDependencies().add(newDependency);
|
||||||
|
} catch (AnalysisException ex) {
|
||||||
|
LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath());
|
||||||
LOGGER.trace("", ex);
|
LOGGER.trace("", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//reported possible null dereference on pomEntries is on a non-feasible path
|
|
||||||
for (String path : pomEntries) {
|
|
||||||
//TODO - one of these is likely the pom for the main JAR we are analyzing
|
|
||||||
LOGGER.debug("Reading pom entry: {}", path);
|
|
||||||
try {
|
|
||||||
//extract POM to its own directory and add it as its own dependency
|
|
||||||
final Properties pomProperties = retrievePomProperties(path, jar);
|
|
||||||
final File pomFile = extractPom(path, jar);
|
|
||||||
final Model pom = PomUtils.readPom(pomFile);
|
|
||||||
pom.processProperties(pomProperties);
|
|
||||||
|
|
||||||
final String displayPath = String.format("%s%s%s",
|
|
||||||
dependency.getFilePath(),
|
|
||||||
File.separator,
|
|
||||||
path);
|
|
||||||
final String displayName = String.format("%s%s%s",
|
|
||||||
dependency.getFileName(),
|
|
||||||
File.separator,
|
|
||||||
path);
|
|
||||||
final Dependency newDependency = new Dependency();
|
|
||||||
newDependency.setActualFilePath(pomFile.getAbsolutePath());
|
|
||||||
newDependency.setFileName(displayName);
|
|
||||||
newDependency.setFilePath(displayPath);
|
|
||||||
setPomEvidence(newDependency, pom, null);
|
|
||||||
engine.getDependencies().add(newDependency);
|
|
||||||
} catch (AnalysisException ex) {
|
|
||||||
LOGGER.warn("An error occurred while analyzing '{}'.", dependency.getActualFilePath());
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
jar.close();
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
LOGGER.warn("Unable to read JarFile '{}'.", dependency.getActualFilePath());
|
||||||
LOGGER.trace("", ex);
|
LOGGER.trace("", ex);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -350,17 +324,13 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
* @param path the path to the pom.xml within the JarFile
|
* @param path the path to the pom.xml within the JarFile
|
||||||
* @param jar the JarFile to load the pom.properties from
|
* @param jar the JarFile to load the pom.properties from
|
||||||
* @return a Properties object or null if no pom.properties was found
|
* @return a Properties object or null if no pom.properties was found
|
||||||
* @throws IOException thrown if there is an exception reading the
|
|
||||||
* pom.properties
|
|
||||||
*/
|
*/
|
||||||
private Properties retrievePomProperties(String path, final JarFile jar) {
|
private Properties retrievePomProperties(String path, final JarFile jar) {
|
||||||
Properties pomProperties = null;
|
Properties pomProperties = null;
|
||||||
final String propPath = path.substring(0, path.length() - 7) + "pom.properies";
|
final String propPath = path.substring(0, path.length() - 7) + "pom.properies";
|
||||||
final ZipEntry propEntry = jar.getEntry(propPath);
|
final ZipEntry propEntry = jar.getEntry(propPath);
|
||||||
if (propEntry != null) {
|
if (propEntry != null) {
|
||||||
Reader reader = null;
|
try (Reader reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8")) {
|
||||||
try {
|
|
||||||
reader = new InputStreamReader(jar.getInputStream(propEntry), "UTF-8");
|
|
||||||
pomProperties = new Properties();
|
pomProperties = new Properties();
|
||||||
pomProperties.load(reader);
|
pomProperties.load(reader);
|
||||||
LOGGER.debug("Read pom.properties: {}", propPath);
|
LOGGER.debug("Read pom.properties: {}", propPath);
|
||||||
@@ -368,14 +338,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
LOGGER.trace("UTF-8 is not supported", ex);
|
LOGGER.trace("UTF-8 is not supported", ex);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.trace("Unable to read the POM properties", ex);
|
LOGGER.trace("Unable to read the POM properties", ex);
|
||||||
} finally {
|
|
||||||
if (reader != null) {
|
|
||||||
try {
|
|
||||||
reader.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("close error", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return pomProperties;
|
return pomProperties;
|
||||||
@@ -413,24 +375,18 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
* the file
|
* the file
|
||||||
*/
|
*/
|
||||||
private File extractPom(String path, JarFile jar) throws AnalysisException {
|
private File extractPom(String path, JarFile jar) throws AnalysisException {
|
||||||
InputStream input = null;
|
|
||||||
FileOutputStream fos = null;
|
|
||||||
final File tmpDir = getNextTempDirectory();
|
final File tmpDir = getNextTempDirectory();
|
||||||
final File file = new File(tmpDir, "pom.xml");
|
final File file = new File(tmpDir, "pom.xml");
|
||||||
try {
|
final ZipEntry entry = jar.getEntry(path);
|
||||||
final ZipEntry entry = jar.getEntry(path);
|
if (entry == null) {
|
||||||
if (entry == null) {
|
throw new AnalysisException(String.format("Pom (%s) does not exist in %s", path, jar.getName()));
|
||||||
throw new AnalysisException(String.format("Pom (%s)does not exist in %s", path, jar.getName()));
|
}
|
||||||
}
|
try (InputStream input = jar.getInputStream(entry);
|
||||||
input = jar.getInputStream(entry);
|
FileOutputStream fos = new FileOutputStream(file)) {
|
||||||
fos = new FileOutputStream(file);
|
|
||||||
IOUtils.copy(input, fos);
|
IOUtils.copy(input, fos);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.warn("An error occurred reading '{}' from '{}'.", path, jar.getName());
|
LOGGER.warn("An error occurred reading '{}' from '{}'.", path, jar.getName());
|
||||||
LOGGER.error("", ex);
|
LOGGER.error("", ex);
|
||||||
} finally {
|
|
||||||
FileUtils.close(fos);
|
|
||||||
FileUtils.close(input);
|
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
@@ -446,11 +402,11 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
* otherwise false
|
* otherwise false
|
||||||
*/
|
*/
|
||||||
public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) {
|
public static boolean setPomEvidence(Dependency dependency, Model pom, List<ClassNameInformation> classes) {
|
||||||
|
if (pom == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
boolean foundSomething = false;
|
boolean foundSomething = false;
|
||||||
boolean addAsIdentifier = true;
|
boolean addAsIdentifier = true;
|
||||||
if (pom == null) {
|
|
||||||
return foundSomething;
|
|
||||||
}
|
|
||||||
String groupid = pom.getGroupId();
|
String groupid = pom.getGroupId();
|
||||||
String parentGroupId = pom.getParentGroupId();
|
String parentGroupId = pom.getParentGroupId();
|
||||||
String artifactid = pom.getArtifactId();
|
String artifactid = pom.getArtifactId();
|
||||||
@@ -636,9 +592,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation)
|
protected boolean parseManifest(Dependency dependency, List<ClassNameInformation> classInformation)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
boolean foundSomething = false;
|
boolean foundSomething = false;
|
||||||
JarFile jar = null;
|
try (JarFile jar = new JarFile(dependency.getActualFilePath())) {
|
||||||
try {
|
|
||||||
jar = new JarFile(dependency.getActualFilePath());
|
|
||||||
final Manifest manifest = jar.getManifest();
|
final Manifest manifest = jar.getManifest();
|
||||||
if (manifest == null) {
|
if (manifest == null) {
|
||||||
if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar")
|
if (!dependency.getFileName().toLowerCase().endsWith("-sources.jar")
|
||||||
@@ -793,10 +747,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
foundSomething = true;
|
foundSomething = true;
|
||||||
versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH);
|
versionEvidence.addEvidence(source, "specification-version", specificationVersion, Confidence.HIGH);
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
if (jar != null) {
|
|
||||||
jar.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return foundSomething;
|
return foundSomething;
|
||||||
}
|
}
|
||||||
@@ -950,9 +900,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private List<ClassNameInformation> collectClassNames(Dependency dependency) {
|
private List<ClassNameInformation> collectClassNames(Dependency dependency) {
|
||||||
final List<ClassNameInformation> classNames = new ArrayList<>();
|
final List<ClassNameInformation> classNames = new ArrayList<>();
|
||||||
JarFile jar = null;
|
try (JarFile jar = new JarFile(dependency.getActualFilePath())) {
|
||||||
try {
|
|
||||||
jar = new JarFile(dependency.getActualFilePath());
|
|
||||||
final Enumeration<JarEntry> entries = jar.entries();
|
final Enumeration<JarEntry> entries = jar.entries();
|
||||||
while (entries.hasMoreElements()) {
|
while (entries.hasMoreElements()) {
|
||||||
final JarEntry entry = entries.nextElement();
|
final JarEntry entry = entries.nextElement();
|
||||||
@@ -966,14 +914,6 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName());
|
LOGGER.warn("Unable to open jar file '{}'.", dependency.getFileName());
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
} finally {
|
|
||||||
if (jar != null) {
|
|
||||||
try {
|
|
||||||
jar.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return classNames;
|
return classNames;
|
||||||
}
|
}
|
||||||
@@ -1124,7 +1064,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
* Up to the first four levels of the package structure, excluding a
|
* Up to the first four levels of the package structure, excluding a
|
||||||
* leading "org" or "com".
|
* leading "org" or "com".
|
||||||
*/
|
*/
|
||||||
private final ArrayList<String> packageStructure = new ArrayList<String>();
|
private final ArrayList<String> packageStructure = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -1133,7 +1073,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
* package structure. Up to the first four levels of the package
|
* package structure. Up to the first four levels of the package
|
||||||
* structure are stored, excluding a leading "org" or "com".
|
* structure are stored, excluding a leading "org" or "com".
|
||||||
* Example:</p>
|
* Example:</p>
|
||||||
* <code>ClassNameInformation obj = new ClassNameInformation("org.owasp.dependencycheck.analyzer.JarAnalyzer");
|
* <code>ClassNameInformation obj = new ClassNameInformation("org/owasp/dependencycheck/analyzer/JarAnalyzer");
|
||||||
* System.out.println(obj.getName());
|
* System.out.println(obj.getName());
|
||||||
* for (String p : obj.getPackageStructure())
|
* for (String p : obj.getPackageStructure())
|
||||||
* System.out.println(p);
|
* System.out.println(p);
|
||||||
@@ -1161,9 +1101,7 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
if (tmp.length <= end) {
|
if (tmp.length <= end) {
|
||||||
end = tmp.length - 1;
|
end = tmp.length - 1;
|
||||||
}
|
}
|
||||||
for (int i = start; i <= end; i++) {
|
packageStructure.addAll(Arrays.asList(tmp).subList(start, end + 1));
|
||||||
packageStructure.add(tmp[i]);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
packageStructure.add(name);
|
packageStructure.add(name);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -87,10 +87,6 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
*/
|
*/
|
||||||
private static final String SUPPORTED_EXTENSIONS = "jar";
|
private static final String SUPPORTED_EXTENSIONS = "jar";
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether or not the Nexus analyzer should use a proxy if configured.
|
|
||||||
*/
|
|
||||||
private boolean useProxy;
|
|
||||||
/**
|
/**
|
||||||
* The Nexus Search to be set up for this analyzer.
|
* The Nexus Search to be set up for this analyzer.
|
||||||
*/
|
*/
|
||||||
@@ -148,7 +144,7 @@ public class NexusAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
LOGGER.debug("Initializing Nexus Analyzer");
|
LOGGER.debug("Initializing Nexus Analyzer");
|
||||||
LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled());
|
LOGGER.debug("Nexus Analyzer enabled: {}", isEnabled());
|
||||||
if (isEnabled()) {
|
if (isEnabled()) {
|
||||||
useProxy = useProxy();
|
final boolean useProxy = useProxy();
|
||||||
final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL);
|
final String searchUrl = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_URL);
|
||||||
LOGGER.debug("Nexus Analyzer URL: {}", searchUrl);
|
LOGGER.debug("Nexus Analyzer URL: {}", searchUrl);
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -121,17 +121,9 @@ public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void analyzeDependency(Dependency dependency, Engine engine)
|
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
throws AnalysisException {
|
|
||||||
final File file = dependency.getActualFile();
|
final File file = dependency.getActualFile();
|
||||||
JsonReader jsonReader;
|
try (JsonReader jsonReader = Json.createReader(FileUtils.openInputStream(file))) {
|
||||||
try {
|
|
||||||
jsonReader = Json.createReader(FileUtils.openInputStream(file));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new AnalysisException(
|
|
||||||
"Problem occurred while reading dependency file.", e);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
final JsonObject json = jsonReader.readObject();
|
final JsonObject json = jsonReader.readObject();
|
||||||
final EvidenceCollection productEvidence = dependency.getProductEvidence();
|
final EvidenceCollection productEvidence = dependency.getProductEvidence();
|
||||||
final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
|
final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
|
||||||
@@ -151,8 +143,8 @@ public class NodePackageAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName()));
|
dependency.setDisplayFileName(String.format("%s/%s", file.getParentFile().getName(), file.getName()));
|
||||||
} catch (JsonException e) {
|
} catch (JsonException e) {
|
||||||
LOGGER.warn("Failed to parse package.json file.", e);
|
LOGGER.warn("Failed to parse package.json file.", e);
|
||||||
} finally {
|
} catch (IOException e) {
|
||||||
jsonReader.close();
|
throw new AnalysisException("Problem occurred while reading dependency file.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import org.slf4j.LoggerFactory;
|
|||||||
import java.io.FileFilter;
|
import java.io.FileFilter;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
|
||||||
import org.owasp.dependencycheck.exception.InitializationException;
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -132,22 +131,10 @@ public class NuspecAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
try {
|
try {
|
||||||
final NuspecParser parser = new XPathNuspecParser();
|
final NuspecParser parser = new XPathNuspecParser();
|
||||||
NugetPackage np = null;
|
NugetPackage np = null;
|
||||||
FileInputStream fis = null;
|
try (FileInputStream fis = new FileInputStream(dependency.getActualFilePath())) {
|
||||||
try {
|
|
||||||
fis = new FileInputStream(dependency.getActualFilePath());
|
|
||||||
np = parser.parse(fis);
|
np = parser.parse(fis);
|
||||||
} catch (NuspecParseException ex) {
|
} catch (NuspecParseException | FileNotFoundException ex) {
|
||||||
throw new AnalysisException(ex);
|
throw new AnalysisException(ex);
|
||||||
} catch (FileNotFoundException ex) {
|
|
||||||
throw new AnalysisException(ex);
|
|
||||||
} finally {
|
|
||||||
if (fis != null) {
|
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
} catch (IOException e) {
|
|
||||||
LOGGER.debug("Error closing input stream");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (np.getOwners() != null) {
|
if (np.getOwners() != null) {
|
||||||
|
|||||||
@@ -360,22 +360,12 @@ public class PythonDistributionAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
if (null == manifest) {
|
if (null == manifest) {
|
||||||
LOGGER.debug("Manifest file not found.");
|
LOGGER.debug("Manifest file not found.");
|
||||||
} else {
|
} else {
|
||||||
InputStream in = null;
|
try (InputStream in = new BufferedInputStream(new FileInputStream(manifest))) {
|
||||||
try {
|
|
||||||
in = new BufferedInputStream(new FileInputStream(manifest));
|
|
||||||
result.load(in);
|
result.load(in);
|
||||||
} catch (MessagingException e) {
|
} catch (MessagingException | FileNotFoundException e) {
|
||||||
LOGGER.warn(e.getMessage(), e);
|
LOGGER.warn(e.getMessage(), e);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (IOException ex) {
|
||||||
LOGGER.warn(e.getMessage(), e);
|
LOGGER.warn(ex.getMessage(), ex);
|
||||||
} finally {
|
|
||||||
if (in != null) {
|
|
||||||
try {
|
|
||||||
in.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.debug("failed to close input stream", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
if (!folder.isDirectory()) {
|
if (!folder.isDirectory()) {
|
||||||
throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath()));
|
throw new AnalysisException(String.format("%s should have been a directory.", folder.getAbsolutePath()));
|
||||||
}
|
}
|
||||||
final List<String> args = new ArrayList<String>();
|
final List<String> args = new ArrayList<>();
|
||||||
final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH);
|
final String bundleAuditPath = Settings.getString(Settings.KEYS.ANALYZER_BUNDLE_AUDIT_PATH);
|
||||||
File bundleAudit = null;
|
File bundleAudit = null;
|
||||||
if (bundleAuditPath != null) {
|
if (bundleAuditPath != null) {
|
||||||
@@ -172,7 +172,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
exitValue = process.waitFor();
|
exitValue = process.waitFor();
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
final String msg = String.format("Bundle-audit process was interupted. Disabling %s", ANALYZER_NAME);
|
final String msg = String.format("Bundle-audit process was interrupted. Disabling %s", ANALYZER_NAME);
|
||||||
throw new InitializationException(msg);
|
throw new InitializationException(msg);
|
||||||
}
|
}
|
||||||
if (0 == exitValue) {
|
if (0 == exitValue) {
|
||||||
@@ -180,9 +180,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
final String msg = String.format("Unexpected exit code from bundle-audit process. Disabling %s: %s", ANALYZER_NAME, exitValue);
|
final String msg = String.format("Unexpected exit code from bundle-audit process. Disabling %s: %s", ANALYZER_NAME, exitValue);
|
||||||
throw new InitializationException(msg);
|
throw new InitializationException(msg);
|
||||||
} else {
|
} else {
|
||||||
BufferedReader reader = null;
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"))) {
|
||||||
try {
|
|
||||||
reader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
|
|
||||||
if (!reader.ready()) {
|
if (!reader.ready()) {
|
||||||
LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME);
|
LOGGER.warn("Bundle-audit error stream unexpectedly not ready. Disabling " + ANALYZER_NAME);
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
@@ -201,14 +199,6 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
setEnabled(false);
|
setEnabled(false);
|
||||||
throw new InitializationException("Unable to read bundle-audit output.", ex);
|
throw new InitializationException("Unable to read bundle-audit output.", ex);
|
||||||
} finally {
|
|
||||||
if (null != reader) {
|
|
||||||
try {
|
|
||||||
reader.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.debug("Error closing reader", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,35 +286,19 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
final String msg = String.format("Unexpected exit code from bundle-audit process; exit code: %s", exitValue);
|
final String msg = String.format("Unexpected exit code from bundle-audit process; exit code: %s", exitValue);
|
||||||
throw new AnalysisException(msg);
|
throw new AnalysisException(msg);
|
||||||
}
|
}
|
||||||
BufferedReader rdr = null;
|
|
||||||
BufferedReader errReader = null;
|
|
||||||
try {
|
try {
|
||||||
errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"));
|
try (BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "UTF-8"))) {
|
||||||
while (errReader.ready()) {
|
while (errReader.ready()) {
|
||||||
final String error = errReader.readLine();
|
final String error = errReader.readLine();
|
||||||
LOGGER.warn(error);
|
LOGGER.warn(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try (BufferedReader rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"))) {
|
||||||
|
processBundlerAuditOutput(dependency, engine, rdr);
|
||||||
}
|
}
|
||||||
rdr = new BufferedReader(new InputStreamReader(process.getInputStream(), "UTF-8"));
|
|
||||||
processBundlerAuditOutput(dependency, engine, rdr);
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
LOGGER.warn("bundle-audit failure", ioe);
|
LOGGER.warn("bundle-audit failure", ioe);
|
||||||
} finally {
|
|
||||||
if (errReader != null) {
|
|
||||||
try {
|
|
||||||
errReader.close();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
LOGGER.warn("bundle-audit close failure", ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (null != rdr) {
|
|
||||||
try {
|
|
||||||
rdr.close();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
LOGGER.warn("bundle-audit close failure", ioe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -342,7 +316,7 @@ public class RubyBundleAuditAnalyzer extends AbstractFileTypeAnalyzer {
|
|||||||
Dependency dependency = null;
|
Dependency dependency = null;
|
||||||
Vulnerability vulnerability = null;
|
Vulnerability vulnerability = null;
|
||||||
String gem = null;
|
String gem = null;
|
||||||
final Map<String, Dependency> map = new HashMap<String, Dependency>();
|
final Map<String, Dependency> map = new HashMap<>();
|
||||||
boolean appendToDescription = false;
|
boolean appendToDescription = false;
|
||||||
while (rdr.ready()) {
|
while (rdr.ready()) {
|
||||||
final String nextLine = rdr.readLine();
|
final String nextLine = rdr.readLine();
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
*/
|
*/
|
||||||
public class VersionFilterAnalyzer extends AbstractAnalyzer {
|
public class VersionFilterAnalyzer extends AbstractAnalyzer {
|
||||||
|
|
||||||
//<editor-fold defaultstate="collapsed" desc="Constaints">
|
//<editor-fold defaultstate="collapsed" desc="Constants">
|
||||||
/**
|
/**
|
||||||
* Evidence source.
|
* Evidence source.
|
||||||
*/
|
*/
|
||||||
@@ -126,7 +126,7 @@ public class VersionFilterAnalyzer extends AbstractAnalyzer {
|
|||||||
* the dependency.
|
* the dependency.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
protected synchronized void analyzeDependency(Dependency dependency, Engine engine) throws AnalysisException {
|
||||||
String fileVersion = null;
|
String fileVersion = null;
|
||||||
String pomVersion = null;
|
String pomVersion = null;
|
||||||
String manifestVersion = null;
|
String manifestVersion = null;
|
||||||
@@ -151,16 +151,14 @@ public class VersionFilterAnalyzer extends AbstractAnalyzer {
|
|||||||
if (fileMatch || manifestMatch || pomMatch) {
|
if (fileMatch || manifestMatch || pomMatch) {
|
||||||
LOGGER.debug("filtering evidence from {}", dependency.getFileName());
|
LOGGER.debug("filtering evidence from {}", dependency.getFileName());
|
||||||
final EvidenceCollection versionEvidence = dependency.getVersionEvidence();
|
final EvidenceCollection versionEvidence = dependency.getVersionEvidence();
|
||||||
synchronized (versionEvidence) {
|
final Iterator<Evidence> itr = versionEvidence.iterator();
|
||||||
final Iterator<Evidence> itr = versionEvidence.iterator();
|
while (itr.hasNext()) {
|
||||||
while (itr.hasNext()) {
|
final Evidence e = itr.next();
|
||||||
final Evidence e = itr.next();
|
if (!(pomMatch && VERSION.equals(e.getName())
|
||||||
if (!(pomMatch && VERSION.equals(e.getName())
|
&& (NEXUS.equals(e.getSource()) || CENTRAL.equals(e.getSource()) || POM.equals(e.getSource())))
|
||||||
&& (NEXUS.equals(e.getSource()) || CENTRAL.equals(e.getSource()) || POM.equals(e.getSource())))
|
&& !(fileMatch && VERSION.equals(e.getName()) && FILE.equals(e.getSource()))
|
||||||
&& !(fileMatch && VERSION.equals(e.getName()) && FILE.equals(e.getSource()))
|
&& !(manifestMatch && MANIFEST.equals(e.getSource()) && IMPLEMENTATION_VERSION.equals(e.getName()))) {
|
||||||
&& !(manifestMatch && MANIFEST.equals(e.getSource()) && IMPLEMENTATION_VERSION.equals(e.getName()))) {
|
itr.remove();
|
||||||
itr.remove();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,8 +24,10 @@ import java.net.URL;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.xpath.XPath;
|
import javax.xml.xpath.XPath;
|
||||||
import javax.xml.xpath.XPathConstants;
|
import javax.xml.xpath.XPathConstants;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
import javax.xml.xpath.XPathFactory;
|
import javax.xml.xpath.XPathFactory;
|
||||||
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
import org.owasp.dependencycheck.data.nexus.MavenArtifact;
|
||||||
import org.owasp.dependencycheck.utils.Settings;
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
@@ -35,6 +37,7 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.NodeList;
|
import org.w3c.dom.NodeList;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class of methods to search Maven Central via Central.
|
* Class of methods to search Maven Central via Central.
|
||||||
@@ -117,7 +120,7 @@ public class CentralSearch {
|
|||||||
if ("0".equals(numFound)) {
|
if ("0".equals(numFound)) {
|
||||||
missing = true;
|
missing = true;
|
||||||
} else {
|
} else {
|
||||||
result = new ArrayList<MavenArtifact>();
|
result = new ArrayList<>();
|
||||||
final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
|
final NodeList docs = (NodeList) xpath.evaluate("/response/result/doc", doc, XPathConstants.NODESET);
|
||||||
for (int i = 0; i < docs.getLength(); i++) {
|
for (int i = 0; i < docs.getLength(); i++) {
|
||||||
final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
|
final String g = xpath.evaluate("./str[@name='g']", docs.item(i));
|
||||||
@@ -125,11 +128,11 @@ public class CentralSearch {
|
|||||||
final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
|
final String a = xpath.evaluate("./str[@name='a']", docs.item(i));
|
||||||
LOGGER.trace("ArtifactId: {}", a);
|
LOGGER.trace("ArtifactId: {}", a);
|
||||||
final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
|
final String v = xpath.evaluate("./str[@name='v']", docs.item(i));
|
||||||
NodeList atts = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET);
|
NodeList attributes = (NodeList) xpath.evaluate("./arr[@name='ec']/str", docs.item(i), XPathConstants.NODESET);
|
||||||
boolean pomAvailable = false;
|
boolean pomAvailable = false;
|
||||||
boolean jarAvailable = false;
|
boolean jarAvailable = false;
|
||||||
for (int x = 0; x < atts.getLength(); x++) {
|
for (int x = 0; x < attributes.getLength(); x++) {
|
||||||
final String tmp = xpath.evaluate(".", atts.item(x));
|
final String tmp = xpath.evaluate(".", attributes.item(x));
|
||||||
if (".pom".equals(tmp)) {
|
if (".pom".equals(tmp)) {
|
||||||
pomAvailable = true;
|
pomAvailable = true;
|
||||||
} else if (".jar".equals(tmp)) {
|
} else if (".jar".equals(tmp)) {
|
||||||
@@ -137,10 +140,10 @@ public class CentralSearch {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
atts = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET);
|
attributes = (NodeList) xpath.evaluate("./arr[@name='tags']/str", docs.item(i), XPathConstants.NODESET);
|
||||||
boolean useHTTPS = false;
|
boolean useHTTPS = false;
|
||||||
for (int x = 0; x < atts.getLength(); x++) {
|
for (int x = 0; x < attributes.getLength(); x++) {
|
||||||
final String tmp = xpath.evaluate(".", atts.item(x));
|
final String tmp = xpath.evaluate(".", attributes.item(x));
|
||||||
if ("https".equals(tmp)) {
|
if ("https".equals(tmp)) {
|
||||||
useHTTPS = true;
|
useHTTPS = true;
|
||||||
}
|
}
|
||||||
@@ -149,7 +152,7 @@ public class CentralSearch {
|
|||||||
result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS));
|
result.add(new MavenArtifact(g, a, v, jarAvailable, pomAvailable, useHTTPS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (ParserConfigurationException | IOException | SAXException | XPathExpressionException e) {
|
||||||
// Anything else is jacked up XML stuff that we really can't recover from well
|
// Anything else is jacked up XML stuff that we really can't recover from well
|
||||||
throw new IOException(e.getMessage(), e);
|
throw new IOException(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
package org.owasp.dependencycheck.data.composer;
|
package org.owasp.dependencycheck.data.composer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reperesents a dependency (GAV, right now) from a Composer dependency.
|
* Represents a dependency (GAV, right now) from a Composer dependency.
|
||||||
*
|
*
|
||||||
* @author colezlaw
|
* @author colezlaw
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -42,11 +42,6 @@ public class ComposerLockParser {
|
|||||||
*/
|
*/
|
||||||
private final JsonReader jsonReader;
|
private final JsonReader jsonReader;
|
||||||
|
|
||||||
/**
|
|
||||||
* The input stream we'll read
|
|
||||||
*/
|
|
||||||
private final InputStream inputStream; // NOPMD - it gets set in the constructor, read later
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The List of ComposerDependencies found
|
* The List of ComposerDependencies found
|
||||||
*/
|
*/
|
||||||
@@ -58,15 +53,14 @@ public class ComposerLockParser {
|
|||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockParser.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(ComposerLockParser.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Createas a ComposerLockParser from a JsonReader and an InputStream.
|
* Creates a ComposerLockParser from a JsonReader and an InputStream.
|
||||||
*
|
*
|
||||||
* @param inputStream the InputStream to parse
|
* @param inputStream the InputStream to parse
|
||||||
*/
|
*/
|
||||||
public ComposerLockParser(InputStream inputStream) {
|
public ComposerLockParser(InputStream inputStream) {
|
||||||
LOGGER.info("Creating a ComposerLockParser");
|
LOGGER.info("Creating a ComposerLockParser");
|
||||||
this.inputStream = inputStream;
|
|
||||||
this.jsonReader = Json.createReader(inputStream);
|
this.jsonReader = Json.createReader(inputStream);
|
||||||
this.composerDependencies = new ArrayList<ComposerDependency>();
|
this.composerDependencies = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -87,7 +81,7 @@ public class ComposerLockParser {
|
|||||||
final String group = groupName.substring(0, groupName.indexOf('/'));
|
final String group = groupName.substring(0, groupName.indexOf('/'));
|
||||||
final String project = groupName.substring(groupName.indexOf('/') + 1);
|
final String project = groupName.substring(groupName.indexOf('/') + 1);
|
||||||
String version = pkg.getString("version");
|
String version = pkg.getString("version");
|
||||||
// Some version nubmers begin with v - which doesn't end up matching CPE's
|
// Some version numbers begin with v - which doesn't end up matching CPE's
|
||||||
if (version.startsWith("v")) {
|
if (version.startsWith("v")) {
|
||||||
version = version.substring(1);
|
version = version.substring(1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ public final class CpeMemoryIndex {
|
|||||||
* @return the CPE Analyzer.
|
* @return the CPE Analyzer.
|
||||||
*/
|
*/
|
||||||
private Analyzer createSearchingAnalyzer() {
|
private Analyzer createSearchingAnalyzer() {
|
||||||
final Map<String, Analyzer> fieldAnalyzers = new HashMap<String, Analyzer>();
|
final Map<String, Analyzer> fieldAnalyzers = new HashMap<>();
|
||||||
fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
|
fieldAnalyzers.put(Fields.DOCUMENT_KEY, new KeywordAnalyzer());
|
||||||
productFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
|
productFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
|
||||||
vendorFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
|
vendorFieldAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
|
||||||
@@ -191,57 +191,35 @@ public final class CpeMemoryIndex {
|
|||||||
* @throws IndexException thrown if there is an issue creating the index
|
* @throws IndexException thrown if there is an issue creating the index
|
||||||
*/
|
*/
|
||||||
private void buildIndex(CveDB cve) throws IndexException {
|
private void buildIndex(CveDB cve) throws IndexException {
|
||||||
Analyzer analyzer = null;
|
try (Analyzer analyzer = createSearchingAnalyzer();
|
||||||
IndexWriter indexWriter = null;
|
IndexWriter indexWriter = new IndexWriter(index, new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer))) {
|
||||||
try {
|
// Tip: reuse the Document and Fields for performance...
|
||||||
analyzer = createSearchingAnalyzer();
|
// See "Re-use Document and Field instances" from
|
||||||
final IndexWriterConfig conf = new IndexWriterConfig(LuceneUtils.CURRENT_VERSION, analyzer);
|
// http://wiki.apache.org/lucene-java/ImproveIndexingSpeed
|
||||||
indexWriter = new IndexWriter(index, conf);
|
final Document doc = new Document();
|
||||||
try {
|
final Field v = new TextField(Fields.VENDOR, Fields.VENDOR, Field.Store.YES);
|
||||||
// Tip: reuse the Document and Fields for performance...
|
final Field p = new TextField(Fields.PRODUCT, Fields.PRODUCT, Field.Store.YES);
|
||||||
// See "Re-use Document and Field instances" from
|
doc.add(v);
|
||||||
// http://wiki.apache.org/lucene-java/ImproveIndexingSpeed
|
doc.add(p);
|
||||||
final Document doc = new Document();
|
|
||||||
final Field v = new TextField(Fields.VENDOR, Fields.VENDOR, Field.Store.YES);
|
|
||||||
final Field p = new TextField(Fields.PRODUCT, Fields.PRODUCT, Field.Store.YES);
|
|
||||||
doc.add(v);
|
|
||||||
doc.add(p);
|
|
||||||
|
|
||||||
final Set<Pair<String, String>> data = cve.getVendorProductList();
|
final Set<Pair<String, String>> data = cve.getVendorProductList();
|
||||||
for (Pair<String, String> pair : data) {
|
for (Pair<String, String> pair : data) {
|
||||||
//todo figure out why there are null products
|
if (pair.getLeft() != null && pair.getRight() != null) {
|
||||||
if (pair.getLeft() != null && pair.getRight() != null) {
|
v.setStringValue(pair.getLeft());
|
||||||
v.setStringValue(pair.getLeft());
|
p.setStringValue(pair.getRight());
|
||||||
p.setStringValue(pair.getRight());
|
indexWriter.addDocument(doc);
|
||||||
indexWriter.addDocument(doc);
|
resetFieldAnalyzer();
|
||||||
resetFieldAnalyzer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (DatabaseException ex) {
|
|
||||||
LOGGER.debug("", ex);
|
|
||||||
throw new IndexException("Error reading CPE data", ex);
|
|
||||||
}
|
}
|
||||||
|
indexWriter.commit();
|
||||||
|
indexWriter.close(true);
|
||||||
|
} catch (DatabaseException ex) {
|
||||||
|
LOGGER.debug("", ex);
|
||||||
|
throw new IndexException("Error reading CPE data", ex);
|
||||||
} catch (CorruptIndexException ex) {
|
} catch (CorruptIndexException ex) {
|
||||||
throw new IndexException("Unable to close an in-memory index", ex);
|
throw new IndexException("Unable to close an in-memory index", ex);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new IndexException("Unable to close an in-memory index", ex);
|
throw new IndexException("Unable to close an in-memory index", ex);
|
||||||
} finally {
|
|
||||||
if (indexWriter != null) {
|
|
||||||
try {
|
|
||||||
try {
|
|
||||||
indexWriter.commit();
|
|
||||||
} finally {
|
|
||||||
indexWriter.close(true);
|
|
||||||
}
|
|
||||||
} catch (CorruptIndexException ex) {
|
|
||||||
throw new IndexException("Unable to close an in-memory index", ex);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new IndexException("Unable to close an in-memory index", ex);
|
|
||||||
}
|
|
||||||
if (analyzer != null) {
|
|
||||||
analyzer.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,12 +54,10 @@ public final class CweDB {
|
|||||||
* @return a HashMap of CWE data
|
* @return a HashMap of CWE data
|
||||||
*/
|
*/
|
||||||
private static Map<String, String> loadData() {
|
private static Map<String, String> loadData() {
|
||||||
ObjectInputStream oin = null;
|
final String filePath = "data/cwe.hashmap.serialized";
|
||||||
try {
|
try (InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
|
||||||
final String filePath = "data/cwe.hashmap.serialized";
|
ObjectInputStream oin = new ObjectInputStream(input)) {
|
||||||
final InputStream input = CweDB.class.getClassLoader().getResourceAsStream(filePath);
|
|
||||||
oin = new ObjectInputStream(input);
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
final Map<String, String> ret = (HashMap<String, String>) oin.readObject();
|
final Map<String, String> ret = (HashMap<String, String>) oin.readObject();
|
||||||
return ret;
|
return ret;
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (ClassNotFoundException ex) {
|
||||||
@@ -68,14 +66,6 @@ public final class CweDB {
|
|||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.warn("Unable to load CWE data due to an IO Error. This should not be an issue.");
|
LOGGER.warn("Unable to load CWE data due to an IO Error. This should not be an issue.");
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
} finally {
|
|
||||||
if (oin != null) {
|
|
||||||
try {
|
|
||||||
oin.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ public class CweHandler extends DefaultHandler {
|
|||||||
/**
|
/**
|
||||||
* a HashMap containing the CWE data.
|
* a HashMap containing the CWE data.
|
||||||
*/
|
*/
|
||||||
private final HashMap<String, String> cwe = new HashMap<String, String>();
|
private final HashMap<String, String> cwe = new HashMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the HashMap of CWE entries (CWE-ID, Full CWE Name).
|
* Returns the HashMap of CWE entries (CWE-ID, Full CWE Name).
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public abstract class AbstractTokenizingFilter extends TokenFilter {
|
|||||||
*/
|
*/
|
||||||
public AbstractTokenizingFilter(TokenStream stream) {
|
public AbstractTokenizingFilter(TokenStream stream) {
|
||||||
super(stream);
|
super(stream);
|
||||||
tokens = new LinkedList<String>();
|
tokens = new LinkedList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public final class TokenPairConcatenatingFilter extends TokenFilter {
|
|||||||
*/
|
*/
|
||||||
public TokenPairConcatenatingFilter(TokenStream stream) {
|
public TokenPairConcatenatingFilter(TokenStream stream) {
|
||||||
super(stream);
|
super(stream);
|
||||||
words = new LinkedList<String>();
|
words = new LinkedList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,7 +22,9 @@ import java.io.IOException;
|
|||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.xpath.XPath;
|
import javax.xml.xpath.XPath;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
import javax.xml.xpath.XPathFactory;
|
import javax.xml.xpath.XPathFactory;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.utils.URLConnectionFactory;
|
import org.owasp.dependencycheck.utils.URLConnectionFactory;
|
||||||
@@ -30,6 +32,7 @@ import org.owasp.dependencycheck.utils.XmlUtils;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class of methods to search Nexus repositories.
|
* Class of methods to search Nexus repositories.
|
||||||
@@ -132,7 +135,7 @@ public class NexusSearch {
|
|||||||
ma.setPomUrl(pomLink);
|
ma.setPomUrl(pomLink);
|
||||||
}
|
}
|
||||||
return ma;
|
return ma;
|
||||||
} catch (Throwable e) {
|
} catch (ParserConfigurationException | IOException | SAXException | XPathExpressionException e) {
|
||||||
// Anything else is jacked-up XML stuff that we really can't recover
|
// Anything else is jacked-up XML stuff that we really can't recover
|
||||||
// from well
|
// from well
|
||||||
throw new IOException(e.getMessage(), e);
|
throw new IOException(e.getMessage(), e);
|
||||||
@@ -170,7 +173,7 @@ public class NexusSearch {
|
|||||||
LOGGER.warn("Expected root node name of status, got {}", doc.getDocumentElement().getNodeName());
|
LOGGER.warn("Expected root node name of status, got {}", doc.getDocumentElement().getNodeName());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (IOException | ParserConfigurationException | SAXException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,14 +17,18 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.data.nuget;
|
package org.owasp.dependencycheck.data.nuget;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.xpath.XPath;
|
import javax.xml.xpath.XPath;
|
||||||
import javax.xml.xpath.XPathConstants;
|
import javax.xml.xpath.XPathConstants;
|
||||||
|
import javax.xml.xpath.XPathExpressionException;
|
||||||
import javax.xml.xpath.XPathFactory;
|
import javax.xml.xpath.XPathFactory;
|
||||||
import org.owasp.dependencycheck.utils.XmlUtils;
|
import org.owasp.dependencycheck.utils.XmlUtils;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
import org.w3c.dom.Node;
|
import org.w3c.dom.Node;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a Nuspec file using XPath.
|
* Parse a Nuspec file using XPath.
|
||||||
@@ -78,7 +82,7 @@ public class XPathNuspecParser implements NuspecParser {
|
|||||||
nuspec.setLicenseUrl(getOrNull((Node) xpath.evaluate("/package/metadata/licenseUrl", d, XPathConstants.NODE)));
|
nuspec.setLicenseUrl(getOrNull((Node) xpath.evaluate("/package/metadata/licenseUrl", d, XPathConstants.NODE)));
|
||||||
nuspec.setTitle(getOrNull((Node) xpath.evaluate("/package/metadata/title", d, XPathConstants.NODE)));
|
nuspec.setTitle(getOrNull((Node) xpath.evaluate("/package/metadata/title", d, XPathConstants.NODE)));
|
||||||
return nuspec;
|
return nuspec;
|
||||||
} catch (Throwable e) {
|
} catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException | NuspecParseException e) {
|
||||||
throw new NuspecParseException("Unable to parse nuspec", e);
|
throw new NuspecParseException("Unable to parse nuspec", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -342,7 +342,7 @@ public final class ConnectionFactory {
|
|||||||
LOGGER.warn("A new version of dependency-check is available; consider upgrading");
|
LOGGER.warn("A new version of dependency-check is available; consider upgrading");
|
||||||
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
Settings.setBoolean(Settings.KEYS.AUTO_UPDATE, false);
|
||||||
} else if (e0 == c0 && e1 == c1) {
|
} else if (e0 == c0 && e1 == c1) {
|
||||||
//do nothing - not sure how we got here, but just incase...
|
//do nothing - not sure how we got here, but just in case...
|
||||||
} else {
|
} else {
|
||||||
LOGGER.error("The database schema must be upgraded to use this version of dependency-check. Please see {} for more information.",
|
LOGGER.error("The database schema must be upgraded to use this version of dependency-check. Please see {} for more information.",
|
||||||
UPGRADE_HELP_URL);
|
UPGRADE_HELP_URL);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public final class CveDB {
|
|||||||
/**
|
/**
|
||||||
* Singleton instance of the CveDB.
|
* Singleton instance of the CveDB.
|
||||||
*/
|
*/
|
||||||
private static CveDB INSTANCE = null;
|
private static CveDB instance = null;
|
||||||
/**
|
/**
|
||||||
* The logger.
|
* The logger.
|
||||||
*/
|
*/
|
||||||
@@ -81,11 +81,6 @@ public final class CveDB {
|
|||||||
* table.
|
* table.
|
||||||
*/
|
*/
|
||||||
private DatabaseProperties databaseProperties;
|
private DatabaseProperties databaseProperties;
|
||||||
/**
|
|
||||||
* Does the underlying connection support batch operations? Currently we do
|
|
||||||
* not support batch execution.
|
|
||||||
*/
|
|
||||||
private final boolean batchSupported = false;
|
|
||||||
/**
|
/**
|
||||||
* The prepared statements.
|
* The prepared statements.
|
||||||
*/
|
*/
|
||||||
@@ -96,27 +91,93 @@ public final class CveDB {
|
|||||||
* statement bundles "dbStatements*.properties".
|
* statement bundles "dbStatements*.properties".
|
||||||
*/
|
*/
|
||||||
enum PreparedStatementCveDb {
|
enum PreparedStatementCveDb {
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
CLEANUP_ORPHANS,
|
CLEANUP_ORPHANS,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
COUNT_CPE,
|
COUNT_CPE,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
DELETE_REFERENCE,
|
DELETE_REFERENCE,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
DELETE_SOFTWARE,
|
DELETE_SOFTWARE,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
DELETE_VULNERABILITY,
|
DELETE_VULNERABILITY,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
INSERT_CPE,
|
INSERT_CPE,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
INSERT_PROPERTY,
|
INSERT_PROPERTY,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
INSERT_REFERENCE,
|
INSERT_REFERENCE,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
INSERT_SOFTWARE,
|
INSERT_SOFTWARE,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
INSERT_VULNERABILITY,
|
INSERT_VULNERABILITY,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
MERGE_PROPERTY,
|
MERGE_PROPERTY,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
SELECT_CPE_ENTRIES,
|
SELECT_CPE_ENTRIES,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
SELECT_CPE_ID,
|
SELECT_CPE_ID,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
SELECT_CVE_FROM_SOFTWARE,
|
SELECT_CVE_FROM_SOFTWARE,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
SELECT_PROPERTIES,
|
SELECT_PROPERTIES,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
SELECT_REFERENCES,
|
SELECT_REFERENCES,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
SELECT_SOFTWARE,
|
SELECT_SOFTWARE,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
SELECT_VENDOR_PRODUCT_LIST,
|
SELECT_VENDOR_PRODUCT_LIST,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
SELECT_VULNERABILITY,
|
SELECT_VULNERABILITY,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
SELECT_VULNERABILITY_ID,
|
SELECT_VULNERABILITY_ID,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
UPDATE_PROPERTY,
|
UPDATE_PROPERTY,
|
||||||
|
/**
|
||||||
|
* Key for SQL Statement.
|
||||||
|
*/
|
||||||
UPDATE_VULNERABILITY
|
UPDATE_VULNERABILITY
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,11 +187,11 @@ public final class CveDB {
|
|||||||
* @return the CveDB singleton
|
* @return the CveDB singleton
|
||||||
* @throws DatabaseException thrown if there is a database error
|
* @throws DatabaseException thrown if there is a database error
|
||||||
*/
|
*/
|
||||||
public synchronized static CveDB getInstance() throws DatabaseException {
|
public static synchronized CveDB getInstance() throws DatabaseException {
|
||||||
if (INSTANCE == null) {
|
if (instance == null) {
|
||||||
INSTANCE = new CveDB();
|
instance = new CveDB();
|
||||||
}
|
}
|
||||||
return INSTANCE;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -155,9 +216,9 @@ public final class CveDB {
|
|||||||
*
|
*
|
||||||
* @return the product name of the database if successful, {@code null} else
|
* @return the product name of the database if successful, {@code null} else
|
||||||
*/
|
*/
|
||||||
private String determineDatabaseProductName() {
|
private synchronized String determineDatabaseProductName() {
|
||||||
try {
|
try {
|
||||||
final String databaseProductName = getConnection().getMetaData().getDatabaseProductName();
|
final String databaseProductName = connection.getMetaData().getDatabaseProductName();
|
||||||
LOGGER.debug("Database product: {}", databaseProductName);
|
LOGGER.debug("Database product: {}", databaseProductName);
|
||||||
return databaseProductName;
|
return databaseProductName;
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
@@ -166,15 +227,6 @@ public final class CveDB {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the database connection.
|
|
||||||
*
|
|
||||||
* @return the database connection
|
|
||||||
*/
|
|
||||||
private Connection getConnection() {
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the database connection. If the database does not exist, it will
|
* Opens the database connection. If the database does not exist, it will
|
||||||
* create a new one.
|
* create a new one.
|
||||||
@@ -196,7 +248,7 @@ public final class CveDB {
|
|||||||
if (isOpen()) {
|
if (isOpen()) {
|
||||||
closeStatements();
|
closeStatements();
|
||||||
try {
|
try {
|
||||||
getConnection().close();
|
connection.close();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.error("There was an error attempting to close the CveDB, see the log for more details.");
|
LOGGER.error("There was an error attempting to close the CveDB, see the log for more details.");
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
@@ -205,7 +257,7 @@ public final class CveDB {
|
|||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
}
|
}
|
||||||
connection = null;
|
connection = null;
|
||||||
INSTANCE = null;
|
instance = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +267,7 @@ public final class CveDB {
|
|||||||
* @return whether the database connection is open or closed
|
* @return whether the database connection is open or closed
|
||||||
*/
|
*/
|
||||||
private boolean isOpen() {
|
private boolean isOpen() {
|
||||||
return getConnection() != null;
|
return connection != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -228,15 +280,15 @@ public final class CveDB {
|
|||||||
private EnumMap<PreparedStatementCveDb, PreparedStatement> prepareStatements()
|
private EnumMap<PreparedStatementCveDb, PreparedStatement> prepareStatements()
|
||||||
throws DatabaseException {
|
throws DatabaseException {
|
||||||
|
|
||||||
final EnumMap<PreparedStatementCveDb, PreparedStatement> result = new EnumMap<PreparedStatementCveDb, PreparedStatement>(PreparedStatementCveDb.class);
|
final EnumMap<PreparedStatementCveDb, PreparedStatement> result = new EnumMap<>(PreparedStatementCveDb.class);
|
||||||
for (PreparedStatementCveDb key : values()) {
|
for (PreparedStatementCveDb key : values()) {
|
||||||
final String statementString = statementBundle.getString(key.name());
|
final String statementString = statementBundle.getString(key.name());
|
||||||
final PreparedStatement preparedStatement;
|
final PreparedStatement preparedStatement;
|
||||||
try {
|
try {
|
||||||
if (key == INSERT_VULNERABILITY || key == INSERT_CPE) {
|
if (key == INSERT_VULNERABILITY || key == INSERT_CPE) {
|
||||||
preparedStatement = getConnection().prepareStatement(statementString, new String[]{"id"});
|
preparedStatement = connection.prepareStatement(statementString, new String[]{"id"});
|
||||||
} else {
|
} else {
|
||||||
preparedStatement = getConnection().prepareStatement(statementString);
|
preparedStatement = connection.prepareStatement(statementString);
|
||||||
}
|
}
|
||||||
} catch (SQLException exception) {
|
} catch (SQLException exception) {
|
||||||
throw new DatabaseException(exception);
|
throw new DatabaseException(exception);
|
||||||
@@ -277,7 +329,7 @@ public final class CveDB {
|
|||||||
public synchronized void commit() throws SQLException {
|
public synchronized void commit() throws SQLException {
|
||||||
//temporary remove this as autocommit is on.
|
//temporary remove this as autocommit is on.
|
||||||
//if (isOpen()) {
|
//if (isOpen()) {
|
||||||
// getConnection().commit();
|
// connection.commit();
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -623,30 +675,15 @@ public final class CveDB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final PreparedStatement insertReference = getPreparedStatement(INSERT_REFERENCE);
|
final PreparedStatement insertReference = getPreparedStatement(INSERT_REFERENCE);
|
||||||
if (batchSupported) {
|
|
||||||
insertReference.clearBatch();
|
|
||||||
}
|
|
||||||
for (Reference r : vuln.getReferences()) {
|
for (Reference r : vuln.getReferences()) {
|
||||||
insertReference.setInt(1, vulnerabilityId);
|
insertReference.setInt(1, vulnerabilityId);
|
||||||
insertReference.setString(2, r.getName());
|
insertReference.setString(2, r.getName());
|
||||||
insertReference.setString(3, r.getUrl());
|
insertReference.setString(3, r.getUrl());
|
||||||
insertReference.setString(4, r.getSource());
|
insertReference.setString(4, r.getSource());
|
||||||
|
insertReference.execute();
|
||||||
if (batchSupported) {
|
|
||||||
insertReference.addBatch();
|
|
||||||
} else {
|
|
||||||
insertReference.execute();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (batchSupported) {
|
|
||||||
insertReference.executeBatch();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final PreparedStatement insertSoftware = getPreparedStatement(INSERT_SOFTWARE);
|
final PreparedStatement insertSoftware = getPreparedStatement(INSERT_SOFTWARE);
|
||||||
if (batchSupported) {
|
|
||||||
insertSoftware.clearBatch();
|
|
||||||
}
|
|
||||||
for (VulnerableSoftware s : vuln.getVulnerableSoftware()) {
|
for (VulnerableSoftware s : vuln.getVulnerableSoftware()) {
|
||||||
int cpeProductId = 0;
|
int cpeProductId = 0;
|
||||||
final PreparedStatement selectCpeId = getPreparedStatement(SELECT_CPE_ID);
|
final PreparedStatement selectCpeId = getPreparedStatement(SELECT_CPE_ID);
|
||||||
@@ -682,23 +719,17 @@ public final class CveDB {
|
|||||||
} else {
|
} else {
|
||||||
insertSoftware.setString(3, s.getPreviousVersion());
|
insertSoftware.setString(3, s.getPreviousVersion());
|
||||||
}
|
}
|
||||||
if (batchSupported) {
|
try {
|
||||||
insertSoftware.addBatch();
|
insertSoftware.execute();
|
||||||
} else {
|
} catch (SQLException ex) {
|
||||||
try {
|
if (ex.getMessage().contains("Duplicate entry")) {
|
||||||
insertSoftware.execute();
|
final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName());
|
||||||
} catch (SQLException ex) {
|
LOGGER.info(msg, ex);
|
||||||
if (ex.getMessage().contains("Duplicate entry")) {
|
} else {
|
||||||
final String msg = String.format("Duplicate software key identified in '%s:%s'", vuln.getName(), s.getName());
|
throw ex;
|
||||||
LOGGER.info(msg, ex);
|
|
||||||
} else {
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (batchSupported) {
|
|
||||||
insertSoftware.executeBatch();
|
|
||||||
}
|
}
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
final String msg = String.format("Error updating '%s'", vuln.getName());
|
final String msg = String.format("Error updating '%s'", vuln.getName());
|
||||||
@@ -777,7 +808,7 @@ public final class CveDB {
|
|||||||
|
|
||||||
final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product);
|
final boolean isVersionTwoADifferentProduct = "apache".equals(vendor) && "struts".equals(product);
|
||||||
|
|
||||||
final Set<String> majorVersionsAffectingAllPrevious = new HashSet<String>();
|
final Set<String> majorVersionsAffectingAllPrevious = new HashSet<>();
|
||||||
final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString());
|
final boolean matchesAnyPrevious = identifiedVersion == null || "-".equals(identifiedVersion.toString());
|
||||||
String majorVersionMatch = null;
|
String majorVersionMatch = null;
|
||||||
for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
|
for (Entry<String, Boolean> entry : vulnerableSoftware.entrySet()) {
|
||||||
@@ -806,12 +837,12 @@ public final class CveDB {
|
|||||||
if (!entry.getValue()) {
|
if (!entry.getValue()) {
|
||||||
final DependencyVersion v = parseDependencyVersion(entry.getKey());
|
final DependencyVersion v = parseDependencyVersion(entry.getKey());
|
||||||
//this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
|
//this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
|
||||||
if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
|
if (canSkipVersions && majorVersionMatch != null && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//this can't dereference a null 'identifiedVersion' because if it was null we would have exited
|
//this can't dereference a null 'identifiedVersion' because if it was null we would have exited
|
||||||
//in the above loop or just after loop (if matchesAnyPrevious return null).
|
//in the above loop or just after loop (if matchesAnyPrevious return null).
|
||||||
if (identifiedVersion.equals(v)) {
|
if (identifiedVersion != null && identifiedVersion.equals(v)) {
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -820,12 +851,12 @@ public final class CveDB {
|
|||||||
if (entry.getValue()) {
|
if (entry.getValue()) {
|
||||||
final DependencyVersion v = parseDependencyVersion(entry.getKey());
|
final DependencyVersion v = parseDependencyVersion(entry.getKey());
|
||||||
//this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
|
//this can't dereference a null 'majorVersionMatch' as canSkipVersions accounts for this.
|
||||||
if (canSkipVersions && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
|
if (canSkipVersions && majorVersionMatch != null && !majorVersionMatch.equals(v.getVersionParts().get(0))) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//this can't dereference a null 'identifiedVersion' because if it was null we would have exited
|
//this can't dereference a null 'identifiedVersion' because if it was null we would have exited
|
||||||
//in the above loop or just after loop (if matchesAnyPrevious return null).
|
//in the above loop or just after loop (if matchesAnyPrevious return null).
|
||||||
if (entry.getValue() && identifiedVersion.compareTo(v) <= 0) {
|
if (entry.getValue() && identifiedVersion != null && identifiedVersion.compareTo(v) <= 0) {
|
||||||
if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) {
|
if (!(isVersionTwoADifferentProduct && !identifiedVersion.getVersionParts().get(0).equals(v.getVersionParts().get(0)))) {
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
@@ -884,10 +915,11 @@ public final class CveDB {
|
|||||||
public synchronized void deleteUnusedCpe() {
|
public synchronized void deleteUnusedCpe() {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
ps = getConnection().prepareStatement(statementBundle.getString("DELETE_UNUSED_DICT_CPE"));
|
ps = connection.prepareStatement(statementBundle.getString("DELETE_UNUSED_DICT_CPE"));
|
||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.error("Unable to delete CPE dictionary entries", ex);
|
LOGGER.error("Unable to delete CPE dictionary entries", ex);
|
||||||
|
} finally {
|
||||||
DBUtils.closeStatement(ps);
|
DBUtils.closeStatement(ps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -905,13 +937,14 @@ public final class CveDB {
|
|||||||
public synchronized void addCpe(String cpe, String vendor, String product) {
|
public synchronized void addCpe(String cpe, String vendor, String product) {
|
||||||
PreparedStatement ps = null;
|
PreparedStatement ps = null;
|
||||||
try {
|
try {
|
||||||
ps = getConnection().prepareStatement(statementBundle.getString("ADD_DICT_CPE"));
|
ps = connection.prepareStatement(statementBundle.getString("ADD_DICT_CPE"));
|
||||||
ps.setString(1, cpe);
|
ps.setString(1, cpe);
|
||||||
ps.setString(2, vendor);
|
ps.setString(2, vendor);
|
||||||
ps.setString(3, product);
|
ps.setString(3, product);
|
||||||
ps.executeUpdate();
|
ps.executeUpdate();
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
LOGGER.error("Unable to add CPE dictionary entry", ex);
|
LOGGER.error("Unable to add CPE dictionary entry", ex);
|
||||||
|
} finally {
|
||||||
DBUtils.closeStatement(ps);
|
DBUtils.closeStatement(ps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ public class DatabaseProperties {
|
|||||||
* @return a map of the database meta data
|
* @return a map of the database meta data
|
||||||
*/
|
*/
|
||||||
public Map<String, String> getMetaData() {
|
public Map<String, String> getMetaData() {
|
||||||
final Map<String, String> map = new TreeMap<String, String>();
|
final Map<String, String> map = new TreeMap<>();
|
||||||
for (Entry<Object, Object> entry : properties.entrySet()) {
|
for (Entry<Object, Object> entry : properties.entrySet()) {
|
||||||
final String key = (String) entry.getKey();
|
final String key = (String) entry.getKey();
|
||||||
if (!"version".equals(key)) {
|
if (!"version".equals(key)) {
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ public final class DriverLoader {
|
|||||||
*/
|
*/
|
||||||
public static Driver load(String className, String pathToDriver) throws DriverLoadException {
|
public static Driver load(String className, String pathToDriver) throws DriverLoadException {
|
||||||
final URLClassLoader parent = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
final URLClassLoader parent = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||||
final List<URL> urls = new ArrayList<URL>();
|
final List<URL> urls = new ArrayList<>();
|
||||||
final String[] paths = pathToDriver.split(File.pathSeparator);
|
final String[] paths = pathToDriver.split(File.pathSeparator);
|
||||||
for (String path : paths) {
|
for (String path : paths) {
|
||||||
final File file = new File(path);
|
final File file = new File(path);
|
||||||
@@ -129,19 +129,7 @@ public final class DriverLoader {
|
|||||||
//using the DriverShim to get around the fact that the DriverManager won't register a driver not in the base class path
|
//using the DriverShim to get around the fact that the DriverManager won't register a driver not in the base class path
|
||||||
DriverManager.registerDriver(shim);
|
DriverManager.registerDriver(shim);
|
||||||
return shim;
|
return shim;
|
||||||
} catch (ClassNotFoundException ex) {
|
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | SQLException ex) {
|
||||||
final String msg = String.format("Unable to load database driver '%s'", className);
|
|
||||||
LOGGER.debug(msg, ex);
|
|
||||||
throw new DriverLoadException(msg, ex);
|
|
||||||
} catch (InstantiationException ex) {
|
|
||||||
final String msg = String.format("Unable to load database driver '%s'", className);
|
|
||||||
LOGGER.debug(msg, ex);
|
|
||||||
throw new DriverLoadException(msg, ex);
|
|
||||||
} catch (IllegalAccessException ex) {
|
|
||||||
final String msg = String.format("Unable to load database driver '%s'", className);
|
|
||||||
LOGGER.debug(msg, ex);
|
|
||||||
throw new DriverLoadException(msg, ex);
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
final String msg = String.format("Unable to load database driver '%s'", className);
|
final String msg = String.format("Unable to load database driver '%s'", className);
|
||||||
LOGGER.debug(msg, ex);
|
LOGGER.debug(msg, ex);
|
||||||
throw new DriverLoadException(msg, ex);
|
throw new DriverLoadException(msg, ex);
|
||||||
|
|||||||
@@ -126,11 +126,7 @@ class DriverShim implements Driver {
|
|||||||
if (m != null) {
|
if (m != null) {
|
||||||
try {
|
try {
|
||||||
return (java.util.logging.Logger) m.invoke(m);
|
return (java.util.logging.Logger) m.invoke(m);
|
||||||
} catch (IllegalAccessException ex) {
|
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
|
||||||
LOGGER.trace("", ex);
|
|
||||||
} catch (IllegalArgumentException ex) {
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
} catch (InvocationTargetException ex) {
|
|
||||||
LOGGER.trace("", ex);
|
LOGGER.trace("", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
* Copyright (c) 2015 Jeremy Long. All Rights Reserved.
|
* Copyright (c) 2015 Jeremy Long. All Rights Reserved.
|
||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.data.update;
|
package org.owasp.dependencycheck.data.update;
|
||||||
|
/*
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
@@ -37,7 +37,7 @@ import org.owasp.dependencycheck.utils.XmlUtils;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
|
*/
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* This class is currently unused and if enabled will likely not work on MySQL
|
* This class is currently unused and if enabled will likely not work on MySQL
|
||||||
@@ -69,7 +69,7 @@ public class CpeUpdater { //extends BaseUpdater implements CachedWebDataSource {
|
|||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
// } catch (InvalidSettingException ex) {
|
// } catch (InvalidSettingException ex) {
|
||||||
// LOGGER.trace("inavlid setting UPDATE_NVDCVE_ENABLED", ex);
|
// LOGGER.trace("invalid setting UPDATE_NVDCVE_ENABLED", ex);
|
||||||
// }
|
// }
|
||||||
// */
|
// */
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public class EngineVersionCheck implements CachedWebDataSource {
|
|||||||
final boolean enabled = Settings.getBoolean(Settings.KEYS.UPDATE_VERSION_CHECK_ENABLED, true);
|
final boolean enabled = Settings.getBoolean(Settings.KEYS.UPDATE_VERSION_CHECK_ENABLED, true);
|
||||||
final String original = Settings.getString(Settings.KEYS.CVE_ORIGINAL_MODIFIED_20_URL);
|
final String original = Settings.getString(Settings.KEYS.CVE_ORIGINAL_MODIFIED_20_URL);
|
||||||
final String current = Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL);
|
final String current = Settings.getString(Settings.KEYS.CVE_MODIFIED_20_URL);
|
||||||
/**
|
/*
|
||||||
* Only update if auto-update is enabled, the engine check is
|
* Only update if auto-update is enabled, the engine check is
|
||||||
* enabled, and the NVD CVE URLs have not been modified (i.e. the
|
* enabled, and the NVD CVE URLs have not been modified (i.e. the
|
||||||
* user has not configured them to point to an internal source).
|
* user has not configured them to point to an internal source).
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import java.util.concurrent.ExecutorService;
|
|||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
|
||||||
@@ -77,7 +78,13 @@ public class NvdCveUpdater implements CachedWebDataSource {
|
|||||||
*/
|
*/
|
||||||
private ExecutorService downloadExecutorService = null;
|
private ExecutorService downloadExecutorService = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to the DAO.
|
||||||
|
*/
|
||||||
private CveDB cveDb = null;
|
private CveDB cveDb = null;
|
||||||
|
/**
|
||||||
|
* The properties obtained from the database.
|
||||||
|
*/
|
||||||
private DatabaseProperties dbProperties = null;
|
private DatabaseProperties dbProperties = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -135,6 +142,10 @@ public class NvdCveUpdater implements CachedWebDataSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the executor services for download and processing of the NVD
|
||||||
|
* CVE XML data.
|
||||||
|
*/
|
||||||
protected void initializeExecutorServices() {
|
protected void initializeExecutorServices() {
|
||||||
processingExecutorService = Executors.newFixedThreadPool(PROCESSING_THREAD_POOL_SIZE);
|
processingExecutorService = Executors.newFixedThreadPool(PROCESSING_THREAD_POOL_SIZE);
|
||||||
downloadExecutorService = Executors.newFixedThreadPool(DOWNLOAD_THREAD_POOL_SIZE);
|
downloadExecutorService = Executors.newFixedThreadPool(DOWNLOAD_THREAD_POOL_SIZE);
|
||||||
@@ -142,6 +153,9 @@ public class NvdCveUpdater implements CachedWebDataSource {
|
|||||||
LOGGER.debug("#processing threads: {}", PROCESSING_THREAD_POOL_SIZE);
|
LOGGER.debug("#processing threads: {}", PROCESSING_THREAD_POOL_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shutdown and cleanup of resources used by the executor services.
|
||||||
|
*/
|
||||||
private void shutdownExecutorServices() {
|
private void shutdownExecutorServices() {
|
||||||
if (processingExecutorService != null) {
|
if (processingExecutorService != null) {
|
||||||
processingExecutorService.shutdownNow();
|
processingExecutorService.shutdownNow();
|
||||||
@@ -426,7 +440,7 @@ public class NvdCveUpdater implements CachedWebDataSource {
|
|||||||
final long timestamp;
|
final long timestamp;
|
||||||
try {
|
try {
|
||||||
timestamp = timestampFuture.get(60, TimeUnit.SECONDS);
|
timestamp = timestampFuture.get(60, TimeUnit.SECONDS);
|
||||||
} catch (Exception e) {
|
} catch (InterruptedException | ExecutionException | TimeoutException e) {
|
||||||
throw new DownloadFailedException(e);
|
throw new DownloadFailedException(e);
|
||||||
}
|
}
|
||||||
lastModifiedDates.put(url, timestamp);
|
lastModifiedDates.put(url, timestamp);
|
||||||
@@ -440,8 +454,16 @@ public class NvdCveUpdater implements CachedWebDataSource {
|
|||||||
*/
|
*/
|
||||||
private static class TimestampRetriever implements Callable<Long> {
|
private static class TimestampRetriever implements Callable<Long> {
|
||||||
|
|
||||||
private String url;
|
/**
|
||||||
|
* The URL to obtain the timestamp from.
|
||||||
|
*/
|
||||||
|
private final String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Instantiates a new timestamp retriever object.
|
||||||
|
*
|
||||||
|
* @param url the URL to hit
|
||||||
|
*/
|
||||||
TimestampRetriever(String url) {
|
TimestampRetriever(String url) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ import org.xml.sax.SAXException;
|
|||||||
import org.xml.sax.helpers.DefaultHandler;
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A SAX Handler that will parse the CPE XML and load it into the databse.
|
* A SAX Handler that will parse the CPE XML and load it into the database.
|
||||||
*
|
*
|
||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
@@ -60,7 +60,7 @@ public class CPEHandler extends DefaultHandler {
|
|||||||
/**
|
/**
|
||||||
* The list of CPE values.
|
* The list of CPE values.
|
||||||
*/
|
*/
|
||||||
private final List<Cpe> data = new ArrayList<Cpe>();
|
private final List<Cpe> data = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of CPE values.
|
* Returns the list of CPE values.
|
||||||
@@ -154,35 +154,10 @@ public class CPEHandler extends DefaultHandler {
|
|||||||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
current.setNode(qName);
|
current.setNode(qName);
|
||||||
if (current.isSchemaVersionNode() && !CURRENT_SCHEMA_VERSION.equals(nodeText.toString())) {
|
if (current.isSchemaVersionNode() && !CURRENT_SCHEMA_VERSION.equals(nodeText.toString())) {
|
||||||
throw new SAXException("ERROR: Unexpecgted CPE Schema Version, expected: "
|
throw new SAXException("ERROR: Unexpected CPE Schema Version, expected: "
|
||||||
+ CURRENT_SCHEMA_VERSION + ", file is: " + nodeText);
|
+ CURRENT_SCHEMA_VERSION + ", file is: " + nodeText);
|
||||||
|
|
||||||
}
|
}
|
||||||
// } else if (current.isCpeItemNode()) {
|
|
||||||
// //do nothing
|
|
||||||
// } else if (current.isTitleNode()) {
|
|
||||||
// //do nothing
|
|
||||||
// } else if (current.isCpeListNode()) {
|
|
||||||
// //do nothing
|
|
||||||
// } else if (current.isMetaNode()) {
|
|
||||||
// //do nothing
|
|
||||||
// } else if (current.isNotesNode()) {
|
|
||||||
// //do nothing
|
|
||||||
// } else if (current.isNoteNode()) {
|
|
||||||
// //do nothing
|
|
||||||
// } else if (current.isCheckNode()) {
|
|
||||||
// //do nothing
|
|
||||||
// } else if (current.isGeneratorNode()) {
|
|
||||||
// //do nothing
|
|
||||||
// } else if (current.isProductNameNode()) {
|
|
||||||
// //do nothing
|
|
||||||
// } else if (current.isProductVersionNode()) {
|
|
||||||
// //do nothing
|
|
||||||
// else if (current.isTimestampNode()) {
|
|
||||||
// //do nothing
|
|
||||||
// } else {
|
|
||||||
// throw new SAXException("ERROR STATE: Unexpected qName '" + qName + "'");
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
|
// <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package org.owasp.dependencycheck.data.update.nvd;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
@@ -224,33 +223,19 @@ public class DownloadTask implements Callable<Future<ProcessTask>> {
|
|||||||
if (file == null || !file.isFile()) {
|
if (file == null || !file.isFile()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
InputStream is = null;
|
try (InputStream is = new FileInputStream(file)) {
|
||||||
try {
|
|
||||||
is = new FileInputStream(file);
|
|
||||||
|
|
||||||
final byte[] buf = new byte[5];
|
final byte[] buf = new byte[5];
|
||||||
int read = 0;
|
int read;
|
||||||
try {
|
read = is.read(buf);
|
||||||
read = is.read(buf);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return read == 5
|
return read == 5
|
||||||
&& buf[0] == '<'
|
&& buf[0] == '<'
|
||||||
&& (buf[1] == '?')
|
&& (buf[1] == '?')
|
||||||
&& (buf[2] == 'x' || buf[2] == 'X')
|
&& (buf[2] == 'x' || buf[2] == 'X')
|
||||||
&& (buf[3] == 'm' || buf[3] == 'M')
|
&& (buf[3] == 'm' || buf[3] == 'M')
|
||||||
&& (buf[4] == 'l' || buf[4] == 'L');
|
&& (buf[4] == 'l' || buf[4] == 'L');
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (IOException ex) {
|
||||||
|
LOGGER.debug("Error checking if file is xml", ex);
|
||||||
return false;
|
return false;
|
||||||
} finally {
|
|
||||||
if (is != null) {
|
|
||||||
try {
|
|
||||||
is.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.debug("Error closing stream", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ public class NvdCve12Handler extends DefaultHandler {
|
|||||||
skip = "1".equals(reject);
|
skip = "1".equals(reject);
|
||||||
if (!skip) {
|
if (!skip) {
|
||||||
vulnerability = attributes.getValue("name");
|
vulnerability = attributes.getValue("name");
|
||||||
software = new ArrayList<VulnerableSoftware>();
|
software = new ArrayList<>();
|
||||||
} else {
|
} else {
|
||||||
vulnerability = null;
|
vulnerability = null;
|
||||||
software = null;
|
software = null;
|
||||||
@@ -132,7 +132,7 @@ public class NvdCve12Handler extends DefaultHandler {
|
|||||||
if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
|
if (!CURRENT_SCHEMA_VERSION.equals(nvdVer)) {
|
||||||
throw new SAXNotSupportedException("Schema version " + nvdVer + " is not supported");
|
throw new SAXNotSupportedException("Schema version " + nvdVer + " is not supported");
|
||||||
}
|
}
|
||||||
vulnerabilities = new HashMap<String, List<VulnerableSoftware>>();
|
vulnerabilities = new HashMap<>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,8 @@ public class NvdCve20Handler extends DefaultHandler {
|
|||||||
*/
|
*/
|
||||||
private static final String CURRENT_SCHEMA_VERSION = "2.0";
|
private static final String CURRENT_SCHEMA_VERSION = "2.0";
|
||||||
/**
|
/**
|
||||||
* a possible attribute value of the {@link AttributeValues#XML_LANG} attribute
|
* a possible attribute value of the {@link AttributeValues#XML_LANG}
|
||||||
|
* attribute
|
||||||
*/
|
*/
|
||||||
private static final String EN = "en";
|
private static final String EN = "en";
|
||||||
/**
|
/**
|
||||||
@@ -97,7 +98,8 @@ public class NvdCve20Handler extends DefaultHandler {
|
|||||||
private CveDB cveDB;
|
private CveDB cveDB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A list of CVE entries and associated VulnerableSoftware entries that contain previous entries.
|
* A list of CVE entries and associated VulnerableSoftware entries that
|
||||||
|
* contain previous entries.
|
||||||
*/
|
*/
|
||||||
private Map<String, List<VulnerableSoftware>> prevVersionVulnMap;
|
private Map<String, List<VulnerableSoftware>> prevVersionVulnMap;
|
||||||
|
|
||||||
@@ -182,9 +184,7 @@ public class NvdCve20Handler extends DefaultHandler {
|
|||||||
totalNumberOfApplicationEntries += 1;
|
totalNumberOfApplicationEntries += 1;
|
||||||
try {
|
try {
|
||||||
saveEntry(vulnerability);
|
saveEntry(vulnerability);
|
||||||
} catch (DatabaseException ex) {
|
} catch (DatabaseException | CorruptIndexException ex) {
|
||||||
throw new SAXException(ex);
|
|
||||||
} catch (CorruptIndexException ex) {
|
|
||||||
throw new SAXException(ex);
|
throw new SAXException(ex);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
throw new SAXException(ex);
|
throw new SAXException(ex);
|
||||||
@@ -251,10 +251,12 @@ public class NvdCve20Handler extends DefaultHandler {
|
|||||||
public void setCveDB(CveDB db) {
|
public void setCveDB(CveDB db) {
|
||||||
cveDB = db;
|
cveDB = db;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the prevVersionVulnMap.
|
* Sets the prevVersionVulnMap.
|
||||||
*
|
*
|
||||||
* @param map the map of vulnerable software with previous versions being vulnerable
|
* @param map the map of vulnerable software with previous versions being
|
||||||
|
* vulnerable
|
||||||
*/
|
*/
|
||||||
public void setPrevVersionVulnMap(Map<String, List<VulnerableSoftware>> map) {
|
public void setPrevVersionVulnMap(Map<String, List<VulnerableSoftware>> map) {
|
||||||
prevVersionVulnMap = map;
|
prevVersionVulnMap = map;
|
||||||
@@ -264,7 +266,8 @@ public class NvdCve20Handler extends DefaultHandler {
|
|||||||
* Saves a vulnerability to the CVE Database.
|
* Saves a vulnerability to the CVE Database.
|
||||||
*
|
*
|
||||||
* @param vuln the vulnerability to store in the database
|
* @param vuln the vulnerability to store in the database
|
||||||
* @throws DatabaseException thrown if there is an error writing to the database
|
* @throws DatabaseException thrown if there is an error writing to the
|
||||||
|
* database
|
||||||
* @throws CorruptIndexException is thrown if the CPE Index is corrupt
|
* @throws CorruptIndexException is thrown if the CPE Index is corrupt
|
||||||
* @throws IOException thrown if there is an IOException with the CPE Index
|
* @throws IOException thrown if there is an IOException with the CPE Index
|
||||||
*/
|
*/
|
||||||
@@ -283,7 +286,8 @@ public class NvdCve20Handler extends DefaultHandler {
|
|||||||
|
|
||||||
// <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
|
// <editor-fold defaultstate="collapsed" desc="The Element Class that maintains state information about the current node">
|
||||||
/**
|
/**
|
||||||
* A simple class to maintain information about the current element while parsing the NVD CVE XML.
|
* A simple class to maintain information about the current element while
|
||||||
|
* parsing the NVD CVE XML.
|
||||||
*/
|
*/
|
||||||
protected static class Element {
|
protected static class Element {
|
||||||
|
|
||||||
@@ -508,7 +512,8 @@ public class NvdCve20Handler extends DefaultHandler {
|
|||||||
// </editor-fold>
|
// </editor-fold>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple class to maintain information about the attribute values encountered while parsing the NVD CVE XML.
|
* A simple class to maintain information about the attribute values
|
||||||
|
* encountered while parsing the NVD CVE XML.
|
||||||
*/
|
*/
|
||||||
protected static class AttributeValues {
|
protected static class AttributeValues {
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
package org.owasp.dependencycheck.data.update.nvd;
|
package org.owasp.dependencycheck.data.update.nvd;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -167,19 +166,7 @@ public class ProcessTask implements Callable<ProcessTask> {
|
|||||||
importXML(filePair.getFirst(), filePair.getSecond());
|
importXML(filePair.getFirst(), filePair.getSecond());
|
||||||
cveDB.commit();
|
cveDB.commit();
|
||||||
properties.save(filePair.getNvdCveInfo());
|
properties.save(filePair.getNvdCveInfo());
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (ParserConfigurationException | SAXException | SQLException | DatabaseException | ClassNotFoundException | IOException ex) {
|
||||||
throw new UpdateException(ex);
|
|
||||||
} catch (ParserConfigurationException ex) {
|
|
||||||
throw new UpdateException(ex);
|
|
||||||
} catch (SAXException ex) {
|
|
||||||
throw new UpdateException(ex);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new UpdateException(ex);
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
throw new UpdateException(ex);
|
|
||||||
} catch (DatabaseException ex) {
|
|
||||||
throw new UpdateException(ex);
|
|
||||||
} catch (ClassNotFoundException ex) {
|
|
||||||
throw new UpdateException(ex);
|
throw new UpdateException(ex);
|
||||||
} finally {
|
} finally {
|
||||||
filePair.cleanup();
|
filePair.cleanup();
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class UpdateableNvdCve implements Iterable<NvdCveInfo>, Iterator<NvdCveIn
|
|||||||
/**
|
/**
|
||||||
* A collection of sources of data.
|
* A collection of sources of data.
|
||||||
*/
|
*/
|
||||||
private final Map<String, NvdCveInfo> collection = new TreeMap<String, NvdCveInfo>();
|
private final Map<String, NvdCveInfo> collection = new TreeMap<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the collection of NvdCveInfo objects. This method is mainly used for testing.
|
* Returns the collection of NvdCveInfo objects. This method is mainly used for testing.
|
||||||
|
|||||||
@@ -128,15 +128,15 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
/**
|
/**
|
||||||
* A collection of related dependencies.
|
* A collection of related dependencies.
|
||||||
*/
|
*/
|
||||||
private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
|
private Set<Dependency> relatedDependencies = new TreeSet<>();
|
||||||
/**
|
/**
|
||||||
* A list of projects that reference this dependency.
|
* A list of projects that reference this dependency.
|
||||||
*/
|
*/
|
||||||
private Set<String> projectReferences = new HashSet<String>();
|
private Set<String> projectReferences = new HashSet<>();
|
||||||
/**
|
/**
|
||||||
* A list of available versions.
|
* A list of available versions.
|
||||||
*/
|
*/
|
||||||
private List<String> availableVersions = new ArrayList<String>();
|
private List<String> availableVersions = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the package path.
|
* Returns the package path.
|
||||||
@@ -598,7 +598,7 @@ public class Dependency implements Serializable, Comparable<Dependency> {
|
|||||||
LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName());
|
LOGGER.warn("Unable to read '{}' to determine hashes.", file.getName());
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
} catch (NoSuchAlgorithmException ex) {
|
} catch (NoSuchAlgorithmException ex) {
|
||||||
LOGGER.warn("Unable to use MD5 of SHA1 checksums.");
|
LOGGER.warn("Unable to use MD5 or SHA1 checksums.");
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
}
|
}
|
||||||
this.setMd5sum(md5);
|
this.setMd5sum(md5);
|
||||||
|
|||||||
@@ -114,23 +114,27 @@ public class EvidenceCollection implements Serializable, Iterable<Evidence> {
|
|||||||
* @return Iterable<Evidence> an iterable collection of evidence
|
* @return Iterable<Evidence> an iterable collection of evidence
|
||||||
*/
|
*/
|
||||||
public final Iterable<Evidence> iterator(Confidence confidence) {
|
public final Iterable<Evidence> iterator(Confidence confidence) {
|
||||||
if (confidence == Confidence.HIGHEST) {
|
if (null != confidence) {
|
||||||
return EvidenceCollection.HIGHEST_CONFIDENCE.filter(this.list);
|
switch (confidence) {
|
||||||
} else if (confidence == Confidence.HIGH) {
|
case HIGHEST:
|
||||||
return EvidenceCollection.HIGH_CONFIDENCE.filter(this.list);
|
return EvidenceCollection.HIGHEST_CONFIDENCE.filter(this.list);
|
||||||
} else if (confidence == Confidence.MEDIUM) {
|
case HIGH:
|
||||||
return EvidenceCollection.MEDIUM_CONFIDENCE.filter(this.list);
|
return EvidenceCollection.HIGH_CONFIDENCE.filter(this.list);
|
||||||
} else {
|
case MEDIUM:
|
||||||
return EvidenceCollection.LOW_CONFIDENCE.filter(this.list);
|
return EvidenceCollection.MEDIUM_CONFIDENCE.filter(this.list);
|
||||||
|
default:
|
||||||
|
return EvidenceCollection.LOW_CONFIDENCE.filter(this.list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new EvidenceCollection.
|
* Creates a new EvidenceCollection.
|
||||||
*/
|
*/
|
||||||
public EvidenceCollection() {
|
public EvidenceCollection() {
|
||||||
list = new TreeSet<Evidence>();
|
list = new TreeSet<>();
|
||||||
weightedStrings = new HashSet<String>();
|
weightedStrings = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -204,7 +208,7 @@ public class EvidenceCollection implements Serializable, Iterable<Evidence> {
|
|||||||
if (source == null) {
|
if (source == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final Set<Evidence> ret = new HashSet<Evidence>();
|
final Set<Evidence> ret = new HashSet<>();
|
||||||
for (Evidence e : list) {
|
for (Evidence e : list) {
|
||||||
if (source.equals(e.getSource())) {
|
if (source.equals(e.getSource())) {
|
||||||
ret.add(e);
|
ret.add(e);
|
||||||
@@ -224,7 +228,7 @@ public class EvidenceCollection implements Serializable, Iterable<Evidence> {
|
|||||||
if (source == null || name == null) {
|
if (source == null || name == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
final Set<Evidence> ret = new HashSet<Evidence>();
|
final Set<Evidence> ret = new HashSet<>();
|
||||||
for (Evidence e : list) {
|
for (Evidence e : list) {
|
||||||
if (source.equals(e.getSource()) && name.equals(e.getName())) {
|
if (source.equals(e.getSource()) && name.equals(e.getName())) {
|
||||||
ret.add(e);
|
ret.add(e);
|
||||||
@@ -345,7 +349,7 @@ public class EvidenceCollection implements Serializable, Iterable<Evidence> {
|
|||||||
* collections
|
* collections
|
||||||
*/
|
*/
|
||||||
public static Set<Evidence> mergeForDisplay(EvidenceCollection... ec) {
|
public static Set<Evidence> mergeForDisplay(EvidenceCollection... ec) {
|
||||||
final Set<Evidence> ret = new TreeSet<Evidence>();
|
final Set<Evidence> ret = new TreeSet<>();
|
||||||
for (EvidenceCollection col : ec) {
|
for (EvidenceCollection col : ec) {
|
||||||
for (Evidence e : col) {
|
for (Evidence e : col) {
|
||||||
//if (e.isUsed()) {
|
//if (e.isUsed()) {
|
||||||
@@ -393,10 +397,10 @@ public class EvidenceCollection implements Serializable, Iterable<Evidence> {
|
|||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* Example, given the following input:</p>
|
* Example, given the following input:</p>
|
||||||
* <code>'Please visit https://www.somedomain.com/path1/path2/file.php?id=439'</code>
|
* <code>'Please visit https://www.owasp.com/path1/path2/file.php?id=439'</code>
|
||||||
* <p>
|
* <p>
|
||||||
* The function would return:</p>
|
* The function would return:</p>
|
||||||
* <code>'Please visit somedomain path1 path2 file'</code>
|
* <code>'Please visit owasp path1 path2 file'</code>
|
||||||
*
|
*
|
||||||
* @param value the value that may contain a url
|
* @param value the value that may contain a url
|
||||||
* @return the modified string
|
* @return the modified string
|
||||||
|
|||||||
@@ -47,11 +47,11 @@ public class Vulnerability implements Serializable, Comparable<Vulnerability> {
|
|||||||
/**
|
/**
|
||||||
* References for this vulnerability.
|
* References for this vulnerability.
|
||||||
*/
|
*/
|
||||||
private Set<Reference> references = new HashSet<Reference>();
|
private Set<Reference> references = new HashSet<>();
|
||||||
/**
|
/**
|
||||||
* A set of vulnerable software.
|
* A set of vulnerable software.
|
||||||
*/
|
*/
|
||||||
private Set<VulnerableSoftware> vulnerableSoftware = new HashSet<VulnerableSoftware>();
|
private Set<VulnerableSoftware> vulnerableSoftware = new HashSet<>();
|
||||||
/**
|
/**
|
||||||
* The CWE for the vulnerability.
|
* The CWE for the vulnerability.
|
||||||
*/
|
*/
|
||||||
@@ -153,7 +153,7 @@ public class Vulnerability implements Serializable, Comparable<Vulnerability> {
|
|||||||
* @return the list of references
|
* @return the list of references
|
||||||
*/
|
*/
|
||||||
public List<Reference> getReferences(boolean sorted) {
|
public List<Reference> getReferences(boolean sorted) {
|
||||||
List<Reference> sortedRefs = new ArrayList<>(this.references);
|
final List<Reference> sortedRefs = new ArrayList<>(this.references);
|
||||||
if (sorted) {
|
if (sorted) {
|
||||||
Collections.sort(sortedRefs);
|
Collections.sort(sortedRefs);
|
||||||
}
|
}
|
||||||
@@ -210,7 +210,7 @@ public class Vulnerability implements Serializable, Comparable<Vulnerability> {
|
|||||||
* @return the list of vulnerable software
|
* @return the list of vulnerable software
|
||||||
*/
|
*/
|
||||||
public List<VulnerableSoftware> getVulnerableSoftware(boolean sorted) {
|
public List<VulnerableSoftware> getVulnerableSoftware(boolean sorted) {
|
||||||
List<VulnerableSoftware> sortedVulnerableSoftware = new ArrayList<>(this.vulnerableSoftware);
|
final List<VulnerableSoftware> sortedVulnerableSoftware = new ArrayList<>(this.vulnerableSoftware);
|
||||||
if (sorted) {
|
if (sorted) {
|
||||||
Collections.sort(sortedVulnerableSoftware);
|
Collections.sort(sortedVulnerableSoftware);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class ExceptionCollection extends Exception {
|
|||||||
/**
|
/**
|
||||||
* A collection of exceptions.
|
* A collection of exceptions.
|
||||||
*/
|
*/
|
||||||
private List<Throwable> exceptions;
|
private final List<Throwable> exceptions;
|
||||||
/**
|
/**
|
||||||
* Flag indicating if a fatal exception occurred that would prevent the
|
* Flag indicating if a fatal exception occurred that would prevent the
|
||||||
* attempt at completing the analysis even if exceptions occurred.
|
* attempt at completing the analysis even if exceptions occurred.
|
||||||
@@ -99,7 +99,7 @@ public class ExceptionCollection extends Exception {
|
|||||||
*/
|
*/
|
||||||
public ExceptionCollection(Throwable exceptions, boolean fatal) {
|
public ExceptionCollection(Throwable exceptions, boolean fatal) {
|
||||||
super();
|
super();
|
||||||
this.exceptions = new ArrayList<Throwable>();
|
this.exceptions = new ArrayList<>();
|
||||||
this.exceptions.add(exceptions);
|
this.exceptions.add(exceptions);
|
||||||
this.fatal = fatal;
|
this.fatal = fatal;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,55 +240,39 @@ public class ReportGenerator {
|
|||||||
InputStream input = null;
|
InputStream input = null;
|
||||||
String templatePath = null;
|
String templatePath = null;
|
||||||
final File f = new File(templateName);
|
final File f = new File(templateName);
|
||||||
if (f.exists() && f.isFile()) {
|
|
||||||
try {
|
|
||||||
templatePath = templateName;
|
|
||||||
input = new FileInputStream(f);
|
|
||||||
} catch (FileNotFoundException ex) {
|
|
||||||
throw new ReportException("Unable to locate template file: " + templateName, ex);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
templatePath = "templates/" + templateName + ".vsl";
|
|
||||||
input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
|
|
||||||
}
|
|
||||||
if (input == null) {
|
|
||||||
throw new ReportException("Template file doesn't exist: " + templatePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
InputStreamReader reader = null;
|
|
||||||
OutputStreamWriter writer = null;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
reader = new InputStreamReader(input, "UTF-8");
|
if (f.exists() && f.isFile()) {
|
||||||
writer = new OutputStreamWriter(outputStream, "UTF-8");
|
try {
|
||||||
if (!velocityEngine.evaluate(context, writer, templatePath, reader)) {
|
templatePath = templateName;
|
||||||
throw new ReportException("Failed to convert the template into html.");
|
input = new FileInputStream(f);
|
||||||
|
} catch (FileNotFoundException ex) {
|
||||||
|
throw new ReportException("Unable to locate template file: " + templateName, ex);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
templatePath = "templates/" + templateName + ".vsl";
|
||||||
|
input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
|
||||||
|
}
|
||||||
|
if (input == null) {
|
||||||
|
throw new ReportException("Template file doesn't exist: " + templatePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
try (InputStreamReader reader = new InputStreamReader(input, "UTF-8");
|
||||||
|
OutputStreamWriter writer = new OutputStreamWriter(outputStream, "UTF-8")) {
|
||||||
|
if (!velocityEngine.evaluate(context, writer, templatePath, reader)) {
|
||||||
|
throw new ReportException("Failed to convert the template into html.");
|
||||||
|
}
|
||||||
|
writer.flush();
|
||||||
|
} catch (UnsupportedEncodingException ex) {
|
||||||
|
throw new ReportException("Unable to generate the report using UTF-8", ex);
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new ReportException("Unable to write the report", ex);
|
||||||
}
|
}
|
||||||
writer.flush();
|
|
||||||
} catch (UnsupportedEncodingException ex) {
|
|
||||||
throw new ReportException("Unable to generate the report using UTF-8", ex);
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new ReportException("Unable to write the report", ex);
|
|
||||||
} finally {
|
} finally {
|
||||||
if (writer != null) {
|
if (input != null) {
|
||||||
try {
|
try {
|
||||||
writer.close();
|
input.close();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.trace("", ex);
|
LOGGER.trace("Error closing input", ex);
|
||||||
}
|
|
||||||
}
|
|
||||||
if (outputStream != null) {
|
|
||||||
try {
|
|
||||||
outputStream.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (reader != null) {
|
|
||||||
try {
|
|
||||||
reader.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -315,21 +299,10 @@ public class ReportGenerator {
|
|||||||
throw new ReportException("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'.");
|
throw new ReportException("Unable to create directory '" + outFile.getParentFile().getAbsolutePath() + "'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
try (OutputStream outputSteam = new FileOutputStream(outFile)) {
|
||||||
OutputStream outputSteam = null;
|
|
||||||
try {
|
|
||||||
outputSteam = new FileOutputStream(outFile);
|
|
||||||
generateReport(templateName, outputSteam);
|
generateReport(templateName, outputSteam);
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (IOException ex) {
|
||||||
throw new ReportException("Unable to write to file: " + outFile, ex);
|
throw new ReportException("Unable to write to file: " + outFile, ex);
|
||||||
} finally {
|
|
||||||
if (outputSteam != null) {
|
|
||||||
try {
|
|
||||||
outputSteam.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("ignore", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,7 +47,8 @@ public final class DBUtils {
|
|||||||
*
|
*
|
||||||
* @param statement a prepared statement that just executed an insert
|
* @param statement a prepared statement that just executed an insert
|
||||||
* @return a primary key
|
* @return a primary key
|
||||||
* @throws DatabaseException thrown if there is an exception obtaining the key
|
* @throws DatabaseException thrown if there is an exception obtaining the
|
||||||
|
* key
|
||||||
*/
|
*/
|
||||||
public static int getGeneratedKey(PreparedStatement statement) throws DatabaseException {
|
public static int getGeneratedKey(PreparedStatement statement) throws DatabaseException {
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
@@ -72,27 +73,29 @@ public final class DBUtils {
|
|||||||
* @param statement a Statement object
|
* @param statement a Statement object
|
||||||
*/
|
*/
|
||||||
public static void closeStatement(Statement statement) {
|
public static void closeStatement(Statement statement) {
|
||||||
if (statement != null) {
|
try {
|
||||||
try {
|
if (statement != null && !statement.isClosed()) {
|
||||||
|
|
||||||
statement.close();
|
statement.close();
|
||||||
} catch (SQLException ex) {
|
|
||||||
LOGGER.trace(statement.toString(), ex);
|
|
||||||
}
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
LOGGER.trace(statement.toString(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the result set capturing and ignoring any SQLExceptions that occur.
|
* Closes the result set capturing and ignoring any SQLExceptions that
|
||||||
|
* occur.
|
||||||
*
|
*
|
||||||
* @param rs a ResultSet to close
|
* @param rs a ResultSet to close
|
||||||
*/
|
*/
|
||||||
public static void closeResultSet(ResultSet rs) {
|
public static void closeResultSet(ResultSet rs) {
|
||||||
if (rs != null) {
|
try {
|
||||||
try {
|
if (rs != null && !rs.isClosed()) {
|
||||||
rs.close();
|
rs.close();
|
||||||
} catch (SQLException ex) {
|
|
||||||
LOGGER.trace(rs.toString(), ex);
|
|
||||||
}
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
LOGGER.trace(rs.toString(), ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ public class DependencyVersion implements Iterable<String>, Comparable<Dependenc
|
|||||||
* @param version the version string to parse
|
* @param version the version string to parse
|
||||||
*/
|
*/
|
||||||
public final void parseVersion(String version) {
|
public final void parseVersion(String version) {
|
||||||
versionParts = new ArrayList<String>();
|
versionParts = new ArrayList<>();
|
||||||
if (version != null) {
|
if (version != null) {
|
||||||
final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)");
|
final Pattern rx = Pattern.compile("(\\d+[a-z]{1,3}$|[a-z]+\\d+|\\d+|(release|beta|alpha)$)");
|
||||||
final Matcher matcher = rx.matcher(version.toLowerCase());
|
final Matcher matcher = rx.matcher(version.toLowerCase());
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public final class DependencyVersionUtil {
|
|||||||
//'-' is a special case used within the CVE entries, just include it as the version.
|
//'-' is a special case used within the CVE entries, just include it as the version.
|
||||||
if ("-".equals(text)) {
|
if ("-".equals(text)) {
|
||||||
final DependencyVersion dv = new DependencyVersion();
|
final DependencyVersion dv = new DependencyVersion();
|
||||||
final List<String> list = new ArrayList<String>();
|
final List<String> list = new ArrayList<>();
|
||||||
list.add(text);
|
list.add(text);
|
||||||
dv.setVersionParts(list);
|
dv.setVersionParts(list);
|
||||||
return dv;
|
return dv;
|
||||||
|
|||||||
@@ -85,18 +85,10 @@ public final class ExtractionUtil {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInputStream fis = null;
|
|
||||||
ZipInputStream zis = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
fis = new FileInputStream(archive);
|
|
||||||
} catch (FileNotFoundException ex) {
|
|
||||||
LOGGER.debug("", ex);
|
|
||||||
throw new ExtractionException("Archive file was not found.", ex);
|
|
||||||
}
|
|
||||||
zis = new ZipInputStream(new BufferedInputStream(fis));
|
|
||||||
ZipEntry entry;
|
ZipEntry entry;
|
||||||
try {
|
try (FileInputStream fis = new FileInputStream(archive);
|
||||||
|
BufferedInputStream bis = new BufferedInputStream(fis);
|
||||||
|
ZipInputStream zis = new ZipInputStream(bis)) {
|
||||||
while ((entry = zis.getNextEntry()) != null) {
|
while ((entry = zis.getNextEntry()) != null) {
|
||||||
if (entry.isDirectory()) {
|
if (entry.isDirectory()) {
|
||||||
final File d = new File(extractTo, entry.getName());
|
final File d = new File(extractTo, entry.getName());
|
||||||
@@ -107,9 +99,7 @@ public final class ExtractionUtil {
|
|||||||
} else {
|
} else {
|
||||||
final File file = new File(extractTo, entry.getName());
|
final File file = new File(extractTo, entry.getName());
|
||||||
if (engine == null || engine.accept(file)) {
|
if (engine == null || engine.accept(file)) {
|
||||||
FileOutputStream fos = null;
|
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||||
try {
|
|
||||||
fos = new FileOutputStream(file);
|
|
||||||
IOUtils.copy(zis, fos);
|
IOUtils.copy(zis, fos);
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
@@ -119,8 +109,6 @@ public final class ExtractionUtil {
|
|||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
|
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
|
||||||
throw new ExtractionException(msg, ex);
|
throw new ExtractionException(msg, ex);
|
||||||
} finally {
|
|
||||||
FileUtils.close(fos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,8 +117,6 @@ public final class ExtractionUtil {
|
|||||||
final String msg = String.format("Exception reading archive '%s'.", archive.getName());
|
final String msg = String.format("Exception reading archive '%s'.", archive.getName());
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new ExtractionException(msg, ex);
|
throw new ExtractionException(msg, ex);
|
||||||
} finally {
|
|
||||||
FileUtils.close(zis);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,31 +128,21 @@ public final class ExtractionUtil {
|
|||||||
* @param filter determines which files get extracted
|
* @param filter determines which files get extracted
|
||||||
* @throws ExtractionException thrown if the archive is not found
|
* @throws ExtractionException thrown if the archive is not found
|
||||||
*/
|
*/
|
||||||
public static void extractFilesUsingFilter(File archive, File destination,
|
public static void extractFilesUsingFilter(File archive, File destination, FilenameFilter filter) throws ExtractionException {
|
||||||
FilenameFilter filter) throws ExtractionException {
|
|
||||||
if (archive == null || destination == null) {
|
if (archive == null || destination == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileInputStream fis = null;
|
try (FileInputStream fis = new FileInputStream(archive)) {
|
||||||
try {
|
extractArchive(new ZipArchiveInputStream(new BufferedInputStream(
|
||||||
fis = new FileInputStream(archive);
|
fis)), destination, filter);
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new ExtractionException("Archive file was not found.", ex);
|
throw new ExtractionException("Archive file was not found.", ex);
|
||||||
}
|
} catch (IOException | ArchiveExtractionException ex) {
|
||||||
try {
|
|
||||||
extractArchive(new ZipArchiveInputStream(new BufferedInputStream(
|
|
||||||
fis)), destination, filter);
|
|
||||||
} catch (ArchiveExtractionException ex) {
|
|
||||||
LOGGER.warn("Exception extracting archive '{}'.", archive.getName());
|
LOGGER.warn("Exception extracting archive '{}'.", archive.getName());
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
} finally {
|
throw new ExtractionException("Unable to extract from archive", ex);
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.debug("", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,9 +173,7 @@ public final class ExtractionUtil {
|
|||||||
extractFile(input, destination, filter, entry);
|
extractFile(input, destination, filter, entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException | AnalysisException ex) {
|
||||||
throw new ArchiveExtractionException(ex);
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
throw new ArchiveExtractionException(ex);
|
throw new ArchiveExtractionException(ex);
|
||||||
} finally {
|
} finally {
|
||||||
FileUtils.close(input);
|
FileUtils.close(input);
|
||||||
@@ -221,26 +195,19 @@ public final class ExtractionUtil {
|
|||||||
FilenameFilter filter, ArchiveEntry entry) throws ExtractionException {
|
FilenameFilter filter, ArchiveEntry entry) throws ExtractionException {
|
||||||
final File file = new File(destination, entry.getName());
|
final File file = new File(destination, entry.getName());
|
||||||
if (filter.accept(file.getParentFile(), file.getName())) {
|
if (filter.accept(file.getParentFile(), file.getName())) {
|
||||||
LOGGER.debug("Extracting '{}'",
|
LOGGER.debug("Extracting '{}'", file.getPath());
|
||||||
file.getPath());
|
createParentFile(file);
|
||||||
FileOutputStream fos = null;
|
|
||||||
try {
|
try (FileOutputStream fos = new FileOutputStream(file)) {
|
||||||
createParentFile(file);
|
|
||||||
fos = new FileOutputStream(file);
|
|
||||||
IOUtils.copy(input, fos);
|
IOUtils.copy(input, fos);
|
||||||
} catch (FileNotFoundException ex) {
|
} catch (FileNotFoundException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
final String msg = String.format("Unable to find file '%s'.",
|
final String msg = String.format("Unable to find file '%s'.", file.getName());
|
||||||
file.getName());
|
|
||||||
throw new ExtractionException(msg, ex);
|
throw new ExtractionException(msg, ex);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
final String msg = String
|
final String msg = String.format("IO Exception while parsing file '%s'.", file.getName());
|
||||||
.format("IO Exception while parsing file '%s'.",
|
|
||||||
file.getName());
|
|
||||||
throw new ExtractionException(msg, ex);
|
throw new ExtractionException(msg, ex);
|
||||||
} finally {
|
|
||||||
FileUtils.close(fos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -253,8 +220,7 @@ public final class ExtractionUtil {
|
|||||||
* @throws ExtractionException thrown if the parent paths could not be
|
* @throws ExtractionException thrown if the parent paths could not be
|
||||||
* created
|
* created
|
||||||
*/
|
*/
|
||||||
private static void createParentFile(final File file)
|
private static void createParentFile(final File file) throws ExtractionException {
|
||||||
throws ExtractionException {
|
|
||||||
final File parent = file.getParentFile();
|
final File parent = file.getParentFile();
|
||||||
if (!parent.isDirectory() && !parent.mkdirs()) {
|
if (!parent.isDirectory() && !parent.mkdirs()) {
|
||||||
final String msg = String.format(
|
final String msg = String.format(
|
||||||
@@ -282,35 +248,11 @@ public final class ExtractionUtil {
|
|||||||
if (!file.renameTo(gzip)) {
|
if (!file.renameTo(gzip)) {
|
||||||
throw new IOException("Unable to rename '" + file.getPath() + "'");
|
throw new IOException("Unable to rename '" + file.getPath() + "'");
|
||||||
}
|
}
|
||||||
final File newfile = new File(originalPath);
|
final File newFile = new File(originalPath);
|
||||||
|
try (GZIPInputStream cin = new GZIPInputStream(new FileInputStream(gzip));
|
||||||
final byte[] buffer = new byte[4096];
|
FileOutputStream out = new FileOutputStream(newFile)) {
|
||||||
|
IOUtils.copy(cin, out);
|
||||||
GZIPInputStream cin = null;
|
|
||||||
FileOutputStream out = null;
|
|
||||||
try {
|
|
||||||
cin = new GZIPInputStream(new FileInputStream(gzip));
|
|
||||||
out = new FileOutputStream(newfile);
|
|
||||||
|
|
||||||
int len;
|
|
||||||
while ((len = cin.read(buffer)) > 0) {
|
|
||||||
out.write(buffer, 0, len);
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
if (cin != null) {
|
|
||||||
try {
|
|
||||||
cin.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("ignore", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (out != null) {
|
|
||||||
try {
|
|
||||||
out.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("ignore", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (gzip.isFile() && !org.apache.commons.io.FileUtils.deleteQuietly(gzip)) {
|
if (gzip.isFile() && !org.apache.commons.io.FileUtils.deleteQuietly(gzip)) {
|
||||||
LOGGER.debug("Failed to delete temporary file when extracting 'gz' {}", gzip.toString());
|
LOGGER.debug("Failed to delete temporary file when extracting 'gz' {}", gzip.toString());
|
||||||
gzip.deleteOnExit();
|
gzip.deleteOnExit();
|
||||||
|
|||||||
@@ -48,15 +48,15 @@ public class FileFilterBuilder {
|
|||||||
/**
|
/**
|
||||||
* A set of filenames to filter.
|
* A set of filenames to filter.
|
||||||
*/
|
*/
|
||||||
private final Set<String> filenames = new HashSet<String>();
|
private final Set<String> filenames = new HashSet<>();
|
||||||
/**
|
/**
|
||||||
* A set of extensions to filter.
|
* A set of extensions to filter.
|
||||||
*/
|
*/
|
||||||
private final Set<String> extensions = new HashSet<String>();
|
private final Set<String> extensions = new HashSet<>();
|
||||||
/**
|
/**
|
||||||
* An array list of file filters.
|
* An array list of file filters.
|
||||||
*/
|
*/
|
||||||
private final List<IOFileFilter> fileFilters = new ArrayList<IOFileFilter>();
|
private final List<IOFileFilter> fileFilters = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new instance and return it. This method is for convenience in using the builder pattern within a single statement.
|
* Create a new instance and return it. This method is for convenience in using the builder pattern within a single statement.
|
||||||
@@ -125,10 +125,10 @@ public class FileFilterBuilder {
|
|||||||
}
|
}
|
||||||
final OrFileFilter filter = new OrFileFilter();
|
final OrFileFilter filter = new OrFileFilter();
|
||||||
if (!filenames.isEmpty()) {
|
if (!filenames.isEmpty()) {
|
||||||
filter.addFileFilter(new NameFileFilter(new ArrayList<String>(filenames)));
|
filter.addFileFilter(new NameFileFilter(new ArrayList<>(filenames)));
|
||||||
}
|
}
|
||||||
if (!extensions.isEmpty()) {
|
if (!extensions.isEmpty()) {
|
||||||
filter.addFileFilter(new SuffixFileFilter(new ArrayList<String>(extensions), IOCase.INSENSITIVE));
|
filter.addFileFilter(new SuffixFileFilter(new ArrayList<>(extensions), IOCase.INSENSITIVE));
|
||||||
}
|
}
|
||||||
for (IOFileFilter iof : fileFilters) {
|
for (IOFileFilter iof : fileFilters) {
|
||||||
filter.addFileFilter(iof);
|
filter.addFileFilter(iof);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ package org.owasp.dependencycheck.utils;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* This is an abstract filter that can be used to filter iterable list.
|
* This is an abstract filter that can be used to filter iterable list.
|
||||||
*
|
*
|
||||||
* This Filter class was copied from:
|
* This Filter class was copied from:
|
||||||
@@ -11,15 +11,35 @@ import java.util.NoSuchElementException;
|
|||||||
*
|
*
|
||||||
* Erik Rasmussen - © 2006 - 2012 All Rights Reserved. @author Erik Rasmussen
|
* Erik Rasmussen - © 2006 - 2012 All Rights Reserved. @author Erik Rasmussen
|
||||||
* https://plus.google.com/115403795880834599019/?rel=author
|
* https://plus.google.com/115403795880834599019/?rel=author
|
||||||
|
*
|
||||||
|
* @param <T> the type to filter
|
||||||
*/
|
*/
|
||||||
public abstract class Filter<T> {
|
public abstract class Filter<T> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines whether the object passes the filter.
|
||||||
|
*
|
||||||
|
* @param object the object to test
|
||||||
|
* @return whether or not the object passes the filter
|
||||||
|
*/
|
||||||
public abstract boolean passes(T object);
|
public abstract boolean passes(T object);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters a given iterator.
|
||||||
|
*
|
||||||
|
* @param iterator the iterator to filter
|
||||||
|
* @return the filtered iterator
|
||||||
|
*/
|
||||||
public Iterator<T> filter(Iterator<T> iterator) {
|
public Iterator<T> filter(Iterator<T> iterator) {
|
||||||
return new FilterIterator(iterator);
|
return new FilterIterator(iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters a given iterable.
|
||||||
|
*
|
||||||
|
* @param iterable the iterable to filter
|
||||||
|
* @return the filtered iterable
|
||||||
|
*/
|
||||||
public Iterable<T> filter(final Iterable<T> iterable) {
|
public Iterable<T> filter(final Iterable<T> iterable) {
|
||||||
return new Iterable<T>() {
|
return new Iterable<T>() {
|
||||||
|
|
||||||
|
|||||||
@@ -47,8 +47,8 @@ public final class UrlStringUtils {
|
|||||||
private static final Pattern IS_URL_TEST = Pattern.compile("^(ht|f)tps?://.*", Pattern.CASE_INSENSITIVE);
|
private static final Pattern IS_URL_TEST = Pattern.compile("^(ht|f)tps?://.*", Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests if the text provided contains a URL. This is somewhat limited search in that it only looks for
|
* Tests if the text provided contains a URL. This is somewhat limited
|
||||||
* (ftp|http|https)://
|
* search in that it only looks for (ftp|http|https)://
|
||||||
*
|
*
|
||||||
* @param text the text to search
|
* @param text the text to search
|
||||||
* @return true if the text contains a url, otherwise false
|
* @return true if the text contains a url, otherwise false
|
||||||
@@ -67,14 +67,16 @@ public final class UrlStringUtils {
|
|||||||
return IS_URL_TEST.matcher(text).matches();
|
return IS_URL_TEST.matcher(text).matches();
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* A listing of domain parts that should not be used as evidence. Yes, this is an incomplete list.
|
* A listing of domain parts that should not be used as evidence. Yes, this
|
||||||
|
* is an incomplete list.
|
||||||
*/
|
*/
|
||||||
private static final Set<String> IGNORE_LIST = new HashSet<String>(
|
private static final Set<String> IGNORE_LIST = new HashSet<>(
|
||||||
Arrays.asList("www", "com", "org", "gov", "info", "name", "net", "pro", "tel", "mobi", "xxx"));
|
Arrays.asList("www", "com", "org", "gov", "info", "name", "net", "pro", "tel", "mobi", "xxx"));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Takes a URL, in String format, and adds the important parts of the URL to a list of strings.</p>
|
* Takes a URL, in String format, and adds the important parts of the URL to
|
||||||
|
* a list of strings.</p>
|
||||||
* <p>
|
* <p>
|
||||||
* Example, given the following input:</p>
|
* Example, given the following input:</p>
|
||||||
* <code>"https://www.somedomain.com/path1/path2/file.php?id=439"</code>
|
* <code>"https://www.somedomain.com/path1/path2/file.php?id=439"</code>
|
||||||
@@ -87,7 +89,7 @@ public final class UrlStringUtils {
|
|||||||
* @throws MalformedURLException thrown if the URL is malformed
|
* @throws MalformedURLException thrown if the URL is malformed
|
||||||
*/
|
*/
|
||||||
public static List<String> extractImportantUrlData(String text) throws MalformedURLException {
|
public static List<String> extractImportantUrlData(String text) throws MalformedURLException {
|
||||||
final List<String> importantParts = new ArrayList<String>();
|
final List<String> importantParts = new ArrayList<>();
|
||||||
final URL url = new URL(text);
|
final URL url = new URL(text);
|
||||||
final String[] domain = url.getHost().split("\\.");
|
final String[] domain = url.getHost().split("\\.");
|
||||||
//add the domain except www and the tld.
|
//add the domain except www and the tld.
|
||||||
@@ -99,14 +101,21 @@ public final class UrlStringUtils {
|
|||||||
}
|
}
|
||||||
final String document = url.getPath();
|
final String document = url.getPath();
|
||||||
final String[] pathParts = document.split("[\\//]");
|
final String[] pathParts = document.split("[\\//]");
|
||||||
for (int i = 0; i < pathParts.length - 2; i++) {
|
for (int i = 0; i < pathParts.length - 1; i++) {
|
||||||
if (!pathParts[i].isEmpty()) {
|
if (!pathParts[i].isEmpty()) {
|
||||||
importantParts.add(pathParts[i]);
|
importantParts.add(pathParts[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pathParts.length > 0 && !pathParts[pathParts.length - 1].isEmpty()) {
|
if (pathParts.length > 0 && !pathParts[pathParts.length - 1].isEmpty()) {
|
||||||
final String fileNameNoExt = pathParts[pathParts.length - 1].replaceAll("\\..*{0,5}$", "");
|
final String tmp = pathParts[pathParts.length - 1];
|
||||||
importantParts.add(fileNameNoExt);
|
final int pos = tmp.lastIndexOf('.');
|
||||||
|
if (pos > 1) {
|
||||||
|
importantParts.add(tmp.substring(0, pos));
|
||||||
|
} else if (pos == 0 && tmp.length() > 1) {
|
||||||
|
importantParts.add(tmp.substring(1));
|
||||||
|
} else {
|
||||||
|
importantParts.add(tmp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return importantParts;
|
return importantParts;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,8 +149,17 @@ public class HintHandler extends DefaultHandler {
|
|||||||
* Internal type to track the parent node state.
|
* Internal type to track the parent node state.
|
||||||
*/
|
*/
|
||||||
enum ParentType {
|
enum ParentType {
|
||||||
|
/**
|
||||||
|
* Marks the add node.
|
||||||
|
*/
|
||||||
ADD,
|
ADD,
|
||||||
|
/**
|
||||||
|
* Marks the given node.
|
||||||
|
*/
|
||||||
GIVEN,
|
GIVEN,
|
||||||
|
/**
|
||||||
|
* Marks the remove node.
|
||||||
|
*/
|
||||||
REMOVE
|
REMOVE
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -79,38 +79,19 @@ public class HintParser {
|
|||||||
* @throws HintParseException thrown if the XML file cannot be parsed
|
* @throws HintParseException thrown if the XML file cannot be parsed
|
||||||
*/
|
*/
|
||||||
public Hints parseHints(File file) throws HintParseException {
|
public Hints parseHints(File file) throws HintParseException {
|
||||||
FileInputStream fis = null;
|
//TODO there must be a better way to determine which schema to use for validation.
|
||||||
try {
|
try {
|
||||||
fis = new FileInputStream(file);
|
try (FileInputStream fis = new FileInputStream(file)) {
|
||||||
return parseHints(fis);
|
return parseHints(fis);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new HintParseException(ex);
|
|
||||||
} catch (SAXException ex) {
|
|
||||||
try {
|
|
||||||
if (fis != null) {
|
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
} catch (IOException ex1) {
|
|
||||||
LOGGER.debug("Unable to close stream", ex1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fis = new FileInputStream(file);
|
|
||||||
} catch (FileNotFoundException ex1) {
|
|
||||||
throw new HintParseException(ex1);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return parseHints(fis, HINT_SCHEMA_OLD);
|
|
||||||
} catch (SAXException ex1) {
|
|
||||||
throw new HintParseException(ex);
|
throw new HintParseException(ex);
|
||||||
}
|
}
|
||||||
} finally {
|
} catch (SAXException ex) {
|
||||||
if (fis != null) {
|
try (FileInputStream fis = new FileInputStream(file)) {
|
||||||
try {
|
return parseHints(fis, HINT_SCHEMA_OLD);
|
||||||
fis.close();
|
} catch (SAXException | IOException ex1) {
|
||||||
} catch (IOException ex) {
|
throw new HintParseException(ex);
|
||||||
LOGGER.debug("Unable to close stream", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -139,24 +120,21 @@ public class HintParser {
|
|||||||
* @throws SAXException thrown if the XML cannot be parsed
|
* @throws SAXException thrown if the XML cannot be parsed
|
||||||
*/
|
*/
|
||||||
private Hints parseHints(InputStream inputStream, String schema) throws HintParseException, SAXException {
|
private Hints parseHints(InputStream inputStream, String schema) throws HintParseException, SAXException {
|
||||||
InputStream schemaStream = null;
|
try (InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(schema)) {
|
||||||
try {
|
|
||||||
schemaStream = this.getClass().getClassLoader().getResourceAsStream(schema);
|
|
||||||
final HintHandler handler = new HintHandler();
|
final HintHandler handler = new HintHandler();
|
||||||
final SAXParser saxParser = XmlUtils.buildSecureSaxParser(schemaStream);
|
final SAXParser saxParser = XmlUtils.buildSecureSaxParser(schemaStream);
|
||||||
final XMLReader xmlReader = saxParser.getXMLReader();
|
final XMLReader xmlReader = saxParser.getXMLReader();
|
||||||
xmlReader.setErrorHandler(new HintErrorHandler());
|
xmlReader.setErrorHandler(new HintErrorHandler());
|
||||||
xmlReader.setContentHandler(handler);
|
xmlReader.setContentHandler(handler);
|
||||||
|
try (Reader reader = new InputStreamReader(inputStream, "UTF-8")) {
|
||||||
final Reader reader = new InputStreamReader(inputStream, "UTF-8");
|
final InputSource in = new InputSource(reader);
|
||||||
final InputSource in = new InputSource(reader);
|
xmlReader.parse(in);
|
||||||
|
final Hints hints = new Hints();
|
||||||
xmlReader.parse(in);
|
hints.setHintRules(handler.getHintRules());
|
||||||
final Hints hints = new Hints();
|
hints.setVendorDuplicatingHintRules(handler.getVendorDuplicatingHintRules());
|
||||||
hints.setHintRules(handler.getHintRules());
|
return hints;
|
||||||
hints.setVendorDuplicatingHintRules(handler.getVendorDuplicatingHintRules());
|
}
|
||||||
return hints;
|
} catch (ParserConfigurationException | FileNotFoundException ex) {
|
||||||
} catch (ParserConfigurationException ex) {
|
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new HintParseException(ex);
|
throw new HintParseException(ex);
|
||||||
} catch (SAXException ex) {
|
} catch (SAXException ex) {
|
||||||
@@ -166,20 +144,9 @@ public class HintParser {
|
|||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new HintParseException(ex);
|
throw new HintParseException(ex);
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException ex) {
|
|
||||||
LOGGER.debug("", ex);
|
|
||||||
throw new HintParseException(ex);
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new HintParseException(ex);
|
throw new HintParseException(ex);
|
||||||
} finally {
|
|
||||||
if (schemaStream != null) {
|
|
||||||
try {
|
|
||||||
schemaStream.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.debug("Error closing hint file stream", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -255,7 +255,7 @@ public class HintRule {
|
|||||||
return removeVersion;
|
return removeVersion;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Adds a given version to the list of evidence to matche.
|
* Adds a given version to the list of evidence to match.
|
||||||
*
|
*
|
||||||
* @param source the source of the evidence
|
* @param source the source of the evidence
|
||||||
* @param name the name of the evidence
|
* @param name the name of the evidence
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ public class Model {
|
|||||||
/**
|
/**
|
||||||
* The list of licenses.
|
* The list of licenses.
|
||||||
*/
|
*/
|
||||||
private final List<License> licenses = new ArrayList<License>();
|
private final List<License> licenses = new ArrayList<>();
|
||||||
/**
|
/**
|
||||||
* The project URL.
|
* The project URL.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ public class PomHandler extends DefaultHandler {
|
|||||||
/**
|
/**
|
||||||
* The stack of elements processed; used to determine the parent node.
|
* The stack of elements processed; used to determine the parent node.
|
||||||
*/
|
*/
|
||||||
private final Deque<String> stack = new ArrayDeque<String>();
|
private final Deque<String> stack = new ArrayDeque<>();
|
||||||
/**
|
/**
|
||||||
* The license object.
|
* The license object.
|
||||||
*/
|
*/
|
||||||
@@ -132,66 +132,77 @@ public class PomHandler extends DefaultHandler {
|
|||||||
public void endElement(String uri, String localName, String qName) throws SAXException {
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
final String parentNode = stack.peek();
|
final String parentNode = stack.peek();
|
||||||
if (null != parentNode) switch (parentNode) {
|
if (null != parentNode) {
|
||||||
case PROJECT:
|
switch (parentNode) {
|
||||||
if (null != qName) switch (qName) {
|
case PROJECT:
|
||||||
case GROUPID:
|
if (null != qName) {
|
||||||
model.setGroupId(currentText.toString());
|
switch (qName) {
|
||||||
break;
|
case GROUPID:
|
||||||
case ARTIFACTID:
|
model.setGroupId(currentText.toString());
|
||||||
model.setArtifactId(currentText.toString());
|
break;
|
||||||
break;
|
case ARTIFACTID:
|
||||||
case VERSION:
|
model.setArtifactId(currentText.toString());
|
||||||
model.setVersion(currentText.toString());
|
break;
|
||||||
break;
|
case VERSION:
|
||||||
case NAME:
|
model.setVersion(currentText.toString());
|
||||||
model.setName(currentText.toString());
|
break;
|
||||||
break;
|
case NAME:
|
||||||
case DESCRIPTION:
|
model.setName(currentText.toString());
|
||||||
model.setDescription(currentText.toString());
|
break;
|
||||||
break;
|
case DESCRIPTION:
|
||||||
case URL:
|
model.setDescription(currentText.toString());
|
||||||
model.setProjectURL(currentText.toString());
|
break;
|
||||||
break;
|
case URL:
|
||||||
default:
|
model.setProjectURL(currentText.toString());
|
||||||
break;
|
break;
|
||||||
} break;
|
default:
|
||||||
case ORGANIZATION:
|
break;
|
||||||
if (NAME.equals(qName)) {
|
}
|
||||||
model.setOrganization(currentText.toString());
|
}
|
||||||
} else if (URL.equals(qName)) {
|
break;
|
||||||
model.setOrganizationUrl(currentText.toString());
|
case ORGANIZATION:
|
||||||
} break;
|
|
||||||
case PARENT:
|
|
||||||
if (null != qName) switch (qName) {
|
|
||||||
case GROUPID:
|
|
||||||
model.setParentGroupId(currentText.toString());
|
|
||||||
break;
|
|
||||||
case ARTIFACTID:
|
|
||||||
model.setParentArtifactId(currentText.toString());
|
|
||||||
break;
|
|
||||||
case VERSION:
|
|
||||||
model.setParentVersion(currentText.toString());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
} break;
|
|
||||||
case LICENSE:
|
|
||||||
if (license != null) {
|
|
||||||
if (NAME.equals(qName)) {
|
if (NAME.equals(qName)) {
|
||||||
license.setName(currentText.toString());
|
model.setOrganization(currentText.toString());
|
||||||
} else if (URL.equals(qName)) {
|
} else if (URL.equals(qName)) {
|
||||||
license.setUrl(currentText.toString());
|
model.setOrganizationUrl(currentText.toString());
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
case LICENSES:
|
case PARENT:
|
||||||
if (LICENSE.equals(qName)) {
|
if (null != qName) {
|
||||||
|
switch (qName) {
|
||||||
|
case GROUPID:
|
||||||
|
model.setParentGroupId(currentText.toString());
|
||||||
|
break;
|
||||||
|
case ARTIFACTID:
|
||||||
|
model.setParentArtifactId(currentText.toString());
|
||||||
|
break;
|
||||||
|
case VERSION:
|
||||||
|
model.setParentVersion(currentText.toString());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case LICENSE:
|
||||||
if (license != null) {
|
if (license != null) {
|
||||||
model.addLicense(license);
|
if (NAME.equals(qName)) {
|
||||||
|
license.setName(currentText.toString());
|
||||||
|
} else if (URL.equals(qName)) {
|
||||||
|
license.setUrl(currentText.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} break;
|
break;
|
||||||
default:
|
case LICENSES:
|
||||||
break;
|
if (LICENSE.equals(qName)) {
|
||||||
|
if (license != null) {
|
||||||
|
model.addLicense(license);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,21 +58,11 @@ public class PomParser {
|
|||||||
* @throws PomParseException thrown if the xml file cannot be parsed
|
* @throws PomParseException thrown if the xml file cannot be parsed
|
||||||
*/
|
*/
|
||||||
public Model parse(File file) throws PomParseException {
|
public Model parse(File file) throws PomParseException {
|
||||||
FileInputStream fis = null;
|
try (FileInputStream fis = new FileInputStream(file)) {
|
||||||
try {
|
|
||||||
fis = new FileInputStream(file);
|
|
||||||
return parse(fis);
|
return parse(fis);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new PomParseException(ex);
|
throw new PomParseException(ex);
|
||||||
} finally {
|
|
||||||
if (fis != null) {
|
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.debug("Unable to close stream", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,18 +80,15 @@ public class PomParser {
|
|||||||
final SAXParser saxParser = XmlUtils.buildSecureSaxParser();
|
final SAXParser saxParser = XmlUtils.buildSecureSaxParser();
|
||||||
final XMLReader xmlReader = saxParser.getXMLReader();
|
final XMLReader xmlReader = saxParser.getXMLReader();
|
||||||
xmlReader.setContentHandler(handler);
|
xmlReader.setContentHandler(handler);
|
||||||
BOMInputStream bomStream = new BOMInputStream(inputStream);
|
final BOMInputStream bomStream = new BOMInputStream(inputStream);
|
||||||
ByteOrderMark bom = bomStream.getBOM();
|
final ByteOrderMark bom = bomStream.getBOM();
|
||||||
String defaultEncoding = "UTF-8";
|
final String defaultEncoding = "UTF-8";
|
||||||
String charsetName = bom == null ? defaultEncoding : bom.getCharsetName();
|
final String charsetName = bom == null ? defaultEncoding : bom.getCharsetName();
|
||||||
final Reader reader = new InputStreamReader(bomStream, charsetName);
|
final Reader reader = new InputStreamReader(bomStream, charsetName);
|
||||||
final InputSource in = new InputSource(reader);
|
final InputSource in = new InputSource(reader);
|
||||||
xmlReader.parse(in);
|
xmlReader.parse(in);
|
||||||
return handler.getModel();
|
return handler.getModel();
|
||||||
} catch (ParserConfigurationException | SAXException ex) {
|
} catch (ParserConfigurationException | SAXException | FileNotFoundException ex) {
|
||||||
LOGGER.debug("", ex);
|
|
||||||
throw new PomParseException(ex);
|
|
||||||
} catch (FileNotFoundException ex) {
|
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new PomParseException(ex);
|
throw new PomParseException(ex);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
package org.owasp.dependencycheck.xml.suppression;
|
package org.owasp.dependencycheck.xml.suppression;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.utils.XmlUtils;
|
import org.owasp.dependencycheck.utils.XmlUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.xml.sax.ErrorHandler;
|
import org.xml.sax.ErrorHandler;
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.SAXParseException;
|
import org.xml.sax.SAXParseException;
|
||||||
@@ -32,7 +34,7 @@ public class SuppressionErrorHandler implements ErrorHandler {
|
|||||||
/**
|
/**
|
||||||
* The logger.
|
* The logger.
|
||||||
*/
|
*/
|
||||||
//private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionErrorHandler.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(SuppressionErrorHandler.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs warnings.
|
* Logs warnings.
|
||||||
@@ -42,7 +44,7 @@ public class SuppressionErrorHandler implements ErrorHandler {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void warning(SAXParseException ex) throws SAXException {
|
public void warning(SAXParseException ex) throws SAXException {
|
||||||
//LOGGER.debug("", ex);
|
LOGGER.trace("", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,7 +62,7 @@ public class SuppressionErrorHandler implements ErrorHandler {
|
|||||||
* Handles fatal exceptions.
|
* Handles fatal exceptions.
|
||||||
*
|
*
|
||||||
* @param ex a fatal exception
|
* @param ex a fatal exception
|
||||||
* @throws SAXException is always
|
* @throws SAXException is always thrown
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void fatalError(SAXParseException ex) throws SAXException {
|
public void fatalError(SAXParseException ex) throws SAXException {
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class SuppressionHandler extends DefaultHandler {
|
|||||||
/**
|
/**
|
||||||
* A list of suppression rules.
|
* A list of suppression rules.
|
||||||
*/
|
*/
|
||||||
private final List<SuppressionRule> suppressionRules = new ArrayList<SuppressionRule>();
|
private final List<SuppressionRule> suppressionRules = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of suppressionRules.
|
* Get the value of suppressionRules.
|
||||||
|
|||||||
@@ -64,39 +64,19 @@ public class SuppressionParser {
|
|||||||
* @throws SuppressionParseException thrown if the XML file cannot be parsed
|
* @throws SuppressionParseException thrown if the XML file cannot be parsed
|
||||||
*/
|
*/
|
||||||
public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException {
|
public List<SuppressionRule> parseSuppressionRules(File file) throws SuppressionParseException {
|
||||||
FileInputStream fis = null;
|
|
||||||
try {
|
try {
|
||||||
fis = new FileInputStream(file);
|
try (FileInputStream fis = new FileInputStream(file)) {
|
||||||
return parseSuppressionRules(fis);
|
return parseSuppressionRules(fis);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new SuppressionParseException(ex);
|
throw new SuppressionParseException(ex);
|
||||||
|
}
|
||||||
} catch (SAXException ex) {
|
} catch (SAXException ex) {
|
||||||
try {
|
try (FileInputStream fis = new FileInputStream(file)) {
|
||||||
if (fis != null) {
|
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
} catch (IOException ex1) {
|
|
||||||
LOGGER.debug("Unable to close stream", ex1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fis = new FileInputStream(file);
|
|
||||||
} catch (FileNotFoundException ex1) {
|
|
||||||
throw new SuppressionParseException(ex);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return parseSuppressionRules(fis, OLD_SUPPRESSION_SCHEMA);
|
return parseSuppressionRules(fis, OLD_SUPPRESSION_SCHEMA);
|
||||||
} catch (SAXException ex1) {
|
} catch (SAXException | IOException ex1) {
|
||||||
throw new SuppressionParseException(ex);
|
throw new SuppressionParseException(ex);
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
if (fis != null) {
|
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.debug("Unable to close stream", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,19 +104,18 @@ public class SuppressionParser {
|
|||||||
* @throws SAXException thrown if the XML cannot be parsed
|
* @throws SAXException thrown if the XML cannot be parsed
|
||||||
*/
|
*/
|
||||||
private List<SuppressionRule> parseSuppressionRules(InputStream inputStream, String schema) throws SuppressionParseException, SAXException {
|
private List<SuppressionRule> parseSuppressionRules(InputStream inputStream, String schema) throws SuppressionParseException, SAXException {
|
||||||
InputStream schemaStream = null;
|
try (InputStream schemaStream = this.getClass().getClassLoader().getResourceAsStream(schema)) {
|
||||||
try {
|
|
||||||
schemaStream = this.getClass().getClassLoader().getResourceAsStream(schema);
|
|
||||||
final SuppressionHandler handler = new SuppressionHandler();
|
final SuppressionHandler handler = new SuppressionHandler();
|
||||||
final SAXParser saxParser = XmlUtils.buildSecureSaxParser(schemaStream);
|
final SAXParser saxParser = XmlUtils.buildSecureSaxParser(schemaStream);
|
||||||
final XMLReader xmlReader = saxParser.getXMLReader();
|
final XMLReader xmlReader = saxParser.getXMLReader();
|
||||||
xmlReader.setErrorHandler(new SuppressionErrorHandler());
|
xmlReader.setErrorHandler(new SuppressionErrorHandler());
|
||||||
xmlReader.setContentHandler(handler);
|
xmlReader.setContentHandler(handler);
|
||||||
final Reader reader = new InputStreamReader(inputStream, "UTF-8");
|
try (Reader reader = new InputStreamReader(inputStream, "UTF-8")) {
|
||||||
final InputSource in = new InputSource(reader);
|
final InputSource in = new InputSource(reader);
|
||||||
xmlReader.parse(in);
|
xmlReader.parse(in);
|
||||||
return handler.getSuppressionRules();
|
return handler.getSuppressionRules();
|
||||||
} catch (ParserConfigurationException ex) {
|
}
|
||||||
|
} catch (ParserConfigurationException | FileNotFoundException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new SuppressionParseException(ex);
|
throw new SuppressionParseException(ex);
|
||||||
} catch (SAXException ex) {
|
} catch (SAXException ex) {
|
||||||
@@ -146,20 +125,9 @@ public class SuppressionParser {
|
|||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new SuppressionParseException(ex);
|
throw new SuppressionParseException(ex);
|
||||||
}
|
}
|
||||||
} catch (FileNotFoundException ex) {
|
|
||||||
LOGGER.debug("", ex);
|
|
||||||
throw new SuppressionParseException(ex);
|
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
throw new SuppressionParseException(ex);
|
throw new SuppressionParseException(ex);
|
||||||
} finally {
|
|
||||||
if (schemaStream != null) {
|
|
||||||
try {
|
|
||||||
schemaStream.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.debug("Error closing suppression file stream", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
# Copyright (c) 2015 The OWASP Foundatio. All Rights Reserved.
|
# Copyright (c) 2015 The OWASP Foundation. All Rights Reserved.
|
||||||
|
|
||||||
DELETE_REFERENCE=DELETE FROM reference WHERE cveid = ?
|
DELETE_REFERENCE=DELETE FROM reference WHERE cveid = ?
|
||||||
DELETE_SOFTWARE=DELETE FROM software WHERE cveid = ?
|
DELETE_SOFTWARE=DELETE FROM software WHERE cveid = ?
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
|
|
||||||
<xsd:simpleType name="cweNamePatternType">
|
<xsd:simpleType name="cweNamePatternType">
|
||||||
<xsd:restriction base="xsd:token">
|
<xsd:restriction base="xsd:token">
|
||||||
<xsd:pattern value="CWE-[1-9]\d{0,5}"></xsd:pattern>
|
<xsd:pattern value="CWE-[1-9]\d{0,5}"/>
|
||||||
</xsd:restriction>
|
</xsd:restriction>
|
||||||
</xsd:simpleType>
|
</xsd:simpleType>
|
||||||
</xsd:schema>
|
</xsd:schema>
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.io.FileInputStream;
|
|||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
import org.apache.commons.compress.utils.IOUtils;
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
import org.owasp.dependencycheck.data.nvdcve.CveDB;
|
||||||
@@ -54,12 +55,10 @@ public abstract class BaseDBTestCase extends BaseTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void ensureDBExists() throws Exception {
|
public static void ensureDBExists() throws Exception {
|
||||||
|
|
||||||
File f = new File("./target/data/dc.h2.db");
|
File f = new File("./target/data/dc.h2.db");
|
||||||
if (f.exists() && f.isFile() && f.length() < 71680) {
|
if (f.exists() && f.isFile() && f.length() < 71680) {
|
||||||
f.delete();
|
f.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
File dataPath = Settings.getDataDirectory();
|
File dataPath = Settings.getDataDirectory();
|
||||||
String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME);
|
String fileName = Settings.getString(Settings.KEYS.DB_FILE_NAME);
|
||||||
LOGGER.trace("DB file name {}", fileName);
|
LOGGER.trace("DB file name {}", fileName);
|
||||||
@@ -68,12 +67,9 @@ public abstract class BaseDBTestCase extends BaseTest {
|
|||||||
if (!dataPath.exists() || !dataFile.exists()) {
|
if (!dataPath.exists() || !dataFile.exists()) {
|
||||||
LOGGER.trace("Extracting database to {}", dataPath.toString());
|
LOGGER.trace("Extracting database to {}", dataPath.toString());
|
||||||
dataPath.mkdirs();
|
dataPath.mkdirs();
|
||||||
FileInputStream fis = null;
|
File path = new File(BaseDBTestCase.class.getClassLoader().getResource("data.zip").toURI().getPath());
|
||||||
ZipInputStream zin = null;
|
try (FileInputStream fis = new FileInputStream(path);
|
||||||
try {
|
ZipInputStream zin = new ZipInputStream(new BufferedInputStream(fis))) {
|
||||||
File path = new File(BaseDBTestCase.class.getClassLoader().getResource("data.zip").toURI().getPath());
|
|
||||||
fis = new FileInputStream(path);
|
|
||||||
zin = new ZipInputStream(new BufferedInputStream(fis));
|
|
||||||
ZipEntry entry;
|
ZipEntry entry;
|
||||||
while ((entry = zin.getNextEntry()) != null) {
|
while ((entry = zin.getNextEntry()) != null) {
|
||||||
if (entry.isDirectory()) {
|
if (entry.isDirectory()) {
|
||||||
@@ -81,53 +77,15 @@ public abstract class BaseDBTestCase extends BaseTest {
|
|||||||
d.mkdir();
|
d.mkdir();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
FileOutputStream fos = null;
|
File o = new File(dataPath, entry.getName());
|
||||||
BufferedOutputStream dest = null;
|
o.createNewFile();
|
||||||
try {
|
try (FileOutputStream fos = new FileOutputStream(o, false);
|
||||||
File o = new File(dataPath, entry.getName());
|
BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER_SIZE)) {
|
||||||
o.createNewFile();
|
IOUtils.copy(zin, dest);
|
||||||
fos = new FileOutputStream(o, false);
|
|
||||||
dest = new BufferedOutputStream(fos, BUFFER_SIZE);
|
|
||||||
byte data[] = new byte[BUFFER_SIZE];
|
|
||||||
int count;
|
|
||||||
while ((count = zin.read(data, 0, BUFFER_SIZE)) != -1) {
|
|
||||||
dest.write(data, 0, count);
|
|
||||||
}
|
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
LOGGER.error("", ex);
|
LOGGER.error("", ex);
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (dest != null) {
|
|
||||||
dest.flush();
|
|
||||||
dest.close();
|
|
||||||
}
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (fos != null) {
|
|
||||||
fos.close();
|
|
||||||
}
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (zin != null) {
|
|
||||||
zin.close();
|
|
||||||
}
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
if (fis != null) {
|
|
||||||
fis.close();
|
|
||||||
}
|
|
||||||
} catch (Throwable ex) {
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,20 +22,24 @@ import static org.junit.Assert.assertTrue;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.AfterClass;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.owasp.dependencycheck.BaseTest;
|
import org.owasp.dependencycheck.BaseTest;
|
||||||
import org.owasp.dependencycheck.dependency.Dependency;
|
import org.owasp.dependencycheck.dependency.Dependency;
|
||||||
import org.owasp.dependencycheck.dependency.Evidence;
|
import org.owasp.dependencycheck.dependency.Evidence;
|
||||||
|
import org.owasp.dependencycheck.utils.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class JarAnalyzerTest extends BaseTest {
|
public class JarAnalyzerTest extends BaseTest {
|
||||||
|
|
||||||
// private static final Logger LOGGER = LoggerFactory.getLogger(JarAnalyzerTest.class);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test of inspect method, of class JarAnalyzer.
|
* Test of inspect method, of class JarAnalyzer.
|
||||||
*
|
*
|
||||||
@@ -58,7 +62,7 @@ public class JarAnalyzerTest extends BaseTest {
|
|||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (Evidence e : result.getVendorEvidence()) {
|
for (Evidence e : result.getVendorEvidence()) {
|
||||||
if (e.getName().equals("url")) {
|
if (e.getName().equals("url")) {
|
||||||
assertEquals("Project url was not as expected in dwr.jar", e.getValue(), "http://getahead.ltd.uk/dwr");
|
assertEquals("Project url was not as expected in dwr.jar", e.getValue(), "http://getahead.ltd.uk/dwr");
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -136,9 +140,40 @@ public class JarAnalyzerTest extends BaseTest {
|
|||||||
File file = BaseTest.getResourceAsFile(this, "xalan-2.7.0.jar");
|
File file = BaseTest.getResourceAsFile(this, "xalan-2.7.0.jar");
|
||||||
Dependency result = new Dependency(file);
|
Dependency result = new Dependency(file);
|
||||||
JarAnalyzer instance = new JarAnalyzer();
|
JarAnalyzer instance = new JarAnalyzer();
|
||||||
List<JarAnalyzer.ClassNameInformation> cni = new ArrayList<JarAnalyzer.ClassNameInformation>();
|
List<JarAnalyzer.ClassNameInformation> cni = new ArrayList<>();
|
||||||
instance.parseManifest(result, cni);
|
instance.parseManifest(result, cni);
|
||||||
|
|
||||||
assertTrue(result.getVersionEvidence().getEvidence("manifest: org/apache/xalan/").size() > 0);
|
assertTrue(result.getVersionEvidence().getEvidence("manifest: org/apache/xalan/").size() > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of getAnalysisPhase method, of class JarAnalyzer.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetAnalysisPhase() {
|
||||||
|
JarAnalyzer instance = new JarAnalyzer();
|
||||||
|
AnalysisPhase expResult = AnalysisPhase.INFORMATION_COLLECTION;
|
||||||
|
AnalysisPhase result = instance.getAnalysisPhase();
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of getAnalyzerEnabledSettingKey method, of class JarAnalyzer.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testGetAnalyzerEnabledSettingKey() {
|
||||||
|
JarAnalyzer instance = new JarAnalyzer();
|
||||||
|
String expResult = Settings.KEYS.ANALYZER_JAR_ENABLED;
|
||||||
|
String result = instance.getAnalyzerEnabledSettingKey();
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testClassInformation() {
|
||||||
|
JarAnalyzer.ClassNameInformation instance = new JarAnalyzer.ClassNameInformation("org/owasp/dependencycheck/analyzer/JarAnalyzer");
|
||||||
|
assertEquals("org/owasp/dependencycheck/analyzer/JarAnalyzer", instance.getName());
|
||||||
|
List<String> expected = Arrays.asList("owasp", "dependencycheck", "analyzer", "jaranalyzer");
|
||||||
|
List<String> results = instance.getPackageStructure();
|
||||||
|
assertEquals(expected, results);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ import org.owasp.dependencycheck.utils.Settings;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
import org.owasp.dependencycheck.exception.InitializationException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unit tests for {@link RubyBundleAuditAnalyzer}.
|
* Unit tests for {@link RubyBundleAuditAnalyzer}.
|
||||||
@@ -122,7 +123,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
|
|||||||
assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2"));
|
assertTrue(dependency.getVersionEvidence().toString().toLowerCase().contains("2.2.2"));
|
||||||
assertTrue(dependency.getFilePath().endsWith(resource));
|
assertTrue(dependency.getFilePath().endsWith(resource));
|
||||||
assertTrue(dependency.getFileName().equals("Gemfile.lock"));
|
assertTrue(dependency.getFileName().equals("Gemfile.lock"));
|
||||||
} catch (Exception e) {
|
} catch (InitializationException | DatabaseException | AnalysisException e) {
|
||||||
LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\".");
|
LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\".");
|
||||||
Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e);
|
Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e);
|
||||||
}
|
}
|
||||||
@@ -145,7 +146,7 @@ public class RubyBundleAuditAnalyzerTest extends BaseDBTestCase {
|
|||||||
Vulnerability vulnerability = dependency.getVulnerabilities().first();
|
Vulnerability vulnerability = dependency.getVulnerabilities().first();
|
||||||
assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0);
|
assertEquals(vulnerability.getCvssScore(), 5.0f, 0.0);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (InitializationException | DatabaseException | AnalysisException e) {
|
||||||
LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\".");
|
LOGGER.warn("Exception setting up RubyBundleAuditAnalyzer. Make sure Ruby gem bundle-audit is installed. You may also need to set property \"analyzer.bundle.audit.path\".");
|
||||||
Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e);
|
Assume.assumeNoException("Exception setting up RubyBundleAuditAnalyzer; bundle audit may not be installed, or property \"analyzer.bundle.audit.path\" may not be set.", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,19 +61,19 @@ public class FieldAnalyzerTest extends BaseTest {
|
|||||||
String field2 = "vendor";
|
String field2 = "vendor";
|
||||||
String text2 = "springsource";
|
String text2 = "springsource";
|
||||||
|
|
||||||
IndexWriter w = createIndex(analyzer, index);
|
try (IndexWriter w = createIndex(analyzer, index)) {
|
||||||
addDoc(w, field1, text1, field2, text2);
|
addDoc(w, field1, text1, field2, text2);
|
||||||
text1 = "x-stream";
|
text1 = "x-stream";
|
||||||
text2 = "xstream";
|
text2 = "xstream";
|
||||||
addDoc(w, field1, text1, field2, text2);
|
addDoc(w, field1, text1, field2, text2);
|
||||||
w.close();
|
}
|
||||||
|
|
||||||
//Analyzer searchingAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
|
//Analyzer searchingAnalyzer = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
|
||||||
String querystr = "product:\"(Spring Framework Core)\" vendor:(SpringSource)";
|
String querystr = "product:\"(Spring Framework Core)\" vendor:(SpringSource)";
|
||||||
|
|
||||||
SearchFieldAnalyzer searchAnalyzerProduct = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
|
SearchFieldAnalyzer searchAnalyzerProduct = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
|
||||||
SearchFieldAnalyzer searchAnalyzerVendor = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
|
SearchFieldAnalyzer searchAnalyzerVendor = new SearchFieldAnalyzer(LuceneUtils.CURRENT_VERSION);
|
||||||
HashMap<String, Analyzer> map = new HashMap<String, Analyzer>();
|
HashMap<String, Analyzer> map = new HashMap<>();
|
||||||
map.put(field1, searchAnalyzerProduct);
|
map.put(field1, searchAnalyzerProduct);
|
||||||
map.put(field2, searchAnalyzerVendor);
|
map.put(field2, searchAnalyzerVendor);
|
||||||
PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer(LuceneUtils.CURRENT_VERSION), map);
|
PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(new StandardAnalyzer(LuceneUtils.CURRENT_VERSION), map);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import org.apache.lucene.analysis.core.KeywordTokenizer;
|
|||||||
*/
|
*/
|
||||||
public class UrlTokenizingFilterTest extends BaseTokenStreamTestCase {
|
public class UrlTokenizingFilterTest extends BaseTokenStreamTestCase {
|
||||||
|
|
||||||
private Analyzer analyzer;
|
private final Analyzer analyzer;
|
||||||
|
|
||||||
public UrlTokenizingFilterTest() {
|
public UrlTokenizingFilterTest() {
|
||||||
analyzer = new Analyzer() {
|
analyzer = new Analyzer() {
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ public class ConnectionFactoryTest extends BaseDBTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testInitialize() throws DatabaseException, SQLException {
|
public void testInitialize() throws DatabaseException, SQLException {
|
||||||
ConnectionFactory.initialize();
|
ConnectionFactory.initialize();
|
||||||
Connection result = ConnectionFactory.getConnection();
|
try (Connection result = ConnectionFactory.getConnection()) {
|
||||||
assertNotNull(result);
|
assertNotNull(result);
|
||||||
result.close();
|
}
|
||||||
ConnectionFactory.cleanup();
|
ConnectionFactory.cleanup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.data.update.nvd;
|
package org.owasp.dependencycheck.data.update.nvd;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.data.update.nvd.NvdCveInfo;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.owasp.dependencycheck.BaseTest;
|
import org.owasp.dependencycheck.BaseTest;
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.data.update.nvd;
|
package org.owasp.dependencycheck.data.update.nvd;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.data.update.nvd.NvdCve12Handler;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|||||||
@@ -17,10 +17,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.data.update.nvd;
|
package org.owasp.dependencycheck.data.update.nvd;
|
||||||
|
|
||||||
import org.owasp.dependencycheck.data.update.nvd.NvdCve20Handler;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.xml.parsers.SAXParser;
|
import javax.xml.parsers.SAXParser;
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
|
|
||||||
@@ -29,6 +30,7 @@ import static org.junit.Assert.assertTrue;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.owasp.dependencycheck.BaseTest;
|
import org.owasp.dependencycheck.BaseTest;
|
||||||
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
|
import org.owasp.dependencycheck.dependency.VulnerableSoftware;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@@ -49,7 +51,7 @@ public class NvdCve_2_0_HandlerTest extends BaseTest {
|
|||||||
NvdCve20Handler instance = new NvdCve20Handler();
|
NvdCve20Handler instance = new NvdCve20Handler();
|
||||||
|
|
||||||
saxParser.parse(file, instance);
|
saxParser.parse(file, instance);
|
||||||
} catch (Throwable ex) {
|
} catch (ParserConfigurationException | SAXException | IOException ex) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
results = ex;
|
results = ex;
|
||||||
}
|
}
|
||||||
@@ -80,7 +82,7 @@ public class NvdCve_2_0_HandlerTest extends BaseTest {
|
|||||||
saxParser.parse(file20, instance);
|
saxParser.parse(file20, instance);
|
||||||
|
|
||||||
assertTrue(instance.getTotalNumberOfEntries()==1);
|
assertTrue(instance.getTotalNumberOfEntries()==1);
|
||||||
} catch (Throwable ex) {
|
} catch (ParserConfigurationException | SAXException | IOException ex) {
|
||||||
results = ex;
|
results = ex;
|
||||||
}
|
}
|
||||||
assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null);
|
assertTrue("Exception thrown during parse of 2012 CVE version 2.0?", results == null);
|
||||||
|
|||||||
@@ -48,12 +48,12 @@ public class FilterTest extends BaseTest {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testFilter_Iterable() {
|
public void testFilter_Iterable() {
|
||||||
List<String> testData = new ArrayList<String>();
|
List<String> testData = new ArrayList<>();
|
||||||
testData.add("keep");
|
testData.add("keep");
|
||||||
testData.add("remove");
|
testData.add("remove");
|
||||||
testData.add("keep");
|
testData.add("keep");
|
||||||
|
|
||||||
List<String> expResults = new ArrayList<String>();
|
List<String> expResults = new ArrayList<>();
|
||||||
expResults.add("keep");
|
expResults.add("keep");
|
||||||
expResults.add("keep");
|
expResults.add("keep");
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,74 @@
|
|||||||
|
/*
|
||||||
|
* 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) 2017 Jeremy Long. All Rights Reserved.
|
||||||
|
*/
|
||||||
|
package org.owasp.dependencycheck.utils;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author jeremy long
|
||||||
|
*/
|
||||||
|
public class UrlStringUtilsTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of containsUrl method, of class UrlStringUtils.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testContainsUrl() {
|
||||||
|
String text = "Test of https://github.com";
|
||||||
|
assertTrue(UrlStringUtils.containsUrl(text));
|
||||||
|
text = "Test of github.com";
|
||||||
|
assertFalse(UrlStringUtils.containsUrl(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of isUrl method, of class UrlStringUtils.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testIsUrl() {
|
||||||
|
String text = "https://github.com";
|
||||||
|
assertTrue(UrlStringUtils.isUrl(text));
|
||||||
|
text = "simple text";
|
||||||
|
assertFalse(UrlStringUtils.isUrl(text));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test of extractImportantUrlData method, of class UrlStringUtils.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testExtractImportantUrlData() throws Exception {
|
||||||
|
String text = "http://github.com/jeremylong/DependencyCheck/index.html";
|
||||||
|
List<String> expResult = Arrays.asList("github", "jeremylong", "DependencyCheck", "index");;
|
||||||
|
List<String> result = UrlStringUtils.extractImportantUrlData(text);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
|
||||||
|
text = "http://github.com/jeremylong/DependencyCheck/.gitignore";
|
||||||
|
expResult = Arrays.asList("github", "jeremylong", "DependencyCheck", "gitignore");;
|
||||||
|
result = UrlStringUtils.extractImportantUrlData(text);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
|
||||||
|
text = "http://github.com/jeremylong/DependencyCheck/something";
|
||||||
|
expResult = Arrays.asList("github", "jeremylong", "DependencyCheck", "something");;
|
||||||
|
result = UrlStringUtils.extractImportantUrlData(text);
|
||||||
|
assertEquals(expResult, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -248,7 +248,7 @@ public class ModelTest extends BaseTest {
|
|||||||
public void testGetLicenses() {
|
public void testGetLicenses() {
|
||||||
Model instance = new Model();
|
Model instance = new Model();
|
||||||
instance.addLicense(new License("name", "url"));
|
instance.addLicense(new License("name", "url"));
|
||||||
List<License> expResult = new ArrayList<License>();
|
List<License> expResult = new ArrayList<>();
|
||||||
expResult.add(new License("name", "url"));
|
expResult.add(new License("name", "url"));
|
||||||
List<License> result = instance.getLicenses();
|
List<License> result = instance.getLicenses();
|
||||||
assertEquals(expResult, result);
|
assertEquals(expResult, result);
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ public class SuppressionRuleTest extends BaseTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testGetCvssBelow() {
|
public void testGetCvssBelow() {
|
||||||
SuppressionRule instance = new SuppressionRule();
|
SuppressionRule instance = new SuppressionRule();
|
||||||
List<Float> cvss = new ArrayList<Float>();
|
List<Float> cvss = new ArrayList<>();
|
||||||
instance.setCvssBelow(cvss);
|
instance.setCvssBelow(cvss);
|
||||||
assertFalse(instance.hasCvssBelow());
|
assertFalse(instance.hasCvssBelow());
|
||||||
instance.addCvssBelow(0.7f);
|
instance.addCvssBelow(0.7f);
|
||||||
@@ -101,7 +101,7 @@ public class SuppressionRuleTest extends BaseTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testCwe() {
|
public void testCwe() {
|
||||||
SuppressionRule instance = new SuppressionRule();
|
SuppressionRule instance = new SuppressionRule();
|
||||||
List<String> cwe = new ArrayList<String>();
|
List<String> cwe = new ArrayList<>();
|
||||||
instance.setCwe(cwe);
|
instance.setCwe(cwe);
|
||||||
assertFalse(instance.hasCwe());
|
assertFalse(instance.hasCwe());
|
||||||
instance.addCwe("2");
|
instance.addCwe("2");
|
||||||
@@ -116,7 +116,7 @@ public class SuppressionRuleTest extends BaseTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testCve() {
|
public void testCve() {
|
||||||
SuppressionRule instance = new SuppressionRule();
|
SuppressionRule instance = new SuppressionRule();
|
||||||
List<String> cve = new ArrayList<String>();
|
List<String> cve = new ArrayList<>();
|
||||||
instance.setCve(cve);
|
instance.setCve(cve);
|
||||||
assertFalse(instance.hasCve());
|
assertFalse(instance.hasCve());
|
||||||
instance.addCve("CVE-2013-1337");
|
instance.addCve("CVE-2013-1337");
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved.
|
|||||||
<version>${reporting.pmd-plugin.version}</version>
|
<version>${reporting.pmd-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetJdk>1.6</targetJdk>
|
<targetJdk>1.6</targetJdk>
|
||||||
<linkXref>true</linkXref>
|
<linkXRef>true</linkXRef>
|
||||||
<sourceEncoding>utf-8</sourceEncoding>
|
<sourceEncoding>utf-8</sourceEncoding>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/generated/**/*.java</exclude>
|
<exclude>**/generated/**/*.java</exclude>
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
* and generates the subsequent reports.
|
* and generates the subsequent reports.
|
||||||
*
|
*
|
||||||
* @throws MojoExecutionException thrown if there is ane exception running
|
* @throws MojoExecutionException thrown if there is ane exception running
|
||||||
* the mojo
|
* the Mojo
|
||||||
* @throws MojoFailureException thrown if dependency-check is configured to
|
* @throws MojoFailureException thrown if dependency-check is configured to
|
||||||
* fail the build
|
* fail the build
|
||||||
*/
|
*/
|
||||||
@@ -118,7 +118,7 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
}
|
}
|
||||||
File outputDir = getCorrectOutputDirectory(this.getProject());
|
File outputDir = getCorrectOutputDirectory(this.getProject());
|
||||||
if (outputDir == null) {
|
if (outputDir == null) {
|
||||||
//in some regards we shouldn't be writting this, but we are anyway.
|
//in some regards we shouldn't be writing this, but we are anyway.
|
||||||
//we shouldn't write this because nothing is configured to generate this report.
|
//we shouldn't write this because nothing is configured to generate this report.
|
||||||
outputDir = new File(this.getProject().getBuild().getDirectory());
|
outputDir = new File(this.getProject().getBuild().getDirectory());
|
||||||
}
|
}
|
||||||
@@ -153,8 +153,8 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
if (project == null) {
|
if (project == null) {
|
||||||
return Collections.emptySet();
|
return Collections.emptySet();
|
||||||
}
|
}
|
||||||
final Set<MavenProject> descendants = new HashSet<MavenProject>();
|
final Set<MavenProject> descendants = new HashSet<>();
|
||||||
int size = 0;
|
int size;
|
||||||
if (getLog().isDebugEnabled()) {
|
if (getLog().isDebugEnabled()) {
|
||||||
getLog().debug(String.format("Collecting descendants of %s", project.getName()));
|
getLog().debug(String.format("Collecting descendants of %s", project.getName()));
|
||||||
}
|
}
|
||||||
@@ -165,7 +165,7 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
mpp = mpp.getCanonicalFile();
|
mpp = mpp.getCanonicalFile();
|
||||||
if (mpp.compareTo(mod.getBasedir()) == 0 && descendants.add(mod)
|
if (mpp.compareTo(mod.getBasedir()) == 0 && descendants.add(mod)
|
||||||
&& getLog().isDebugEnabled()) {
|
&& getLog().isDebugEnabled()) {
|
||||||
getLog().debug(String.format("Decendent module %s added", mod.getName()));
|
getLog().debug(String.format("Descendant module %s added", mod.getName()));
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
@@ -180,18 +180,18 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
for (MavenProject p : getReactorProjects()) {
|
for (MavenProject p : getReactorProjects()) {
|
||||||
if (project.equals(p.getParent()) || descendants.contains(p.getParent())) {
|
if (project.equals(p.getParent()) || descendants.contains(p.getParent())) {
|
||||||
if (descendants.add(p) && getLog().isDebugEnabled()) {
|
if (descendants.add(p) && getLog().isDebugEnabled()) {
|
||||||
getLog().debug(String.format("Decendent %s added", p.getName()));
|
getLog().debug(String.format("Descendant %s added", p.getName()));
|
||||||
|
|
||||||
}
|
}
|
||||||
for (MavenProject modTest : getReactorProjects()) {
|
for (MavenProject modTest : getReactorProjects()) {
|
||||||
if (p.getModules() != null && p.getModules().contains(modTest.getName())
|
if (p.getModules() != null && p.getModules().contains(modTest.getName())
|
||||||
&& descendants.add(modTest)
|
&& descendants.add(modTest)
|
||||||
&& getLog().isDebugEnabled()) {
|
&& getLog().isDebugEnabled()) {
|
||||||
getLog().debug(String.format("Decendent %s added", modTest.getName()));
|
getLog().debug(String.format("Descendant %s added", modTest.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Set<MavenProject> addedDescendants = new HashSet<MavenProject>();
|
final Set<MavenProject> addedDescendants = new HashSet<>();
|
||||||
for (MavenProject dec : descendants) {
|
for (MavenProject dec : descendants) {
|
||||||
for (String mod : dec.getModules()) {
|
for (String mod : dec.getModules()) {
|
||||||
try {
|
try {
|
||||||
@@ -209,7 +209,7 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
}
|
}
|
||||||
for (MavenProject addedDescendant : addedDescendants) {
|
for (MavenProject addedDescendant : addedDescendants) {
|
||||||
if (descendants.add(addedDescendant) && getLog().isDebugEnabled()) {
|
if (descendants.add(addedDescendant) && getLog().isDebugEnabled()) {
|
||||||
getLog().debug(String.format("Decendent module %s added", addedDescendant.getName()));
|
getLog().debug(String.format("Descendant module %s added", addedDescendant.getName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -259,7 +259,7 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canGenerateReport() {
|
public boolean canGenerateReport() {
|
||||||
return true; //aggregate always returns true for now - we can look at a more complicated/acurate solution later
|
return true; //aggregate always returns true for now - we can look at a more complicated/accurate solution later
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,13 +17,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.owasp.dependencycheck.maven;
|
package org.owasp.dependencycheck.maven;
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import org.apache.maven.artifact.Artifact;
|
import org.apache.maven.artifact.Artifact;
|
||||||
@@ -109,18 +106,23 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
@Parameter(readonly = true, required = true, property = "reactorProjects")
|
@Parameter(readonly = true, required = true, property = "reactorProjects")
|
||||||
private List<MavenProject> reactorProjects;
|
private List<MavenProject> reactorProjects;
|
||||||
/**
|
/**
|
||||||
* The entry point towards a Maven version independent way of resolving artifacts (handles both Maven 3.0 sonatype and Maven 3.1+ eclipse Aether implementations).
|
* The entry point towards a Maven version independent way of resolving
|
||||||
|
* artifacts (handles both Maven 3.0 Sonatype and Maven 3.1+ eclipse Aether
|
||||||
|
* implementations).
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
private ArtifactResolver artifactResolver;
|
private ArtifactResolver artifactResolver;
|
||||||
|
|
||||||
@Parameter( defaultValue = "${session}", readonly = true, required = true )
|
/**
|
||||||
|
* The Maven Session.
|
||||||
|
*/
|
||||||
|
@Parameter(defaultValue = "${session}", readonly = true, required = true)
|
||||||
protected MavenSession session;
|
protected MavenSession session;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remote repositories which will be searched for artifacts.
|
* Remote repositories which will be searched for artifacts.
|
||||||
*/
|
*/
|
||||||
@Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true )
|
@Parameter(defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true)
|
||||||
private List<ArtifactRepository> remoteRepositories;
|
private List<ArtifactRepository> remoteRepositories;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -527,6 +529,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
protected String getConnectionString() {
|
protected String getConnectionString() {
|
||||||
return connectionString;
|
return connectionString;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if the mojo should fail the build if an exception occurs.
|
* Returns if the mojo should fail the build if an exception occurs.
|
||||||
*
|
*
|
||||||
@@ -591,29 +594,6 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the correct output directory depending on if a site is being
|
|
||||||
* executed or not.
|
|
||||||
*
|
|
||||||
* @param current the Maven project to get the output directory from
|
|
||||||
* @return the directory to write the report(s)
|
|
||||||
*/
|
|
||||||
protected File getDataFile(MavenProject current) {
|
|
||||||
if (getLog().isDebugEnabled()) {
|
|
||||||
getLog().debug(String.format("Getting data filefor %s using key '%s'", current.getName(), getDataFileContextKey()));
|
|
||||||
}
|
|
||||||
final Object obj = current.getContextValue(getDataFileContextKey());
|
|
||||||
if (obj != null) {
|
|
||||||
if (obj instanceof String) {
|
|
||||||
final File f = new File((String) obj);
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
} else if (getLog().isDebugEnabled()) {
|
|
||||||
getLog().debug("Context value not found");
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scans the project's artifacts and adds them to the engine's dependency
|
* Scans the project's artifacts and adds them to the engine's dependency
|
||||||
* list.
|
* list.
|
||||||
@@ -643,6 +623,7 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
* @param project the project being scanned
|
* @param project the project being scanned
|
||||||
* @param nodes the list of dependency nodes, generally obtained via the
|
* @param nodes the list of dependency nodes, generally obtained via the
|
||||||
* DependencyGraphBuilder
|
* DependencyGraphBuilder
|
||||||
|
* @param buildingRequest the Maven project building request
|
||||||
* @return a collection of exceptions that may have occurred while resolving
|
* @return a collection of exceptions that may have occurred while resolving
|
||||||
* and scanning the dependencies
|
* and scanning the dependencies
|
||||||
*/
|
*/
|
||||||
@@ -655,8 +636,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact());
|
final ArtifactCoordinate coordinate = TransferUtils.toArtifactCoordinate(dependencyNode.getArtifact());
|
||||||
final Artifact result = artifactResolver.resolveArtifact( buildingRequest, coordinate ).getArtifact();
|
final Artifact result = artifactResolver.resolveArtifact(buildingRequest, coordinate).getArtifact();
|
||||||
if (result.isResolved() && result.getFile()!= null) {
|
if (result.isResolved() && result.getFile() != null) {
|
||||||
final List<Dependency> deps = engine.scan(result.getFile().getAbsoluteFile(),
|
final List<Dependency> deps = engine.scan(result.getFile().getAbsoluteFile(),
|
||||||
project.getName() + ":" + dependencyNode.getArtifact().getScope());
|
project.getName() + ":" + dependencyNode.getArtifact().getScope());
|
||||||
if (deps != null) {
|
if (deps != null) {
|
||||||
@@ -702,21 +683,18 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns a new ProjectBuildingRequest populated from the current session and the current project remote
|
* @return Returns a new ProjectBuildingRequest populated from the current
|
||||||
* repositories, used to resolve artifacts.
|
* session and the current project remote repositories, used to resolve
|
||||||
|
* artifacts.
|
||||||
*/
|
*/
|
||||||
public ProjectBuildingRequest newResolveArtifactProjectBuildingRequest()
|
public ProjectBuildingRequest newResolveArtifactProjectBuildingRequest() {
|
||||||
{
|
final ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
|
||||||
ProjectBuildingRequest buildingRequest =
|
buildingRequest.setRemoteRepositories(remoteRepositories);
|
||||||
new DefaultProjectBuildingRequest( session.getProjectBuildingRequest() );
|
|
||||||
|
|
||||||
buildingRequest.setRemoteRepositories( remoteRepositories );
|
|
||||||
|
|
||||||
return buildingRequest;
|
return buildingRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the dependency-check scan and generates the necassary report.
|
* Executes the dependency-check scan and generates the necessary report.
|
||||||
*
|
*
|
||||||
* @throws MojoExecutionException thrown if there is an exception running
|
* @throws MojoExecutionException thrown if there is an exception running
|
||||||
* the scan
|
* the scan
|
||||||
@@ -1079,8 +1057,8 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities: %n%s%n%n"
|
msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities: %n%s%n%n"
|
||||||
+ "See the dependency-check report for more details.%n%n", ids.toString());
|
+ "See the dependency-check report for more details.%n%n", ids.toString());
|
||||||
} else {
|
} else {
|
||||||
msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities that have a CVSS score greater than '%.1f': %n%s%n%n"
|
msg = String.format("%n%nOne or more dependencies were identified with vulnerabilities that have a CVSS score greater than '%.1f': "
|
||||||
+ "See the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
|
+ "%n%s%n%nSee the dependency-check report for more details.%n%n", failBuildOnCVSS, ids.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new MojoFailureException(msg);
|
throw new MojoFailureException(msg);
|
||||||
@@ -1154,60 +1132,5 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
|
|||||||
return "dependency-output-dir-" + dataFileName;
|
return "dependency-output-dir-" + dataFileName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Writes the scan data to disk. This is used to serialize the scan data
|
|
||||||
* between the "check" and "aggregate" phase.
|
|
||||||
*
|
|
||||||
* @param mp the mMven project for which the data file was created
|
|
||||||
* @param writeTo the directory to write the data file
|
|
||||||
* @param dependencies the list of dependencies to serialize
|
|
||||||
*/
|
|
||||||
protected void writeDataFile(MavenProject mp, File writeTo, List<Dependency> dependencies) {
|
|
||||||
File file;
|
|
||||||
//check to see if this was already written out
|
|
||||||
if (mp.getContextValue(this.getDataFileContextKey()) == null) {
|
|
||||||
if (writeTo == null) {
|
|
||||||
file = new File(mp.getBuild().getDirectory());
|
|
||||||
file = new File(file, dataFileName);
|
|
||||||
} else {
|
|
||||||
file = new File(writeTo, dataFileName);
|
|
||||||
}
|
|
||||||
final File parent = file.getParentFile();
|
|
||||||
if (!parent.isDirectory() && !parent.mkdirs()) {
|
|
||||||
getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.",
|
|
||||||
parent.getAbsolutePath()));
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectOutputStream out = null;
|
|
||||||
try {
|
|
||||||
if (dependencies != null) {
|
|
||||||
out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
|
|
||||||
out.writeObject(dependencies);
|
|
||||||
}
|
|
||||||
if (getLog().isDebugEnabled()) {
|
|
||||||
getLog().debug(String.format("Serialized data file written to '%s' for %s, referenced by key %s",
|
|
||||||
file.getAbsolutePath(), mp.getName(), this.getDataFileContextKey()));
|
|
||||||
}
|
|
||||||
mp.setContextValue(this.getDataFileContextKey(), file.getAbsolutePath());
|
|
||||||
} catch (IOException ex) {
|
|
||||||
getLog().warn("Unable to create data file used for report aggregation; "
|
|
||||||
+ "if report aggregation is being used the results may be incomplete.");
|
|
||||||
if (getLog().isDebugEnabled()) {
|
|
||||||
getLog().debug(ex.getMessage(), ex);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (out != null) {
|
|
||||||
try {
|
|
||||||
out.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
if (getLog().isDebugEnabled()) {
|
|
||||||
getLog().debug("ignore", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ public class BaseDependencyCheckMojoTest extends BaseTest {
|
|||||||
MavenProject project = new MockUp<MavenProject>() {
|
MavenProject project = new MockUp<MavenProject>() {
|
||||||
@Mock
|
@Mock
|
||||||
public Set<Artifact> getArtifacts() {
|
public Set<Artifact> getArtifacts() {
|
||||||
Set<Artifact> artifacts = new HashSet<Artifact>();
|
Set<Artifact> artifacts = new HashSet<>();
|
||||||
Artifact a = new ArtifactStub();
|
Artifact a = new ArtifactStub();
|
||||||
try {
|
try {
|
||||||
File file = new File(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());
|
File file = new File(Test.class.getProtectionDomain().getCodeSource().getLocation().toURI());
|
||||||
@@ -107,6 +107,9 @@ public class BaseDependencyCheckMojoTest extends BaseTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of ODC Mojo for testing.
|
||||||
|
*/
|
||||||
public class BaseDependencyCheckMojoImpl extends BaseDependencyCheckMojo {
|
public class BaseDependencyCheckMojoImpl extends BaseDependencyCheckMojo {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -39,20 +39,9 @@ public class BaseTest {
|
|||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUpClass() throws Exception {
|
public static void setUpClass() throws Exception {
|
||||||
Settings.initialize();
|
Settings.initialize();
|
||||||
InputStream mojoProperties = null;
|
try (InputStream mojoProperties = BaseTest.class.getClassLoader().getResourceAsStream(BaseTest.PROPERTIES_FILE)) {
|
||||||
try {
|
|
||||||
mojoProperties = BaseTest.class.getClassLoader().getResourceAsStream(BaseTest.PROPERTIES_FILE);
|
|
||||||
Settings.mergeProperties(mojoProperties);
|
Settings.mergeProperties(mojoProperties);
|
||||||
} finally {
|
|
||||||
if (mojoProperties != null) {
|
|
||||||
try {
|
|
||||||
mojoProperties.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
Logger.getLogger(BaseTest.class.getName()).log(Level.SEVERE, null, ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
|
|||||||
@@ -120,7 +120,7 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved.
|
|||||||
<version>${reporting.pmd-plugin.version}</version>
|
<version>${reporting.pmd-plugin.version}</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<targetJdk>1.6</targetJdk>
|
<targetJdk>1.6</targetJdk>
|
||||||
<linkXref>true</linkXref>
|
<linkXRef>true</linkXRef>
|
||||||
<sourceEncoding>utf-8</sourceEncoding>
|
<sourceEncoding>utf-8</sourceEncoding>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/org/owasp/dependencycheck/org/apache/**/*.java</exclude>
|
<exclude>**/org/owasp/dependencycheck/org/apache/**/*.java</exclude>
|
||||||
|
|||||||
@@ -65,11 +65,8 @@ public final class Checksum {
|
|||||||
*/
|
*/
|
||||||
public static byte[] getChecksum(String algorithm, File file) throws NoSuchAlgorithmException, IOException {
|
public static byte[] getChecksum(String algorithm, File file) throws NoSuchAlgorithmException, IOException {
|
||||||
final MessageDigest md = MessageDigest.getInstance(algorithm);
|
final MessageDigest md = MessageDigest.getInstance(algorithm);
|
||||||
FileInputStream fis = null;
|
try (FileInputStream fis = new FileInputStream(file);
|
||||||
FileChannel ch = null;
|
FileChannel ch = fis.getChannel()) {
|
||||||
try {
|
|
||||||
fis = new FileInputStream(file);
|
|
||||||
ch = fis.getChannel();
|
|
||||||
final ByteBuffer buf = ByteBuffer.allocateDirect(8192);
|
final ByteBuffer buf = ByteBuffer.allocateDirect(8192);
|
||||||
int b = ch.read(buf);
|
int b = ch.read(buf);
|
||||||
while (b != -1 && b != 0) {
|
while (b != -1 && b != 0) {
|
||||||
@@ -81,21 +78,6 @@ public final class Checksum {
|
|||||||
b = ch.read(buf);
|
b = ch.read(buf);
|
||||||
}
|
}
|
||||||
return md.digest();
|
return md.digest();
|
||||||
} finally {
|
|
||||||
if (ch != null) {
|
|
||||||
try {
|
|
||||||
ch.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("Error closing channel '{}'.", file.getName(), ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (fis != null) {
|
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("Error closing file '{}'.", file.getName(), ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,12 +31,12 @@ import java.util.List;
|
|||||||
*
|
*
|
||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public class ExpectedOjectInputStream extends ObjectInputStream {
|
public class ExpectedObjectInputStream extends ObjectInputStream {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The list of fully qualified class names that are able to be deserialized.
|
* The list of fully qualified class names that are able to be deserialized.
|
||||||
*/
|
*/
|
||||||
private List<String> expected = new ArrayList<String>();
|
private final List<String> expected = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new ExpectedOjectInputStream that can be used to securely deserialize an object by restricting the classes
|
* Constructs a new ExpectedOjectInputStream that can be used to securely deserialize an object by restricting the classes
|
||||||
@@ -46,7 +46,7 @@ public class ExpectedOjectInputStream extends ObjectInputStream {
|
|||||||
* @param expected the fully qualified class names of the classes that can be deserialized
|
* @param expected the fully qualified class names of the classes that can be deserialized
|
||||||
* @throws IOException thrown if there is an error reading from the stream
|
* @throws IOException thrown if there is an error reading from the stream
|
||||||
*/
|
*/
|
||||||
public ExpectedOjectInputStream(InputStream inputStream, String... expected) throws IOException {
|
public ExpectedObjectInputStream(InputStream inputStream, String... expected) throws IOException {
|
||||||
super(inputStream);
|
super(inputStream);
|
||||||
this.expected.addAll(Arrays.asList(expected));
|
this.expected.addAll(Arrays.asList(expected));
|
||||||
}
|
}
|
||||||
@@ -283,7 +283,7 @@ public class SSLSocketFactoryEx extends SSLSocketFactory {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final List<String> aa = new ArrayList<String>();
|
final List<String> aa = new ArrayList<>();
|
||||||
for (String preferredProtocol : preferredProtocols) {
|
for (String preferredProtocol : preferredProtocols) {
|
||||||
final int idx = Arrays.binarySearch(availableProtocols, preferredProtocol);
|
final int idx = Arrays.binarySearch(availableProtocols, preferredProtocol);
|
||||||
if (idx >= 0) {
|
if (idx >= 0) {
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import java.util.Properties;
|
|||||||
* @author Jeremy Long
|
* @author Jeremy Long
|
||||||
*/
|
*/
|
||||||
public final class Settings {
|
public final class Settings {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logger.
|
* The logger.
|
||||||
*/
|
*/
|
||||||
@@ -49,14 +50,14 @@ public final class Settings {
|
|||||||
/**
|
/**
|
||||||
* Thread local settings.
|
* Thread local settings.
|
||||||
*/
|
*/
|
||||||
private static final ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<Settings>();
|
private static final ThreadLocal<Settings> LOCAL_SETTINGS = new ThreadLocal<>();
|
||||||
/**
|
/**
|
||||||
* The properties.
|
* The properties.
|
||||||
*/
|
*/
|
||||||
private Properties props = null;
|
private Properties props = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A reference to the temporary directory; used incase it needs to be
|
* A reference to the temporary directory; used in case it needs to be
|
||||||
* deleted during cleanup.
|
* deleted during cleanup.
|
||||||
*/
|
*/
|
||||||
private static File tempDirectory = null;
|
private static File tempDirectory = null;
|
||||||
@@ -425,7 +426,6 @@ public final class Settings {
|
|||||||
}
|
}
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private constructor for the Settings class. This class loads the
|
* Private constructor for the Settings class. This class loads the
|
||||||
* properties files.
|
* properties files.
|
||||||
@@ -433,10 +433,8 @@ public final class Settings {
|
|||||||
* @param propertiesFilePath the path to the base properties file to load
|
* @param propertiesFilePath the path to the base properties file to load
|
||||||
*/
|
*/
|
||||||
private Settings(String propertiesFilePath) {
|
private Settings(String propertiesFilePath) {
|
||||||
InputStream in = null;
|
|
||||||
props = new Properties();
|
props = new Properties();
|
||||||
try {
|
try (InputStream in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath)) {
|
||||||
in = this.getClass().getClassLoader().getResourceAsStream(propertiesFilePath);
|
|
||||||
props.load(in);
|
props.load(in);
|
||||||
} catch (NullPointerException ex) {
|
} catch (NullPointerException ex) {
|
||||||
LOGGER.error("Did not find settings file '{}'.", propertiesFilePath);
|
LOGGER.error("Did not find settings file '{}'.", propertiesFilePath);
|
||||||
@@ -444,14 +442,6 @@ public final class Settings {
|
|||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
LOGGER.error("Unable to load settings from '{}'.", propertiesFilePath);
|
LOGGER.error("Unable to load settings from '{}'.", propertiesFilePath);
|
||||||
LOGGER.debug("", ex);
|
LOGGER.debug("", ex);
|
||||||
} finally {
|
|
||||||
if (in != null) {
|
|
||||||
try {
|
|
||||||
in.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
logProperties("Properties loaded", props);
|
logProperties("Properties loaded", props);
|
||||||
}
|
}
|
||||||
@@ -530,9 +520,7 @@ public final class Settings {
|
|||||||
private static void logProperties(String header, Properties properties) {
|
private static void logProperties(String header, Properties properties) {
|
||||||
if (LOGGER.isDebugEnabled()) {
|
if (LOGGER.isDebugEnabled()) {
|
||||||
final StringWriter sw = new StringWriter();
|
final StringWriter sw = new StringWriter();
|
||||||
PrintWriter pw = null;
|
try (PrintWriter pw = new PrintWriter(sw)) {
|
||||||
try {
|
|
||||||
pw = new PrintWriter(sw);
|
|
||||||
pw.format("%s:%n%n", header);
|
pw.format("%s:%n%n", header);
|
||||||
final Enumeration<?> e = properties.propertyNames();
|
final Enumeration<?> e = properties.propertyNames();
|
||||||
while (e.hasMoreElements()) {
|
while (e.hasMoreElements()) {
|
||||||
@@ -548,10 +536,6 @@ public final class Settings {
|
|||||||
}
|
}
|
||||||
pw.flush();
|
pw.flush();
|
||||||
LOGGER.debug(sw.toString());
|
LOGGER.debug(sw.toString());
|
||||||
} finally {
|
|
||||||
if (pw != null) {
|
|
||||||
pw.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -650,18 +634,8 @@ public final class Settings {
|
|||||||
* the properties
|
* the properties
|
||||||
*/
|
*/
|
||||||
public static void mergeProperties(File filePath) throws FileNotFoundException, IOException {
|
public static void mergeProperties(File filePath) throws FileNotFoundException, IOException {
|
||||||
FileInputStream fis = null;
|
try (FileInputStream fis = new FileInputStream(filePath)) {
|
||||||
try {
|
|
||||||
fis = new FileInputStream(filePath);
|
|
||||||
mergeProperties(fis);
|
mergeProperties(fis);
|
||||||
} finally {
|
|
||||||
if (fis != null) {
|
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("close error", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -678,18 +652,8 @@ public final class Settings {
|
|||||||
* the properties
|
* the properties
|
||||||
*/
|
*/
|
||||||
public static void mergeProperties(String filePath) throws FileNotFoundException, IOException {
|
public static void mergeProperties(String filePath) throws FileNotFoundException, IOException {
|
||||||
FileInputStream fis = null;
|
try (FileInputStream fis = new FileInputStream(filePath)) {
|
||||||
try {
|
|
||||||
fis = new FileInputStream(filePath);
|
|
||||||
mergeProperties(fis);
|
mergeProperties(fis);
|
||||||
} finally {
|
|
||||||
if (fis != null) {
|
|
||||||
try {
|
|
||||||
fis.close();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
LOGGER.trace("close error", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -790,8 +754,7 @@ public final class Settings {
|
|||||||
* @return the property from the properties file
|
* @return the property from the properties file
|
||||||
*/
|
*/
|
||||||
public static String getString(String key, String defaultValue) {
|
public static String getString(String key, String defaultValue) {
|
||||||
final String str = System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue));
|
return System.getProperty(key, LOCAL_SETTINGS.get().props.getProperty(key, defaultValue));
|
||||||
return str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -981,9 +944,10 @@ public final class Settings {
|
|||||||
*/
|
*/
|
||||||
public static File getDataDirectory() throws IOException {
|
public static File getDataDirectory() throws IOException {
|
||||||
final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY);
|
final File path = Settings.getDataFile(Settings.KEYS.DATA_DIRECTORY);
|
||||||
if (path.exists() || path.mkdirs()) {
|
if (path != null && (path.exists() || path.mkdirs())) {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
throw new IOException(String.format("Unable to create the data directory '%s'", path.getAbsolutePath()));
|
throw new IOException(String.format("Unable to create the data directory '%s'",
|
||||||
|
(path == null) ? "unknown" : path.getAbsolutePath()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user