Merge branch 'master' into reporting

Conflicts:
	dependency-check-cli/pom.xml

Former-commit-id: f381a7191effbe65f852c76e5e19033e4a264171
This commit is contained in:
Hans Joachim Desserud
2015-07-06 18:36:49 +02:00
28 changed files with 446 additions and 395 deletions

2
.gitignore vendored
View File

@@ -1,4 +1,6 @@
*/target/** */target/**
# IntelliJ test run side-effects
dependency-check-core/data/
# Intellij project files # Intellij project files
*.iml *.iml
*.ipr *.ipr

View File

@@ -198,7 +198,7 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
<version>${reporting.javadoc-plugin.version}</version> <version>${reporting.javadoc-plugin.version}</version>
<configuration> <configuration>
<failOnError>false</failOnError> <failOnError>false</failOnError>
<bottom>Copyright© 2012-15 Jeremy Long. All Rights Reserved.</bottom> <bottom>Copyright<EFBFBD> 2012-15 Jeremy Long. All Rights Reserved.</bottom>
</configuration> </configuration>
<reportSets> <reportSets>
<reportSet> <reportSet>
@@ -333,7 +333,6 @@ Copyright (c) 2012 - Jeremy Long. All Rights Reserved.
<dependency> <dependency>
<groupId>ch.qos.logback</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId> <artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency> </dependency>
</dependencies> </dependencies>
</project> </project>

View File

@@ -351,22 +351,27 @@ public class App {
} }
} }
/**
* Creates a file appender and adds it to logback.
*
* @param verboseLog the path to the verbose log file
*/
private void prepareLogger(String verboseLog) { private void prepareLogger(String verboseLog) {
StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton(); final StaticLoggerBinder loggerBinder = StaticLoggerBinder.getSingleton();
LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory(); final LoggerContext context = (LoggerContext) loggerBinder.getLoggerFactory();
final PatternLayoutEncoder encoder = new PatternLayoutEncoder(); final PatternLayoutEncoder encoder = new PatternLayoutEncoder();
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();
FileAppender fa = new FileAppender(); final FileAppender fa = new FileAppender();
fa.setAppend(true); fa.setAppend(true);
fa.setEncoder(encoder); fa.setEncoder(encoder);
fa.setContext(context); fa.setContext(context);
fa.setFile(verboseLog); fa.setFile(verboseLog);
final File f = new File(verboseLog); final File f = new File(verboseLog);
String name = f.getName(); String name = f.getName();
int i = name.lastIndexOf('.'); final int i = name.lastIndexOf('.');
if (i > 1) { if (i > 1) {
name = name.substring(0, i); name = name.substring(0, i);
} }

View File

@@ -372,8 +372,13 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
</dependency> </dependency>
<!-- Set this to test so that each project that uses this has to have its own implementation of SLF4J --> <!-- Set this to test so that each project that uses this has to have its own implementation of SLF4J -->
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>slf4j-simple</artifactId> <artifactId>logback-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<!-- For the CAL10N support --> <!-- For the CAL10N support -->

View File

@@ -17,13 +17,6 @@
*/ */
package org.owasp.dependencycheck; package org.owasp.dependencycheck;
import java.io.File;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.owasp.dependencycheck.analyzer.AnalysisPhase; import org.owasp.dependencycheck.analyzer.AnalysisPhase;
import org.owasp.dependencycheck.analyzer.Analyzer; import org.owasp.dependencycheck.analyzer.Analyzer;
import org.owasp.dependencycheck.analyzer.AnalyzerService; import org.owasp.dependencycheck.analyzer.AnalyzerService;
@@ -43,6 +36,14 @@ import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.io.File;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
/** /**
* Scans files, directories, etc. for Dependencies. Analyzers are loaded and used to process the files found by the scan, if a * Scans files, directories, etc. for Dependencies. Analyzers are loaded and used to process the files found by the scan, if a
* file is encountered and an Analyzer is associated with the file type then the file is turned into a dependency. * file is encountered and an Analyzer is associated with the file type then the file is turned into a dependency.
@@ -167,7 +168,6 @@ public class Engine {
* *
* @param paths an array of paths to files or directories to be analyzed * @param paths an array of paths to files or directories to be analyzed
* @return the list of dependencies scanned * @return the list of dependencies scanned
*
* @since v0.3.2.5 * @since v0.3.2.5
*/ */
public List<Dependency> scan(String[] paths) { public List<Dependency> scan(String[] paths) {
@@ -200,7 +200,6 @@ public class Engine {
* *
* @param files an array of paths to files or directories to be analyzed. * @param files an array of paths to files or directories to be analyzed.
* @return the list of dependencies * @return the list of dependencies
*
* @since v0.3.2.5 * @since v0.3.2.5
*/ */
public List<Dependency> scan(File[] files) { public List<Dependency> scan(File[] files) {
@@ -220,7 +219,6 @@ public class Engine {
* *
* @param files a set of paths to files or directories to be analyzed * @param files a set of paths to files or directories to be analyzed
* @return the list of dependencies scanned * @return the list of dependencies scanned
*
* @since v0.3.2.5 * @since v0.3.2.5
*/ */
public List<Dependency> scan(Set<File> files) { public List<Dependency> scan(Set<File> files) {
@@ -240,7 +238,6 @@ public class Engine {
* *
* @param files a set of paths to files or directories to be analyzed * @param files a set of paths to files or directories to be analyzed
* @return the list of dependencies scanned * @return the list of dependencies scanned
*
* @since v0.3.2.5 * @since v0.3.2.5
*/ */
public List<Dependency> scan(List<File> files) { public List<Dependency> scan(List<File> files) {
@@ -260,9 +257,7 @@ public class Engine {
* *
* @param file the path to a file or directory to be analyzed * @param file the path to a file or directory to be analyzed
* @return the list of dependencies scanned * @return the list of dependencies scanned
*
* @since v0.3.2.4 * @since v0.3.2.4
*
*/ */
public List<Dependency> scan(File file) { public List<Dependency> scan(File file) {
if (file.exists()) { if (file.exists()) {
@@ -324,7 +319,7 @@ public class Engine {
Dependency dependency = null; Dependency dependency = null;
if (supportsExtension(extension)) { if (supportsExtension(extension)) {
dependency = new Dependency(file); dependency = new Dependency(file);
if (extension == null ? fileName == null : extension.equals(fileName)) { if (extension.equals(fileName)) {
dependency.setFileExtension(extension); dependency.setFileExtension(extension);
} }
dependencies.add(dependency); dependencies.add(dependency);
@@ -333,7 +328,10 @@ public class Engine {
} }
/** /**
* Runs the analyzers against all of the dependencies. * Runs the analyzers against all of the dependencies. Since the mutable dependencies list is exposed via
* {@link #getDependencies()}, this method iterates over a copy of the dependencies list. Thus, the potential for
* {@link java.util.ConcurrentModificationException}s is avoided, and analyzers may safely add or remove entries
* from the dependencies list.
*/ */
public void analyzeDependencies() { public void analyzeDependencies() {
boolean autoUpdate = true; boolean autoUpdate = true;

View File

@@ -42,7 +42,6 @@ import org.owasp.dependencycheck.dependency.Dependency;
import org.owasp.dependencycheck.dependency.Evidence; import org.owasp.dependencycheck.dependency.Evidence;
import org.owasp.dependencycheck.utils.DCResources; import org.owasp.dependencycheck.utils.DCResources;
import org.owasp.dependencycheck.utils.Settings; import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
import org.slf4j.cal10n.LocLogger; import org.slf4j.cal10n.LocLogger;
import org.slf4j.cal10n.LocLoggerFactory; import org.slf4j.cal10n.LocLoggerFactory;
import org.w3c.dom.Document; import org.w3c.dom.Document;
@@ -79,15 +78,15 @@ public class AssemblyAnalyzer extends AbstractFileTypeAnalyzer {
/** /**
* Message Conveyer * Message Conveyer
*/ */
private IMessageConveyor messageConveyer = new MessageConveyor(Locale.getDefault()); private final IMessageConveyor MESSAGE_CONVERYOR = new MessageConveyor(Locale.getDefault());
/** /**
* LocLoggerFactory for localized logger * LocLoggerFactory for localized logger
*/ */
private LocLoggerFactory llFactory = new LocLoggerFactory(messageConveyer); private final LocLoggerFactory LLFACTORY = new LocLoggerFactory(MESSAGE_CONVERYOR);
/** /**
* Logger * Logger
*/ */
private LocLogger LOGGER = llFactory.getLocLogger(AssemblyAnalyzer.class); private final LocLogger LOGGER = LLFACTORY.getLocLogger(AssemblyAnalyzer.class);
/** /**
* Builds the beginnings of a List for ProcessBuilder * Builds the beginnings of a List for ProcessBuilder

View File

@@ -35,9 +35,8 @@ import org.owasp.dependencycheck.utils.Settings;
import org.owasp.dependencycheck.utils.UrlStringUtils; import org.owasp.dependencycheck.utils.UrlStringUtils;
/** /**
* Used to analyze Autoconf input files named configure.ac or configure.in. * Used to analyze Autoconf input files named configure.ac or configure.in. Files simply named "configure" are also analyzed,
* Files simply named "configure" are also analyzed, assuming they are generated * assuming they are generated by Autoconf, and contain certain special package descriptor variables.
* by Autoconf, and contain certain special package descriptor variables.
* *
* @author Dale Visser <dvisser@ida.org> * @author Dale Visser <dvisser@ida.org>
* @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a> * @see <a href="https://www.gnu.org/software/autoconf/">Autoconf - GNU Project - Free Software Foundation (FSF)</a>
@@ -85,10 +84,11 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
* Matches AC_INIT statement in configure.ac file. * Matches AC_INIT statement in configure.ac file.
*/ */
private static final Pattern AC_INIT_PATTERN; private static final Pattern AC_INIT_PATTERN;
static { static {
// each instance of param or sep_param has a capture group // each instance of param or sep_param has a capture group
final String param = "\\[{0,2}(.+?)\\]{0,2}"; final String param = "\\[{0,2}(.+?)\\]{0,2}";
final String sep_param = "\\s*,\\s*" + param; final String sepParam = "\\s*,\\s*" + param;
// Group 1: Package // Group 1: Package
// Group 2: Version // Group 2: Version
// Group 3: optional // Group 3: optional
@@ -98,8 +98,8 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
// Group 7: optional // Group 7: optional
// Group 8: URL (if it exists) // Group 8: URL (if it exists)
AC_INIT_PATTERN = Pattern.compile(String.format( AC_INIT_PATTERN = Pattern.compile(String.format(
"AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sep_param, "AC_INIT\\(%s%s(%s)?(%s)?(%s)?\\s*\\)", param, sepParam,
sep_param, sep_param, sep_param), Pattern.DOTALL sepParam, sepParam, sepParam), Pattern.DOTALL
| Pattern.CASE_INSENSITIVE); | Pattern.CASE_INSENSITIVE);
} }
@@ -133,8 +133,7 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
} }
/** /**
* Returns the key used in the properties file to reference the analyzer's * Returns the key used in the properties file to reference the analyzer's enabled property.
* enabled property.
* *
* @return the analyzer's enabled property setting key * @return the analyzer's enabled property setting key
*/ */
@@ -174,6 +173,13 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
} }
} }
/**
* Extracts evidence from the configuration.
*
* @param dependency the dependency being analyzed
* @param name the name of the source of evidence
* @param contents the contents to analyze for evidence
*/
private void extractConfigureScriptEvidence(Dependency dependency, private void extractConfigureScriptEvidence(Dependency dependency,
final String name, final String contents) { final String name, final String contents) {
final Matcher matcher = PACKAGE_VAR.matcher(contents); final Matcher matcher = PACKAGE_VAR.matcher(contents);
@@ -198,6 +204,13 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
} }
} }
/**
* Retrieves the contents of a given file.
*
* @param actualFile the file to read
* @return the contents of the file
* @throws AnalysisException thrown if there is an IO Exception
*/
private String getFileContents(final File actualFile) private String getFileContents(final File actualFile)
throws AnalysisException { throws AnalysisException {
String contents = ""; String contents = "";
@@ -210,6 +223,13 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
return contents; return contents;
} }
/**
* Gathers evidence from a given file
*
* @param dependency the dependency to add evidence to
* @param name the source of the evidence
* @param contents the evidence to analyze
*/
private void gatherEvidence(Dependency dependency, final String name, private void gatherEvidence(Dependency dependency, final String name,
String contents) { String contents) {
final Matcher matcher = AC_INIT_PATTERN.matcher(contents); final Matcher matcher = AC_INIT_PATTERN.matcher(contents);
@@ -243,8 +263,7 @@ public class AutoconfAnalyzer extends AbstractFileTypeAnalyzer {
/** /**
* Initializes the file type analyzer. * Initializes the file type analyzer.
* *
* @throws Exception * @throws Exception thrown if there is an exception during initialization
* thrown if there is an exception during initialization
*/ */
@Override @Override
protected void initializeFileTypeAnalyzer() throws Exception { protected void initializeFileTypeAnalyzer() throws Exception {

View File

@@ -657,6 +657,9 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
final String source = "Manifest"; final String source = "Manifest";
String specificationVersion = null;
boolean hasImplementationVersion = false;
for (Entry<Object, Object> entry : atts.entrySet()) { for (Entry<Object, Object> entry : atts.entrySet()) {
String key = entry.getKey().toString(); String key = entry.getKey().toString();
String value = atts.getValue(key); String value = atts.getValue(key);
@@ -670,8 +673,11 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
productEvidence.addEvidence(source, key, value, Confidence.HIGH); productEvidence.addEvidence(source, key, value, Confidence.HIGH);
addMatchingValues(classInformation, value, productEvidence); addMatchingValues(classInformation, value, productEvidence);
} else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) { } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VERSION.toString())) {
hasImplementationVersion = true;
foundSomething = true; foundSomething = true;
versionEvidence.addEvidence(source, key, value, Confidence.HIGH); versionEvidence.addEvidence(source, key, value, Confidence.HIGH);
} else if ("specification-version".equalsIgnoreCase(key)) {
specificationVersion = key;
} else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) { } else if (key.equalsIgnoreCase(Attributes.Name.IMPLEMENTATION_VENDOR.toString())) {
foundSomething = true; foundSomething = true;
vendorEvidence.addEvidence(source, key, value, Confidence.HIGH); vendorEvidence.addEvidence(source, key, value, Confidence.HIGH);
@@ -724,9 +730,9 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
foundSomething = true; foundSomething = true;
if (key.contains("version")) { if (key.contains("version")) {
if (key.contains("specification")) { if (!key.contains("specification")) {
versionEvidence.addEvidence(source, key, value, Confidence.LOW); //versionEvidence.addEvidence(source, key, value, Confidence.LOW);
} else { //} else {
versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM); versionEvidence.addEvidence(source, key, value, Confidence.MEDIUM);
} }
} else if ("build-id".equals(key)) { } else if ("build-id".equals(key)) {
@@ -778,6 +784,10 @@ public class JarAnalyzer extends AbstractFileTypeAnalyzer {
} }
} }
} }
if (specificationVersion != null && !hasImplementationVersion) {
foundSomething = true;
versionEvidence.addEvidence(source, "specificationn-version", specificationVersion, Confidence.HIGH);
}
} finally { } finally {
if (jar != null) { if (jar != null) {
jar.close(); jar.close();

View File

@@ -48,14 +48,6 @@ public class NexusSearch {
* Whether to use the Proxy when making requests. * Whether to use the Proxy when making requests.
*/ */
private boolean useProxy; private boolean useProxy;
/**
* The username to use if the Nexus requires authentication.
*/
private String userName = null;
/**
* The password to use if the Nexus requires authentication.
*/
private char[] password;
/** /**
* Used for logging. * Used for logging.
*/ */

View File

@@ -73,7 +73,7 @@ public class CveDB {
*/ */
public CveDB() throws DatabaseException { public CveDB() throws DatabaseException {
super(); super();
statementBundle = java.util.ResourceBundle.getBundle("data/dbStatements"); statementBundle = ResourceBundle.getBundle("data/dbStatements");
try { try {
open(); open();
databaseProperties = new DatabaseProperties(this); databaseProperties = new DatabaseProperties(this);

View File

@@ -189,9 +189,8 @@ public class StandardUpdate {
} }
/** /**
* Determines if the index needs to be updated. This is done by fetching the NVD CVE meta data and checking the last * Determines if the index needs to be updated. This is done by fetching the NVD CVE meta data and checking the last update
* update date. If the data needs to be refreshed this method will return the NvdCveUrl for the files that need to * date. If the data needs to be refreshed this method will return the NvdCveUrl for the files that need to be updated.
* be updated.
* *
* @return the collection of files that need to be updated * @return the collection of files that need to be updated
* @throws MalformedURLException is thrown if the URL for the NVD CVE Meta data is incorrect * @throws MalformedURLException is thrown if the URL for the NVD CVE Meta data is incorrect
@@ -249,7 +248,7 @@ public class StandardUpdate {
} }
} catch (NumberFormatException ex) { } catch (NumberFormatException ex) {
LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file."); LOGGER.warn("An invalid schema version or timestamp exists in the data.properties file.");
LOGGER.debug( "", ex); LOGGER.debug("", ex);
} }
} }
return updates; return updates;

View File

@@ -599,8 +599,8 @@ public class Dependency implements Serializable, Comparable<Dependency> {
private Set<Dependency> relatedDependencies = new TreeSet<Dependency>(); private Set<Dependency> relatedDependencies = new TreeSet<Dependency>();
/** /**
* Get the value of {@link #relatedDependencies}. This field is used to collect other dependencies which really * Get the value of {@link #relatedDependencies}. This field is used to collect other dependencies which really represent the
* represent the same dependency, and may be presented as one item in reports. * same dependency, and may be presented as one item in reports.
* *
* @return the value of relatedDependencies * @return the value of relatedDependencies
*/ */
@@ -660,22 +660,19 @@ public class Dependency implements Serializable, Comparable<Dependency> {
/** /**
* Adds a related dependency. The internal collection is normally a {@link java.util.TreeSet}, which relies on * Adds a related dependency. The internal collection is normally a {@link java.util.TreeSet}, which relies on
* {@link #compareTo(Dependency)}. A consequence of this is that if you attempt to add a dependency with the * {@link #compareTo(Dependency)}. A consequence of this is that if you attempt to add a dependency with the same file path
* same file path (modulo character case) as one that is already in the collection, it won't get added. * (modulo character case) as one that is already in the collection, it won't get added.
* *
* @param dependency a reference to the related dependency * @param dependency a reference to the related dependency
*/ */
public void addRelatedDependency(Dependency dependency) { public void addRelatedDependency(Dependency dependency) {
boolean debug = false;
if (this == dependency) { if (this == dependency) {
LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here " LOGGER.warn("Attempted to add a circular reference - please post the log file to issue #172 here "
+ "https://github.com/jeremylong/DependencyCheck/issues/172"); + "https://github.com/jeremylong/DependencyCheck/issues/172");
debug = true; LOGGER.debug("this: {}", this);
LOGGER.debug("dependency: {}", dependency);
} else if (!relatedDependencies.add(dependency)) { } else if (!relatedDependencies.add(dependency)) {
LOGGER.warn("Failed to add dependency, likely due to referencing the same file as another dependency in the set."); LOGGER.debug("Failed to add dependency, likely due to referencing the same file as another dependency in the set.");
debug = true;
}
if (debug) {
LOGGER.debug("this: {}", this); LOGGER.debug("this: {}", this);
LOGGER.debug("dependency: {}", dependency); LOGGER.debug("dependency: {}", dependency);
} }
@@ -735,22 +732,22 @@ public class Dependency implements Serializable, Comparable<Dependency> {
return false; return false;
} }
final Dependency other = (Dependency) obj; final Dependency other = (Dependency) obj;
return ObjectUtils.equals(this.actualFilePath, other.actualFilePath) && return ObjectUtils.equals(this.actualFilePath, other.actualFilePath)
ObjectUtils.equals(this.filePath, other.filePath) && && ObjectUtils.equals(this.filePath, other.filePath)
ObjectUtils.equals(this.fileName, other.fileName) && && ObjectUtils.equals(this.fileName, other.fileName)
ObjectUtils.equals(this.fileExtension, other.fileExtension) && && ObjectUtils.equals(this.fileExtension, other.fileExtension)
ObjectUtils.equals(this.md5sum, other.md5sum) && && ObjectUtils.equals(this.md5sum, other.md5sum)
ObjectUtils.equals(this.sha1sum, other.sha1sum) && && ObjectUtils.equals(this.sha1sum, other.sha1sum)
ObjectUtils.equals(this.identifiers, other.identifiers) && && ObjectUtils.equals(this.identifiers, other.identifiers)
ObjectUtils.equals(this.vendorEvidence, other.vendorEvidence) && && ObjectUtils.equals(this.vendorEvidence, other.vendorEvidence)
ObjectUtils.equals(this.productEvidence, other.productEvidence) && && ObjectUtils.equals(this.productEvidence, other.productEvidence)
ObjectUtils.equals(this.versionEvidence, other.versionEvidence) && && ObjectUtils.equals(this.versionEvidence, other.versionEvidence)
ObjectUtils.equals(this.description, other.description) && && ObjectUtils.equals(this.description, other.description)
ObjectUtils.equals(this.license, other.license) && && ObjectUtils.equals(this.license, other.license)
ObjectUtils.equals(this.vulnerabilities, other.vulnerabilities) && && ObjectUtils.equals(this.vulnerabilities, other.vulnerabilities)
ObjectUtils.equals(this.relatedDependencies, other.relatedDependencies) && && ObjectUtils.equals(this.relatedDependencies, other.relatedDependencies)
ObjectUtils.equals(this.projectReferences, other.projectReferences) && && ObjectUtils.equals(this.projectReferences, other.projectReferences)
ObjectUtils.equals(this.availableVersions, other.availableVersions); && ObjectUtils.equals(this.availableVersions, other.availableVersions);
} }
/** /**

View File

@@ -17,6 +17,9 @@
*/ */
package org.owasp.dependencycheck.dependency; package org.owasp.dependencycheck.dependency;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;
import java.io.Serializable; import java.io.Serializable;
/** /**
@@ -26,6 +29,16 @@ import java.io.Serializable;
*/ */
public class Evidence implements Serializable, Comparable<Evidence> { public class Evidence implements Serializable, Comparable<Evidence> {
/**
* Used as starting point for generating the value in {@link #hashCode()}.
*/
private static final int MAGIC_HASH_INIT_VALUE = 3;
/**
* Used as a multiplier for generating the value in {@link #hashCode()}.
*/
private static final int MAGIC_HASH_MULTIPLIER = 67;
/** /**
* Creates a new Evidence object. * Creates a new Evidence object.
*/ */
@@ -46,6 +59,7 @@ public class Evidence implements Serializable, Comparable<Evidence> {
this.value = value; this.value = value;
this.confidence = confidence; this.confidence = confidence;
} }
/** /**
* The name of the evidence. * The name of the evidence.
*/ */
@@ -68,6 +82,7 @@ public class Evidence implements Serializable, Comparable<Evidence> {
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
/** /**
* The source of the evidence. * The source of the evidence.
*/ */
@@ -90,6 +105,7 @@ public class Evidence implements Serializable, Comparable<Evidence> {
public void setSource(String source) { public void setSource(String source) {
this.source = source; this.source = source;
} }
/** /**
* The value of the evidence. * The value of the evidence.
*/ */
@@ -124,6 +140,7 @@ public class Evidence implements Serializable, Comparable<Evidence> {
public void setValue(String value) { public void setValue(String value) {
this.value = value; this.value = value;
} }
/** /**
* A value indicating if the Evidence has been "used" (aka read). * A value indicating if the Evidence has been "used" (aka read).
*/ */
@@ -146,6 +163,7 @@ public class Evidence implements Serializable, Comparable<Evidence> {
public void setUsed(boolean used) { public void setUsed(boolean used) {
this.used = used; this.used = used;
} }
/** /**
* The confidence level for the evidence. * The confidence level for the evidence.
*/ */
@@ -176,11 +194,11 @@ public class Evidence implements Serializable, Comparable<Evidence> {
*/ */
@Override @Override
public int hashCode() { public int hashCode() {
int hash = 3; int hash = MAGIC_HASH_INIT_VALUE;
hash = 67 * hash + (this.name != null ? this.name.hashCode() : 0); hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.name));
hash = 67 * hash + (this.source != null ? this.source.hashCode() : 0); hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.source));
hash = 67 * hash + (this.value != null ? this.value.hashCode() : 0); hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(StringUtils.lowerCase(this.value));
hash = 67 * hash + (this.confidence != null ? this.confidence.hashCode() : 0); hash = MAGIC_HASH_MULTIPLIER * hash + ObjectUtils.hashCode(this.confidence);
return hash; return hash;
} }
@@ -200,19 +218,10 @@ public class Evidence implements Serializable, Comparable<Evidence> {
} }
final Evidence e = (Evidence) that; final Evidence e = (Evidence) that;
return testEquality(name, e.name) && testEquality(source, e.source) && testEquality(value, e.value) return StringUtils.equalsIgnoreCase(name, e.name)
&& (confidence == null ? e.confidence == null : confidence == e.confidence); && StringUtils.equalsIgnoreCase(source, e.source)
} && StringUtils.equalsIgnoreCase(value, e.value)
&& ObjectUtils.equals(confidence, e.confidence);
/**
* Simple equality test for use within the equals method. This does a case insensitive compare.
*
* @param l a string to compare.
* @param r another string to compare.
* @return whether the two strings are the same.
*/
private boolean testEquality(String l, String r) {
return l == null ? r == null : l.equalsIgnoreCase(r);
} }
/** /**
@@ -225,13 +234,13 @@ public class Evidence implements Serializable, Comparable<Evidence> {
if (o == null) { if (o == null) {
return 1; return 1;
} }
if (equalsWithNullCheck(source, o.source)) { if (StringUtils.equalsIgnoreCase(source, o.source)) {
if (equalsWithNullCheck(name, o.name)) { if (StringUtils.equalsIgnoreCase(name, o.name)) {
if (equalsWithNullCheck(value, o.value)) { if (StringUtils.equalsIgnoreCase(value, o.value)) {
if (equalsWithNullCheck(confidence, o.confidence)) { if (ObjectUtils.equals(confidence, o.confidence)) {
return 0; //they are equal return 0; //they are equal
} else { } else {
return compareToWithNullCheck(confidence, o.confidence); return ObjectUtils.compare(confidence, o.confidence);
} }
} else { } else {
return compareToIgnoreCaseWithNullCheck(value, o.value); return compareToIgnoreCaseWithNullCheck(value, o.value);
@@ -244,38 +253,6 @@ public class Evidence implements Serializable, Comparable<Evidence> {
} }
} }
/**
* Equality check with an exhaustive, possibly duplicative, check against nulls.
*
* @param me the value to be compared
* @param other the other value to be compared
* @return true if the values are equal; otherwise false
*/
private boolean equalsWithNullCheck(String me, String other) {
if (me == null && other == null) {
return true;
} else if (me == null || other == null) {
return false;
}
return me.equalsIgnoreCase(other);
}
/**
* Equality check with an exhaustive, possibly duplicative, check against nulls.
*
* @param me the value to be compared
* @param other the other value to be compared
* @return true if the values are equal; otherwise false
*/
private boolean equalsWithNullCheck(Confidence me, Confidence other) {
if (me == null && other == null) {
return true;
} else if (me == null || other == null) {
return false;
}
return me.equals(other);
}
/** /**
* Wrapper around {@link java.lang.String#compareToIgnoreCase(java.lang.String) String.compareToIgnoreCase} with an * Wrapper around {@link java.lang.String#compareToIgnoreCase(java.lang.String) String.compareToIgnoreCase} with an
* exhaustive, possibly duplicative, check against nulls. * exhaustive, possibly duplicative, check against nulls.
@@ -295,25 +272,6 @@ public class Evidence implements Serializable, Comparable<Evidence> {
return me.compareToIgnoreCase(other); return me.compareToIgnoreCase(other);
} }
/**
* Wrapper around {@link java.lang.Enum#compareTo(java.lang.Enum) Enum.compareTo} with an exhaustive, possibly duplicative,
* check against nulls.
*
* @param me the value to be compared
* @param other the other value to be compared
* @return true if the values are equal; otherwise false
*/
private int compareToWithNullCheck(Confidence me, Confidence other) {
if (me == null && other == null) {
return 0;
} else if (me == null) {
return -1; //the other string is greater then me
} else if (other == null) {
return 1; //me is greater then the other string
}
return me.compareTo(other);
}
/** /**
* Standard toString() implementation. * Standard toString() implementation.
* *

View File

@@ -32,13 +32,40 @@ import ch.qos.cal10n.LocaleData;
) )
public enum DCResources { public enum DCResources {
/**
* Not deployed.
*/
NOTDEPLOYED, NOTDEPLOYED,
/**
* grok error.
*/
GROKERROR, GROKERROR,
/**
* The dependency is not an assembly.
*/
NOTASSEMBLY, NOTASSEMBLY,
/**
* GROK Return Code.
*/
GROKRC, GROKRC,
/**
* Grok assembly was extracted.
*/
GROKDEPLOYED, GROKDEPLOYED,
/**
* Grok assembly was not extracted.
*/
GROKNOTDEPLOYED, GROKNOTDEPLOYED,
/**
* Grok failed to initialize.
*/
GROKINITFAIL, GROKINITFAIL,
/**
* Grok initialized.
*/
GROKINITMSG, GROKINITMSG,
/**
* Grok assembly was not deleted.
*/
GROKNOTDELETED GROKNOTDELETED
} }

View File

@@ -70,3 +70,6 @@ analyzer.nexus.proxy=true
# the URL for searching search.maven.org for SHA-1 and whether it's enabled # the URL for searching search.maven.org for SHA-1 and whether it's enabled
analyzer.central.enabled=true analyzer.central.enabled=true
analyzer.central.url=http://search.maven.org/solrsearch/select analyzer.central.url=http://search.maven.org/solrsearch/select
# the number of nested archives that will be searched.
archive.scan.depth=3

View File

@@ -34,8 +34,6 @@ import org.owasp.dependencycheck.dependency.Evidence;
import org.owasp.dependencycheck.utils.Settings; import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.slf4j.impl.SimpleLogger;
import org.slf4j.impl.SimpleLoggerFactory;
/** /**
* Tests for the AssemblyAnalyzer. * Tests for the AssemblyAnalyzer.

View File

@@ -96,7 +96,7 @@ public class CPEAnalyzerIntegrationTest extends AbstractDatabaseTestCase {
callDetermineCPE_full("hazelcast-2.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); callDetermineCPE_full("hazelcast-2.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
callDetermineCPE_full("spring-context-support-2.5.5.jar", "cpe:/a:vmware:springsource_spring_framework:2.5.5", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); callDetermineCPE_full("spring-context-support-2.5.5.jar", "cpe:/a:vmware:springsource_spring_framework:2.5.5", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
callDetermineCPE_full("spring-core-3.0.0.RELEASE.jar", "cpe:/a:vmware:springsource_spring_framework:3.0.0", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); callDetermineCPE_full("spring-core-3.0.0.RELEASE.jar", "cpe:/a:vmware:springsource_spring_framework:3.0.0", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
callDetermineCPE_full("org.mortbay.jetty.jar", "cpe:/a:mortbay_jetty:jetty:4.2", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); callDetermineCPE_full("org.mortbay.jetty.jar", "cpe:/a:mortbay_jetty:jetty:4.2.27", instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
callDetermineCPE_full("jaxb-xercesImpl-1.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); callDetermineCPE_full("jaxb-xercesImpl-1.5.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
callDetermineCPE_full("ehcache-core-2.2.0.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp); callDetermineCPE_full("ehcache-core-2.2.0.jar", null, instance, fnAnalyzer, jarAnalyzer, hAnalyzer, fp);
} finally { } finally {

View File

@@ -19,6 +19,7 @@ package org.owasp.dependencycheck.dependency;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import static org.hamcrest.CoreMatchers.*;
/** /**
* *
@@ -53,6 +54,14 @@ public class EvidenceTest {
assertTrue(instance.equals(that8)); assertTrue(instance.equals(that8));
} }
@Test
public void testHashcodeContract() throws Exception {
final Evidence titleCase = new Evidence("Manifest", "Implementation-Title", "Spring Framework", Confidence.HIGH);
final Evidence lowerCase = new Evidence("manifest", "implementation-title", "spring framework", Confidence.HIGH);
assertThat(titleCase, is(equalTo(lowerCase)));
assertThat(titleCase.hashCode(), is(equalTo(lowerCase.hashCode())));
}
/** /**
* Test of compareTo method, of class Evidence. * Test of compareTo method, of class Evidence.
*/ */

View File

@@ -1,21 +0,0 @@
handlers=java.util.logging.ConsoleHandler, java.util.logging.FileHandler
# logging levels
# FINEST, FINER, FINE, CONFIG, INFO, WARNING and SEVERE.
# Configure the ConsoleHandler.
java.util.logging.ConsoleHandler.level=SEVERE
# Configure the FileHandler.
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.level=FINEST
# The following special tokens can be used in the pattern property
# which specifies the location and name of the log file.
# / - standard path separator
# %t - system temporary directory
# %h - value of the user.home system property
# %g - generation number for rotating logs
# %u - unique number to avoid conflicts
# FileHandler writes to %h/demo0.log by default.
java.util.logging.FileHandler.pattern=./logs/DependencyCheck%g.log

View File

@@ -0,0 +1,23 @@
<configuration>
<contextName>dependency-check</contextName>
<!-- Logging configuration -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.out</Target>
<encoder>
<pattern>[%level] %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="console"/>
</root>
<logger name="org.owasp.dependencycheck.analyzer.AssemblyAnalyzerTest" additivity="false" level="WARN">
<appender-ref ref="console"/>
</logger>
<logger name="org.owasp.dependencycheck.data.central.CentralSearchTest" additivity="false" level="WARN">
<appender-ref ref="console"/>
</logger>
<logger name="org.owasp.dependencycheck.data.nexus.NexusSearchTest" additivity="false" level="WARN">
<appender-ref ref="console"/>
</logger>
</configuration>

View File

@@ -149,7 +149,7 @@ public class AggregateMojo extends BaseDependencyCheckMojo {
if (mpp.compareTo(mod.getBasedir()) == 0 && descendants.add(mod)) { if (mpp.compareTo(mod.getBasedir()) == 0 && descendants.add(mod)) {
if (getLog().isDebugEnabled()) { if (getLog().isDebugEnabled()) {
getLog().debug(String.format("Decendent module %s added", mod.getName())); getLog().debug(String.format("Decendent module %s added", mod.getName()));
}; }
} }
} catch (IOException ex) { } catch (IOException ex) {
if (getLog().isDebugEnabled()) { if (getLog().isDebugEnabled()) {

View File

@@ -67,10 +67,6 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
* The properties file location. * The properties file location.
*/ */
private static final String PROPERTIES_FILE = "mojo.properties"; private static final String PROPERTIES_FILE = "mojo.properties";
/**
* Name of the logging properties file.
*/
private static final String LOG_PROPERTIES_FILE = "log.properties";
/** /**
* System specific new line character. * System specific new line character.
*/ */
@@ -949,10 +945,11 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma
} else { } else {
file = new File(writeTo, dataFileName); file = new File(writeTo, dataFileName);
} }
File parent = file.getParentFile(); final File parent = file.getParentFile();
if (!parent.isDirectory()) { if (!parent.isDirectory()) {
if (parent.mkdirs()) { if (parent.mkdirs()) {
getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.", parent.getAbsolutePath())); getLog().error(String.format("Directory '%s' does not exist and cannot be created; unable to write data file.",
parent.getAbsolutePath()));
} }
} }

View File

@@ -18,22 +18,32 @@
package org.owasp.dependencycheck.maven.slf4j; package org.owasp.dependencycheck.maven.slf4j;
import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugin.logging.Log;
import org.slf4j.helpers.FormattingTuple;
import org.slf4j.helpers.MarkerIgnoringBase; import org.slf4j.helpers.MarkerIgnoringBase;
import org.slf4j.helpers.MessageFormatter; import org.slf4j.helpers.MessageFormatter;
/** /**
* Created by colezlaw on 6/14/15. * Created on 6/14/15.
*
* @author colezlaw
*/ */
public class MavenLoggerAdapter extends MarkerIgnoringBase { public class MavenLoggerAdapter extends MarkerIgnoringBase {
private Log log; private Log log;
/**
* Creates a new Maven Logger Adapter.
*
* @param log the maven log
*/
public MavenLoggerAdapter(Log log) { public MavenLoggerAdapter(Log log) {
super(); super();
this.log = log; this.log = log;
} }
/**
*
* @return
*/
@Override @Override
public boolean isTraceEnabled() { public boolean isTraceEnabled() {
if (log != null) { if (log != null) {

View File

@@ -22,7 +22,9 @@ import org.slf4j.ILoggerFactory;
import org.slf4j.Logger; import org.slf4j.Logger;
/** /**
* Created by colezlaw on 6/14/15. * Created on 6/14/15.
*
* @author colezlaw
*/ */
public class MavenLoggerFactory implements ILoggerFactory { public class MavenLoggerFactory implements ILoggerFactory {

View File

@@ -48,7 +48,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder {
/** /**
* Maven mojos have their own logger, so we'll use one of those * Maven mojos have their own logger, so we'll use one of those
*/ */
private Log log; private Log log = null;
/** /**
* Set the Task which will this is to log through. * Set the Task which will this is to log through.
@@ -70,7 +70,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder {
private static final String loggerFactoryClassStr = MavenLoggerFactory.class.getName(); private static final String loggerFactoryClassStr = MavenLoggerFactory.class.getName();
/** /**
* The ILoggerFactory instance returned by the {@link #getLoggerFactory} method should always be the smae object * The ILoggerFactory instance returned by the {@link #getLoggerFactory} method should always be the same object
*/ */
private ILoggerFactory loggerFactory; private ILoggerFactory loggerFactory;
@@ -83,6 +83,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder {
* *
* @return the logger factory * @return the logger factory
*/ */
@Override
public ILoggerFactory getLoggerFactory() { public ILoggerFactory getLoggerFactory() {
return loggerFactory; return loggerFactory;
} }
@@ -92,6 +93,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder {
* *
* @return the logger factory class string * @return the logger factory class string
*/ */
@Override
public String getLoggerFactoryClassStr() { public String getLoggerFactoryClassStr() {
return loggerFactoryClassStr; return loggerFactoryClassStr;
} }

View File

@@ -230,8 +230,13 @@ Copyright (c) 2014 - Jeremy Long. All Rights Reserved.
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>slf4j-simple</artifactId> <artifactId>logback-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -0,0 +1,13 @@
<configuration>
<contextName>dependency-check</contextName>
<!-- Logging configuration -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.out</Target>
<encoder>
<pattern>[%level] %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="console"/>
</root>
</configuration>