fixed analyzer method signature, added SpringCleaningAnalyzer, and removed ArchiveAnalyzer interface

Former-commit-id: 789fcd7a7c463ee2528c9a325a8536f2cc9278c5
This commit is contained in:
Jeremy Long
2013-01-09 22:49:41 -05:00
parent d1194f23d7
commit bb1e47ae43
13 changed files with 74 additions and 92 deletions

View File

@@ -472,7 +472,7 @@ along with DependencyCheck. If not, see <http://www.gnu.org/licenses/>.
<!-- The following dependencies are only scanned during integration testing --> <!-- The following dependencies are only scanned during integration testing -->
<!--<dependency> <!--<dependency>
<groupId>org.springframework</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId> <artifactId>spring-webmvc</artifactId>
<version>2.5.5</version> <version>2.5.5</version>
<scope>test</scope> <scope>test</scope>
</dependency>--> </dependency>-->

View File

@@ -19,9 +19,7 @@
package org.codesecure.dependencycheck; package org.codesecure.dependencycheck;
import java.util.EnumMap; import java.util.EnumMap;
import org.codesecure.dependencycheck.dependency.Dependency;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@@ -33,10 +31,10 @@ import org.codesecure.dependencycheck.analyzer.AnalysisException;
import org.codesecure.dependencycheck.analyzer.AnalysisPhase; import org.codesecure.dependencycheck.analyzer.AnalysisPhase;
import org.codesecure.dependencycheck.analyzer.Analyzer; import org.codesecure.dependencycheck.analyzer.Analyzer;
import org.codesecure.dependencycheck.analyzer.AnalyzerService; import org.codesecure.dependencycheck.analyzer.AnalyzerService;
import org.codesecure.dependencycheck.analyzer.ArchiveAnalyzer;
import org.codesecure.dependencycheck.data.CachedWebDataSource; import org.codesecure.dependencycheck.data.CachedWebDataSource;
import org.codesecure.dependencycheck.data.UpdateException; import org.codesecure.dependencycheck.data.UpdateException;
import org.codesecure.dependencycheck.data.UpdateService; import org.codesecure.dependencycheck.data.UpdateService;
import org.codesecure.dependencycheck.dependency.Dependency;
import org.codesecure.dependencycheck.utils.FileUtils; import org.codesecure.dependencycheck.utils.FileUtils;
/** /**
@@ -188,9 +186,9 @@ public class Engine {
* Runs the analyzers against all of the dependencies. * Runs the analyzers against all of the dependencies.
*/ */
public void analyzeDependencies() { public void analyzeDependencies() {
//phase one initilize
for (AnalysisPhase phase : AnalysisPhase.values()) { for (AnalysisPhase phase : AnalysisPhase.values()) {
List<Analyzer> analyzerList = analyzers.get(phase); List<Analyzer> analyzerList = analyzers.get(phase);
for (Analyzer a : analyzerList) { for (Analyzer a : analyzerList) {
try { try {
a.initialize(); a.initialize();
@@ -204,41 +202,34 @@ public class Engine {
} }
continue; continue;
} }
}
}
// analysis phases
for (AnalysisPhase phase : AnalysisPhase.values()) {
List<Analyzer> analyzerList = analyzers.get(phase);
for (Analyzer a : analyzerList) {
for (Dependency d : dependencies) { for (Dependency d : dependencies) {
if (a.supportsExtension(d.getFileExtension())) { if (a.supportsExtension(d.getFileExtension())) {
try { try {
if (a instanceof ArchiveAnalyzer) { a.analyze(d, this);
ArchiveAnalyzer aa = (ArchiveAnalyzer) a;
aa.analyze(d, this);
} else {
a.analyze(d);
}
} catch (AnalysisException ex) { } catch (AnalysisException ex) {
d.addAnalysisException(ex); d.addAnalysisException(ex);
} catch (IOException ex) {
String msg = String.format("IOException occured while analyzing the file '%s'.",
d.getActualFilePath());
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, msg, ex);
} }
} }
} }
try {
a.close();
} catch (Exception ex) {
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
}
} }
} }
//Now cycle through all of the analyzers one last time to call //close/cleanup
// cleanup on any archiveanalyzers. These should only exist in the
// initial phase, but we are going to be thourough just in case.
for (AnalysisPhase phase : AnalysisPhase.values()) { for (AnalysisPhase phase : AnalysisPhase.values()) {
List<Analyzer> analyzerList = analyzers.get(phase); List<Analyzer> analyzerList = analyzers.get(phase);
for (Analyzer a : analyzerList) { for (Analyzer a : analyzerList) {
if (a instanceof ArchiveAnalyzer) { try {
ArchiveAnalyzer aa = (ArchiveAnalyzer) a; a.close();
aa.cleanup(); } catch (Exception ex) {
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
} }
} }
} }

View File

@@ -19,6 +19,7 @@
package org.codesecure.dependencycheck.analyzer; package org.codesecure.dependencycheck.analyzer;
import java.util.Set; import java.util.Set;
import org.codesecure.dependencycheck.Engine;
import org.codesecure.dependencycheck.dependency.Dependency; import org.codesecure.dependencycheck.dependency.Dependency;
/** /**
@@ -37,10 +38,12 @@ public interface Analyzer {
* description or license information for the dependency it should be added. * description or license information for the dependency it should be added.
* *
* @param dependency a dependency to analyze. * @param dependency a dependency to analyze.
* @param engine the engine that is scanning the dependencies - this is useful
* if we need to check other dependencies
* @throws AnalysisException is thrown if there is an error analyzing the * @throws AnalysisException is thrown if there is an error analyzing the
* dependency file * dependency file
*/ */
void analyze(Dependency dependency) throws AnalysisException; void analyze(Dependency dependency, Engine engine) throws AnalysisException;
/** /**
* <p>Returns a list of supported file extensions. An example would be an * <p>Returns a list of supported file extensions. An example would be an

View File

@@ -1,48 +0,0 @@
/*
* This file is part of DependencyCheck.
*
* DependencyCheck is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* DependencyCheck is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License along with
* DependencyCheck. If not, see http://www.gnu.org/licenses/.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.codesecure.dependencycheck.analyzer;
import org.codesecure.dependencycheck.dependency.Dependency;
import java.io.IOException;
import org.codesecure.dependencycheck.Engine;
/**
* An interface that defines an Analyzer that is used to expand archives and
* allow the engine to scan the contents.
*
* @author Jeremy Long (jeremy.long@gmail.com)
*/
public interface ArchiveAnalyzer {
/**
* An ArchiveAnalyzer expands an archive and calls the scan method of the
* engine on the exploded contents.
*
* @param dependency a dependency to analyze.
* @param engine the engine that is scanning the dependencies.
* @throws IOException is thrown if there is an error reading the dependency
* file
*/
void analyze(Dependency dependency, Engine engine) throws IOException;
/**
* Cleans any temporary files generated when analyzing the archive.
*/
void cleanup();
}

View File

@@ -21,6 +21,7 @@ package org.codesecure.dependencycheck.analyzer;
import org.codesecure.dependencycheck.dependency.Dependency; import org.codesecure.dependencycheck.dependency.Dependency;
import org.codesecure.dependencycheck.dependency.Evidence; import org.codesecure.dependencycheck.dependency.Evidence;
import java.util.Set; import java.util.Set;
import org.codesecure.dependencycheck.Engine;
/** /**
* *
@@ -85,10 +86,11 @@ public class FileNameAnalyzer implements Analyzer {
* Collects information about the file name. * Collects information about the file name.
* *
* @param dependency the dependency to analyze. * @param dependency the dependency to analyze.
* @param engine the engine that is scanning the dependencies
* @throws AnalysisException is thrown if there is an error reading the JAR * @throws AnalysisException is thrown if there is an error reading the JAR
* file. * file.
*/ */
public void analyze(Dependency dependency) throws AnalysisException { public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
String fileName = dependency.getFileName(); String fileName = dependency.getFileName();
int pos = fileName.lastIndexOf("."); int pos = fileName.lastIndexOf(".");

View File

@@ -23,6 +23,7 @@ import java.io.FileInputStream;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import javax.xml.bind.JAXBException; import javax.xml.bind.JAXBException;
import org.codesecure.dependencycheck.Engine;
import org.codesecure.dependencycheck.dependency.Dependency; import org.codesecure.dependencycheck.dependency.Dependency;
import org.codesecure.dependencycheck.dependency.Evidence; import org.codesecure.dependencycheck.dependency.Evidence;
import org.codesecure.dependencycheck.dependency.EvidenceCollection; import org.codesecure.dependencycheck.dependency.EvidenceCollection;
@@ -54,7 +55,7 @@ import org.codesecure.dependencycheck.utils.NonClosingStream;
* *
* @author Jeremy Long (jeremy.long@gmail.com) * @author Jeremy Long (jeremy.long@gmail.com)
*/ */
public class JarAnalyzer extends AbstractAnalyzer { public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
/** /**
* The system independent newline character. * The system independent newline character.
@@ -178,10 +179,11 @@ public class JarAnalyzer extends AbstractAnalyzer {
* checksums to identify the correct CPE information. * checksums to identify the correct CPE information.
* *
* @param dependency the dependency to analyze. * @param dependency the dependency to analyze.
* @param engine the engine that is scanning the dependencies
* @throws AnalysisException is thrown if there is an error reading the JAR * @throws AnalysisException is thrown if there is an error reading the JAR
* file. * file.
*/ */
public void analyze(Dependency dependency) throws AnalysisException { public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
try { try {
parseManifest(dependency); parseManifest(dependency);
analyzePackageNames(dependency); analyzePackageNames(dependency);

View File

@@ -29,6 +29,7 @@ import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs; import org.apache.lucene.search.TopDocs;
import org.codesecure.dependencycheck.Engine;
import org.codesecure.dependencycheck.analyzer.AnalysisException; import org.codesecure.dependencycheck.analyzer.AnalysisException;
import org.codesecure.dependencycheck.analyzer.AnalysisPhase; import org.codesecure.dependencycheck.analyzer.AnalysisPhase;
import org.codesecure.dependencycheck.data.lucene.LuceneUtils; import org.codesecure.dependencycheck.data.lucene.LuceneUtils;
@@ -436,10 +437,11 @@ public class CPEAnalyzer implements org.codesecure.dependencycheck.analyzer.Anal
* identifiers for this dependency. * identifiers for this dependency.
* *
* @param dependency The Dependency to analyze. * @param dependency The Dependency to analyze.
* @param engine The analysis engine
* @throws AnalysisException is thrown if there is an issue analyzing the * @throws AnalysisException is thrown if there is an issue analyzing the
* dependency. * dependency.
*/ */
public void analyze(Dependency dependency) throws AnalysisException { public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
try { try {
determineCPE(dependency); determineCPE(dependency);
} catch (CorruptIndexException ex) { } catch (CorruptIndexException ex) {

View File

@@ -22,6 +22,7 @@ import java.io.IOException;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.codesecure.dependencycheck.Engine;
import org.codesecure.dependencycheck.analyzer.AnalysisException; import org.codesecure.dependencycheck.analyzer.AnalysisException;
import org.codesecure.dependencycheck.analyzer.AnalysisPhase; import org.codesecure.dependencycheck.analyzer.AnalysisPhase;
import org.codesecure.dependencycheck.dependency.Dependency; import org.codesecure.dependencycheck.dependency.Dependency;
@@ -92,11 +93,12 @@ public class NvdCveAnalyzer implements org.codesecure.dependencycheck.analyzer.A
* Analyzes a dependency and attempts to determine if there are any CPE * Analyzes a dependency and attempts to determine if there are any CPE
* identifiers for this dependency. * identifiers for this dependency.
* *
* @param dependency The Dependency to analyze. * @param dependency The Dependency to analyze
* @param engine The analysis engine
* @throws AnalysisException is thrown if there is an issue analyzing the * @throws AnalysisException is thrown if there is an issue analyzing the
* dependency. * dependency
*/ */
public void analyze(Dependency dependency) throws AnalysisException { public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
for (Identifier id : dependency.getIdentifiers()) { for (Identifier id : dependency.getIdentifiers()) {
if ("cpe".equals(id.getType())) { if ("cpe".equals(id.getType())) {
try { try {

View File

@@ -138,4 +138,31 @@ public class Identifier {
public void setDescription(String description) { public void setDescription(String description) {
this.description = description; this.description = description;
} }
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Identifier other = (Identifier) obj;
if ((this.value == null) ? (other.value != null) : !this.value.equals(other.value)) {
return false;
}
if ((this.type == null) ? (other.type != null) : !this.type.equals(other.type)) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 5;
hash = 53 * hash + (this.value != null ? this.value.hashCode() : 0);
hash = 53 * hash + (this.type != null ? this.type.hashCode() : 0);
return hash;
}
} }

View File

@@ -1,4 +1,5 @@
org.codesecure.dependencycheck.analyzer.JarAnalyzer org.codesecure.dependencycheck.analyzer.JarAnalyzer
org.codesecure.dependencycheck.analyzer.FileNameAnalyzer org.codesecure.dependencycheck.analyzer.FileNameAnalyzer
org.codesecure.dependencycheck.analyzer.SpringCleaningAnalyzer
org.codesecure.dependencycheck.data.cpe.CPEAnalyzer org.codesecure.dependencycheck.data.cpe.CPEAnalyzer
org.codesecure.dependencycheck.data.nvdcve.NvdCveAnalyzer org.codesecure.dependencycheck.data.nvdcve.NvdCveAnalyzer

View File

@@ -19,7 +19,7 @@ import static org.junit.Assert.*;
* @author Jeremy Long (jeremy.long@gmail.com) * @author Jeremy Long (jeremy.long@gmail.com)
*/ */
public class FileNameAnalyzerTest { public class FileNameAnalyzerTest {
public FileNameAnalyzerTest() { public FileNameAnalyzerTest() {
} }
@@ -30,11 +30,11 @@ public class FileNameAnalyzerTest {
@AfterClass @AfterClass
public static void tearDownClass() throws Exception { public static void tearDownClass() throws Exception {
} }
@Before @Before
public void setUp() { public void setUp() {
} }
@After @After
public void tearDown() { public void tearDown() {
} }
@@ -97,7 +97,7 @@ public class FileNameAnalyzerTest {
File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath());
Dependency result = new Dependency(file); Dependency result = new Dependency(file);
FileNameAnalyzer instance = new FileNameAnalyzer(); FileNameAnalyzer instance = new FileNameAnalyzer();
instance.analyze(result); instance.analyze(result, null);
assertTrue(result.getVendorEvidence().toString().toLowerCase().contains("struts")); assertTrue(result.getVendorEvidence().toString().toLowerCase().contains("struts"));
} }
@@ -119,7 +119,7 @@ public class FileNameAnalyzerTest {
public void testClose() { public void testClose() {
System.out.println("close"); System.out.println("close");
FileNameAnalyzer instance = new FileNameAnalyzer(); FileNameAnalyzer instance = new FileNameAnalyzer();
instance.close(); instance.close();
assertTrue(true); //close does nothing. assertTrue(true); //close does nothing.
} }
} }

View File

@@ -53,14 +53,14 @@ public class JarAnalyzerTest {
File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath());
Dependency result = new Dependency(file); Dependency result = new Dependency(file);
JarAnalyzer instance = new JarAnalyzer(); JarAnalyzer instance = new JarAnalyzer();
instance.analyze(result); instance.analyze(result, null);
assertTrue(result.getVendorEvidence().toString().toLowerCase().contains("apache")); assertTrue(result.getVendorEvidence().toString().toLowerCase().contains("apache"));
assertTrue(result.getVendorEvidence().getWeighting().contains("apache")); assertTrue(result.getVendorEvidence().getWeighting().contains("apache"));
file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath()); file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jetty.jar").getPath());
result = new Dependency(file); result = new Dependency(file);
instance.analyze(result); instance.analyze(result, null);
boolean found = false; boolean found = false;
for (Evidence e : result.getProductEvidence()) { for (Evidence e : result.getProductEvidence()) {
if (e.getName().equalsIgnoreCase("package-title") if (e.getName().equalsIgnoreCase("package-title")
@@ -93,7 +93,7 @@ public class JarAnalyzerTest {
file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jmx.jar").getPath()); file = new File(this.getClass().getClassLoader().getResource("org.mortbay.jmx.jar").getPath());
result = new Dependency(file); result = new Dependency(file);
instance.analyze(result); instance.analyze(result, null);
assertEquals("org.mortbar,jmx.jar has version evidence?", result.getVersionEvidence().size(), 0); assertEquals("org.mortbar,jmx.jar has version evidence?", result.getVersionEvidence().size(), 0);
} }

View File

@@ -97,11 +97,11 @@ public class CPEAnalyzerTest extends BaseIndexTestCase {
File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath()); File file = new File(this.getClass().getClassLoader().getResource("struts2-core-2.1.2.jar").getPath());
JarAnalyzer jarAnalyzer = new JarAnalyzer(); JarAnalyzer jarAnalyzer = new JarAnalyzer();
Dependency depends = new Dependency(file); Dependency depends = new Dependency(file);
jarAnalyzer.analyze(depends); jarAnalyzer.analyze(depends, null);
File fileSpring = new File(this.getClass().getClassLoader().getResource("spring-core-2.5.5.jar").getPath()); File fileSpring = new File(this.getClass().getClassLoader().getResource("spring-core-2.5.5.jar").getPath());
Dependency spring = new Dependency(fileSpring); Dependency spring = new Dependency(fileSpring);
jarAnalyzer.analyze(spring); jarAnalyzer.analyze(spring, null);
CPEAnalyzer instance = new CPEAnalyzer(); CPEAnalyzer instance = new CPEAnalyzer();
instance.open(); instance.open();