Compare commits

..

3 Commits

Author SHA1 Message Date
Jeremy Long
2fcc325af7 bug fixes
Former-commit-id: 02eac4d4a7073e140181c39fa8137b37f86e5f74
2012-12-02 22:22:25 -05:00
Jeremy Long
5334cf7def fixed reported bug
Former-commit-id: 0f4d2380d45811e2c181996651ed1541376a3cb6
2012-11-20 20:11:08 -05:00
Jeremy Long
a8a85a5947 Cleaned up reporting
Former-commit-id: ba7c493381c4a5d9b1078e8f8c8a44f3ffc119f3
2012-11-17 07:57:55 -05:00
23 changed files with 234 additions and 115 deletions

View File

@@ -7,10 +7,10 @@ If found, it will generate a report linking to the associated CVE entries.
Usage:
$ mvn package
$ cd target
$ java -jar DependencyCheck-0.2.3.jar -h
$ java -jar DependencyCheck-0.2.3.jar -a Testing -out . -scan ./test-classes/org.mortbay.jetty.jar -scan ./test-classes/struts2-core-2.1.2.jar -scan ./lib
$ java -jar DependencyCheck-0.2.3.1.jar -h
$ java -jar DependencyCheck-0.2.3.1.jar -a Testing -out . -scan ./test-classes/org.mortbay.jetty.jar -scan ./test-classes/struts2-core-2.1.2.jar -scan ./lib
Then load the resulting 'Testing.html' into your favorite browser.
Then load the resulting 'DependencyCheck-Report.html' into your favorite browser.
Author: Jeremy Long (jeremy.long@gmail.com)

16
pom.xml
View File

@@ -23,7 +23,7 @@ along with DependencyCheck. If not, see <http://www.gnu.org/licenses/>.
<groupId>org.codesecure</groupId>
<artifactId>DependencyCheck</artifactId>
<version>0.2.3</version>
<version>0.2.3.1</version>
<packaging>jar</packaging>
<name>DependencyCheck</name>
@@ -100,7 +100,7 @@ along with DependencyCheck. If not, see <http://www.gnu.org/licenses/>.
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.8.1</version>
<configuration>
<bottom>Copyright &#169; 2012 Jeremy Long. All Rights Reserved.</bottom>
<bottom>Copyright&#169; 2012 Jeremy Long. All Rights Reserved.</bottom>
</configuration>
</plugin>
<plugin>
@@ -243,6 +243,9 @@ along with DependencyCheck. If not, see <http://www.gnu.org/licenses/>.
<value>target/data/cpe</value>
</property>
</systemProperties>
<includes>
<include>**/*IntegrationTest.java</include>
</includes>
</configuration>
<executions>
<execution>
@@ -448,5 +451,14 @@ along with DependencyCheck. If not, see <http://www.gnu.org/licenses/>.
<artifactId>hawtdb</artifactId>
<version>1.6</version>
</dependency>-->
<!-- The following dependencies are only scanned during integration testing -->
<!--<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>2.5.5</version>
<scope>test</scope>
</dependency>-->
</dependencies>
</project>

View File

@@ -158,9 +158,9 @@ public class App {
scanner.analyzeDependencies();
List<Dependency> dependencies = scanner.getDependencies();
ReportGenerator report = new ReportGenerator();
ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers());
try {
report.generateReports(reportDirectory, applicationName, dependencies);
report.generateReports(reportDirectory);
} catch (IOException ex) {
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
} catch (Exception ex) {

View File

@@ -195,7 +195,8 @@ public class Engine {
try {
a.initialize();
} catch (Exception ex) {
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, "Exception occured initializing " + a.getName() + ".", ex);
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE,
"Exception occured initializing " + a.getName() + ".", ex);
try {
a.close();
} catch (Exception ex1) {
@@ -254,8 +255,23 @@ public class Engine {
try {
source.update();
} catch (UpdateException ex) {
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, "Unable to update " + source.getClass().getName(), ex);
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE,
"Unable to update " + source.getClass().getName(), ex);
}
}
}
/**
* Returns a full list of all of the analyzers. This is useful
* for reporting which analyzers where used.
* @return a list of Analyzers
*/
public List<Analyzer> getAnalyzers() {
List<Analyzer> ret = new ArrayList<Analyzer>();
for (AnalysisPhase phase : AnalysisPhase.values()) {
List<Analyzer> analyzerList = analyzers.get(phase);
ret.addAll(analyzerList);
}
return ret;
}
}

View File

@@ -186,6 +186,7 @@ public class JarAnalyzer extends AbstractAnalyzer {
parseManifest(dependency);
analyzePackageNames(dependency);
analyzePOM(dependency);
addPredefinedData(dependency);
} catch (IOException ex) {
throw new AnalysisException("Exception occured reading the JAR file.", ex);
} catch (JAXBException ex) {
@@ -615,4 +616,15 @@ public class JarAnalyzer extends AbstractAnalyzer {
sb.append(text.substring(end + 1));
return interpolateString(sb.toString(), properties); //yes yes, this should be a loop...
}
private void addPredefinedData(Dependency dependency) {
Evidence spring = new Evidence("Manifest",
"Implementation-Title",
"Spring Framework",
Evidence.Confidence.HIGH);
if (dependency.getProductEvidence().getEvidence().contains(spring)) {
dependency.getVendorEvidence().addEvidence("a priori", "vendor", "SpringSource", Evidence.Confidence.HIGH);
}
}
}

View File

@@ -149,23 +149,11 @@ public class CPEAnalyzer implements org.codesecure.dependencycheck.analyzer.Anal
Confidence versionConf = Confidence.HIGH;
String vendors = addEvidenceWithoutDuplicateTerms("", dependency.getVendorEvidence(), vendorConf);
//dependency.getVendorEvidence().toString(vendorConf);
// if ("".equals(vendors)) {
// vendors = STRING_THAT_WILL_NEVER_BE_IN_THE_INDEX;
// }
String products = addEvidenceWithoutDuplicateTerms("", dependency.getProductEvidence(), productConf);
///dependency.getProductEvidence().toString(productConf);
// if ("".equals(products)) {
// products = STRING_THAT_WILL_NEVER_BE_IN_THE_INDEX;
// }
String versions = addEvidenceWithoutDuplicateTerms("", dependency.getVersionEvidence(), versionConf);
//dependency.getVersionEvidence().toString(versionConf);
// if ("".equals(versions)) {
// versions = STRING_THAT_WILL_NEVER_BE_IN_THE_INDEX;
// }
boolean found = false;
int cnt = 0;
int ctr = 0;
do {
List<Entry> entries = searchCPE(vendors, products, versions, dependency.getProductEvidence().getWeighting(),
dependency.getVendorEvidence().getWeighting());
@@ -186,14 +174,14 @@ public class CPEAnalyzer implements org.codesecure.dependencycheck.analyzer.Anal
if (!found) {
int round = cnt % 3;
int round = ctr % 3;
if (round == 0) {
vendorConf = reduceConfidence(vendorConf);
if (dependency.getVendorEvidence().contains(vendorConf)) {
//vendors += " " + dependency.getVendorEvidence().toString(vendorConf);
vendors = addEvidenceWithoutDuplicateTerms(vendors, dependency.getVendorEvidence(), vendorConf);
} else {
cnt += 1;
ctr += 1;
round += 1;
}
}
@@ -203,7 +191,7 @@ public class CPEAnalyzer implements org.codesecure.dependencycheck.analyzer.Anal
//products += " " + dependency.getProductEvidence().toString(productConf);
products = addEvidenceWithoutDuplicateTerms(products, dependency.getProductEvidence(), productConf);
} else {
cnt += 1;
ctr += 1;
round += 1;
}
}
@@ -215,7 +203,7 @@ public class CPEAnalyzer implements org.codesecure.dependencycheck.analyzer.Anal
}
}
}
} while (!found && (++cnt) < 9);
} while (!found && (++ctr) < 9);
}
/**

View File

@@ -45,17 +45,12 @@ public class Entry {
public static Entry parse(Document doc) {
Entry entry = new Entry();
try {
entry.setName(doc.get(Fields.NAME));
entry.parseName(doc.get(Fields.NAME));
entry.setTitle(doc.get(Fields.TITLE));
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(Entry.class.getName()).log(Level.SEVERE, null, ex);
entry.name = doc.get(Fields.NAME);
}
// entry.vendor = doc.get(Fields.VENDOR);
// entry.version = doc.get(Fields.VERSION);
// //entry.revision = doc.get(Fields.REVISION);
// entry.product = doc.get(Fields.TITLE);
// entry.nvdId = doc.get(Fields.NVDID);
return entry;
}
/**
@@ -95,15 +90,12 @@ public class Entry {
}
/**
* Set the value of name and calls parseName to obtain the
* vendor:product:version:revision
* Set the value of name
*
* @param name new value of name
* @throws UnsupportedEncodingException should never be thrown...
*/
public void setName(String name) throws UnsupportedEncodingException {
public void setName(String name) {
this.name = name;
parseName();
}
/**
* The status of the CPE Entry.
@@ -310,15 +302,17 @@ public class Entry {
* <p>Results in:</p> <ul> <li>Vendor: apache</li> <li>Product: struts</li>
* <li>Version: 1.1</li> <li>Revision: rc2</li> </ul>
*
* @param cpeName the cpe name
* @throws UnsupportedEncodingException should never be thrown...
*/
private void parseName() throws UnsupportedEncodingException {
if (name != null && name.length() > 7) {
String[] data = name.substring(7).split(":");
public void parseName(String cpeName) throws UnsupportedEncodingException {
this.name = cpeName;
if (cpeName != null && cpeName.length() > 7) {
String[] data = cpeName.substring(7).split(":");
if (data.length >= 1) {
vendor = URLDecoder.decode(data[0], "UTF-8");
vendor = URLDecoder.decode(data[0], "UTF-8").replaceAll("[_-]", " ");
if (data.length >= 2) {
product = URLDecoder.decode(data[1], "UTF-8");
product = URLDecoder.decode(data[1], "UTF-8").replaceAll("[_-]", " ");
if (data.length >= 3) {
version = URLDecoder.decode(data[2], "UTF-8");
if (data.length >= 4) {

View File

@@ -100,6 +100,11 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
}
File path = new File(exePath.getCanonicalFile() + File.separator + fileName);
path = new File(path.getCanonicalPath());
if (!path.exists()) {
if (!path.mkdirs()) {
throw new IOException("Unable to create CPE Data directory");
}
}
return path;
}
@@ -113,6 +118,7 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
Map fieldAnalyzers = new HashMap();
fieldAnalyzers.put(Fields.VERSION, new KeywordAnalyzer());
fieldAnalyzers.put(Fields.NAME, new KeywordAnalyzer());
PerFieldAnalyzerWrapper wrapper = new PerFieldAnalyzerWrapper(
new StandardAnalyzer(Version.LUCENE_35), fieldAnalyzers);

View File

@@ -66,7 +66,7 @@ public class CPEHandler extends DefaultHandler {
skip = (temp != null && temp.equals("true"));
try {
if (!skip && name.startsWith("cpe:/a:")) {
entry.setName(name);
entry.parseName(name);
} else {
skip = true;
}

View File

@@ -27,7 +27,6 @@ import org.apache.lucene.index.Term;
import org.codesecure.dependencycheck.data.cpe.Entry;
import org.codesecure.dependencycheck.data.cpe.Fields;
import org.codesecure.dependencycheck.data.cpe.Index;
import org.codesecure.dependencycheck.data.lucene.LuceneUtils;
/**
* The Indexer is used to convert a CPE Entry, retrieved from the CPE XML file,
@@ -46,7 +45,8 @@ public class Indexer extends Index implements EntrySaveDelegate {
*/
public void saveEntry(Entry entry) throws CorruptIndexException, IOException {
Document doc = convertEntryToDoc(entry);
Term term = new Term(Fields.NVDID, LuceneUtils.escapeLuceneQuery(entry.getNvdId()));
//Term term = new Term(Fields.NVDID, LuceneUtils.escapeLuceneQuery(entry.getNvdId()));
Term term = new Term(Fields.NAME, entry.getName());
indexWriter.updateDocument(term, doc);
}

View File

@@ -98,6 +98,11 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
}
File path = new File(exePath.getCanonicalFile() + File.separator + fileName);
path = new File(path.getCanonicalPath());
if (!path.exists()) {
if (!path.mkdirs()) {
throw new IOException("Unable to create NVD CVE Data directory");
}
}
return path;
}

View File

@@ -43,15 +43,17 @@ public class Importer {
*/
public static void importXML(File file) {
NvdCveParser indexer = null;
org.codesecure.dependencycheck.data.cpe.xml.Indexer cpeIndexer = null;
try {
indexer = new NvdCveParser();
indexer.openIndexWriter();
//HACK - hack to ensure all CPE data is stored in the index.
cpeIndexer = new org.codesecure.dependencycheck.data.cpe.xml.Indexer();
cpeIndexer.openIndexWriter();
indexer.setCPEIndexer(cpeIndexer);
indexer.parse(file);
} catch (CorruptIndexException ex) {
Logger.getLogger(Importer.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
@@ -60,6 +62,9 @@ public class Importer {
if (indexer != null) {
indexer.close();
}
if (cpeIndexer != null) {
cpeIndexer.close();
}
}
}
// public static void importXML(File file) throws FileNotFoundException, IOException, JAXBException,

View File

@@ -23,14 +23,17 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.FieldInfo.IndexOptions;
import org.apache.lucene.index.Term;
import org.codesecure.dependencycheck.data.cpe.Entry;
import org.codesecure.dependencycheck.data.nvdcve.Fields;
import org.codesecure.dependencycheck.data.nvdcve.Index;
@@ -40,6 +43,19 @@ import org.codesecure.dependencycheck.data.nvdcve.Index;
*/
public class NvdCveParser extends Index {
//HACK - this has initially been placed here as a hack because not all
// of the CPEs listed in the NVD CVE are actually in the CPE xml file
// hosted by NIST.
private org.codesecure.dependencycheck.data.cpe.xml.Indexer cpeIndexer = null;
/**
* Adds the CPE Index to add additional CPEs found by parsing the NVD CVE.
* @param indexer the CPE Indexer to write new CPEs into.
*/
public void setCPEIndexer(org.codesecure.dependencycheck.data.cpe.xml.Indexer indexer) {
this.cpeIndexer = indexer;
}
/**
* Parses an NVD CVE xml file using a buffered readerd. This
* method maybe more fragile then using a partial-unmarshalling SAX
@@ -164,10 +180,27 @@ public class NvdCveParser extends Index {
* Adds a CPE to the Lucene Document
* @param cpe a string representing a CPE
* @param doc a lucene document
* @throws CorruptIndexException is thrown if the CPE Index is corrupt
* @throws IOException is thrown if there is an IO Exception while writting to the CPE Index
*/
private void addVulnerableCpe(String cpe, Document doc) {
private void addVulnerableCpe(String cpe, Document doc) throws CorruptIndexException, IOException {
Field vulnerable = new Field(Fields.VULNERABLE_CPE, cpe, Field.Store.NO, Field.Index.ANALYZED);
vulnerable.setIndexOptions(IndexOptions.DOCS_ONLY);
doc.add(vulnerable);
//HACK - this has initially been placed here as a hack because not all
// of the CPEs listed in the NVD CVE are actually in the CPE xml file
// hosted by NIST.
Entry cpeEntry = new Entry();
try {
cpeEntry.parseName(cpe);
cpeEntry.setNvdId("0");
cpeEntry.setTitle(cpe);
} catch (UnsupportedEncodingException ex) {
Logger.getLogger(NvdCveParser.class.getName()).log(Level.SEVERE, null, ex);
}
if (cpeIndexer != null) {
cpeIndexer.saveEntry(cpeEntry);
}
}
}

View File

@@ -184,7 +184,7 @@ public class EvidenceCollection implements Iterable<Evidence> {
text = text.toLowerCase();
for (Evidence e : this.list) {
if (e.used && e.value.contains(text)) {
if (e.used && e.value.toLowerCase().contains(text)) {
return true;
}
}

View File

@@ -18,15 +18,15 @@ package org.codesecure.dependencycheck.reporting;
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
import java.io.FileInputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.velocity.app.VelocityEngine;
@@ -35,66 +35,110 @@ import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;
import org.apache.velocity.tools.ToolManager;
import org.apache.velocity.tools.config.EasyFactoryConfiguration;
import org.codesecure.dependencycheck.analyzer.Analyzer;
import org.codesecure.dependencycheck.dependency.Dependency;
/**
* The ReportGenerator is used to, as the name implies, generate reports. Internally
* the generator uses the Velocity Templating Engine. The ReportGenerator exposes
* a list of Dependencies to the template when generating the report.
*
* @author Jeremy Long (jeremy.long@gmail.com)
*/
public class ReportGenerator {
/**
* The Velocity Engine.
*/
private VelocityEngine engine = null;
/**
* The Velocity Engine Context.
*/
private Context context = null;
/**
* Constructs a new ReportGenerator.
*
* @param applicationName the application name being analyzed
* @param dependencies the list of dependencies
* @param analyzers the list of analyzers used.
*/
public ReportGenerator(String applicationName, List<Dependency> dependencies, List<Analyzer> analyzers) {
engine = createVelocityEngine();
context = createContext();
engine.init();
context.put("applicationName", applicationName);
context.put("dependencies", dependencies);
context.put("analyzers", analyzers);
}
/**
* Creates a new Velocity Engine.
* @return a velocity engine.
*/
private VelocityEngine createVelocityEngine() {
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
return ve;
}
/**
* Creates a new Velocity Context initialized with escape and date tools.
* @return a Velcotiy Context.
*/
private Context createContext() {
ToolManager manager = new ToolManager();
Context c = manager.createContext();
EasyFactoryConfiguration config = new EasyFactoryConfiguration();
config.addDefaultTools();
config.toolbox("application")
.tool("esc", "org.apache.velocity.tools.generic.EscapeTool")
.tool("org.apache.velocity.tools.generic.DateTool");
manager.configure(config);
return c;
}
/**
* Generates the Dependency Reports for the identified dependencies.
*
* @param outputDir the path where the reports should be written.
* @param applicationName the name of the application that was scanned.
* @param dependencies a list of dependencies to include in the report.
* @throws IOException is thrown when the template file does not exist.
* @throws Exception is thrown if there is an error writting out the
* reports.
*/
public void generateReports(String outputDir, String applicationName, List<Dependency> dependencies) throws IOException, Exception {
Map<String, Object> properties = new HashMap<String, Object>();
properties.put("dependencies", dependencies);
properties.put("applicationName", applicationName);
String reportName = applicationName.replaceAll("[^a-zA-Z0-9-_ \\.]+", "");
String filename = outputDir + File.separatorChar + reportName;
generateReport("HtmlReport", filename + ".html", properties);
//generateReport("XmlReport",filename + ".xml",properties);
public void generateReports(String outputDir) throws IOException, Exception {
generateReport("HtmlReport", outputDir + File.separator + "DependencyCheck-Report.html");
//generateReport("XmlReport", outputDir + File.separator + "DependencyCheck-Report.xml");
}
/**
* much of this code is from
* http://stackoverflow.com/questions/2931516/loading-velocity-template-inside-a-jar-file
* Generates a report from a given Velocity Template. The template name
* provided can be the name of a template contained in the jar file, such as
* 'XmlReport' or 'HtmlReport', or the template name can be the path to a template file.
*
* @param templateName the name of the template to load.
* @param outFileName The filename and path to write the report to.
* @param properties a map of properties to load into the velocity context.
* @param outFileName the filename and path to write the report to.
* @throws IOException is thrown when the template file does not exist.
* @throws Exception is thrown when an exception occurs.
*/
protected void generateReport(String templateName, String outFileName,
Map<String, Object> properties) throws IOException, Exception {
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ToolManager manager = new ToolManager();
Context context = manager.createContext();
EasyFactoryConfiguration config = new EasyFactoryConfiguration();
config.addDefaultTools();
config.toolbox("application").tool("esc", "org.apache.velocity.tools.generic.EscapeTool").tool("org.apache.velocity.tools.generic.DateTool");
manager.configure(config);
ve.init();
final String templatePath = "templates/" + templateName + ".vsl";
InputStream input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
public void generateReport(String templateName, String outFileName) throws IOException, Exception {
InputStream input = null;
String templatePath = null;
File f = new File(templateName);
if (f.exists() && f.isFile()) {
try {
templatePath = templateName;
input = new FileInputStream(f);
} catch (FileNotFoundException ex) {
Logger.getLogger(ReportGenerator.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
templatePath = "templates/" + templateName + ".vsl";
input = this.getClass().getClassLoader().getResourceAsStream(templatePath);
}
if (input == null) {
throw new IOException("Template file doesn't exist");
}
@@ -102,19 +146,10 @@ public class ReportGenerator {
InputStreamReader reader = new InputStreamReader(input);
BufferedWriter writer = null;
//VelocityContext context = new VelocityContext();
//load the data into the context
if (properties != null) {
for (Map.Entry<String, Object> property : properties.entrySet()) {
context.put(property.getKey(), property.getValue());
}
}
try {
writer = new BufferedWriter(new FileWriter(new File(outFileName)));
if (!ve.evaluate(context, writer, templatePath, reader)) {
if (!engine.evaluate(context, writer, templatePath, reader)) {
throw new Exception("Failed to convert the template into html.");
}
writer.flush();

View File

@@ -326,7 +326,7 @@ public final class CliParser {
* @return if auto-update is allowed.
*/
public boolean isAutoUpdate() {
return (line != null) ? !line.hasOption(ArgumentName.DISABLE_AUTO_UPDATE) : false;
return (line != null) ? !line.hasOption(ArgumentName.DISABLE_AUTO_UPDATE) : true;
}
/**

View File

@@ -34,7 +34,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
</script>
<script type="text/javascript">
$(document).ready(function() {
$(".expandablesubsection").click(function (e) {
$(".expandable").click(function (e) {
e = e || window.event;
var h = e.target || e.srcElement;
var content = "#content" + h.id.substr(6);
@@ -64,7 +64,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
.hidden {
display: none;
}
.exandable {}
.expandablesubsection {
cursor: pointer;
/*background-image: url(img/plus.gif);*/
@@ -285,8 +285,12 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
<div class="sectioncontent">Report Generated On: $date<br/><br/>
Dependencies Scanned:&nbsp;$dependencies.size()<br/><br/>
<div class="indent">
#foreach($dependency in $dependencies)
<a href="#$esc.html($esc.url($dependency.FilePath))">$esc.html($dependency.FileName)</a><br/>
#foreach($dependency in $dependencies)
#if($dependency.getVulnerabilities().size()>0)
<a href="#$esc.html($esc.url($dependency.FilePath))">$esc.html($dependency.FileName)</a>&nbsp;<b style="color:#ff0000;">&#8226;</b><br/>
#else
<a href="#$esc.html($esc.url($dependency.FilePath))">$esc.html($dependency.FileName)</a><br/>
#end
#end
</div>
<h2>Dependencies</h2>
@@ -308,7 +312,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
#if ( $dependency.analysisExceptions.size() != 0 )
#set($cnt=$cnt+1)
<h4 id="header$cnt" class="subsectionheader expandablesubsection red">Exceptions Occured During Analysis</h4>
<h4 id="header$cnt" class="subsectionheader expandable expandablesubsection red">Exceptions Occured During Analysis</h4>
<div id="content$cnt" class="subsectioncontent standardsubsection hidden">
<ul>
#foreach($ex in $dependency.analysisExceptions)
@@ -336,7 +340,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
</div>
#end
#set($cnt=$cnt+1)
<h4 id="header$cnt" class="subsectionheader expandablesubsection white">Evidence</h4>
<h4 id="header$cnt" class="subsectionheader expandable expandablesubsection white">Evidence</h4>
<div id="content$cnt" class="subsectioncontent standardsubsection hidden">
<table class="lined fullwidth" border="0">
<tr><th class="left" style="width:10%;">Source</th><th class="left" style="width:20%;">Name</th><th class="left" style="width:70%;">Value</th></tr>
@@ -377,7 +381,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
</div>
#if($dependency.getVulnerabilities().size()>0)
#set($cnt=$cnt+1)
<h4 id="header$cnt" class="subsectionheader white">Published Vulnerabilities</h4>
<h4 id="header$cnt" class="subsectionheader expandable collaspablesubsection white">Published Vulnerabilities</h4>
<div id="content$cnt" class="subsectioncontent standardsubsection">
#foreach($vuln in $dependency.getVulnerabilities())
<p><b><a target="_blank" href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=$esc.url($vuln.name)">$esc.html($vuln.name)</a></b></p>

View File

@@ -6,4 +6,4 @@
<body>
<menu ref="reports" />
</body>
</project>
</project>

View File

@@ -51,7 +51,8 @@ public class EngineIntegrationTest {
instance.scan(path);
assertTrue(instance.getDependencies().size() > 0);
instance.analyzeDependencies();
ReportGenerator rg = new ReportGenerator();
rg.generateReports("./target/", "DependencyCheck", instance.getDependencies());
ReportGenerator rg = new ReportGenerator("DependencyCheck",
instance.getDependencies(), instance.getAnalyzers());
rg.generateReports("./target/");
}
}

View File

@@ -63,7 +63,8 @@ public class JarAnalyzerTest {
instance.analyze(result);
boolean found = false;
for (Evidence e : result.getProductEvidence()) {
if (e.getName().equals("package-title") && e.getValue().equals("org.mortbay.http")) {
if (e.getName().equalsIgnoreCase("package-title")
&& e.getValue().equalsIgnoreCase("org.mortbay.http")) {
found = true;
break;
}
@@ -72,7 +73,8 @@ public class JarAnalyzerTest {
found = false;
for (Evidence e : result.getVendorEvidence()) {
if (e.getName().equals("implementation-url") && e.getValue().equals("http://jetty.mortbay.org")) {
if (e.getName().equalsIgnoreCase("implementation-url")
&& e.getValue().equalsIgnoreCase("http://jetty.mortbay.org")) {
found = true;
break;
}
@@ -81,7 +83,8 @@ public class JarAnalyzerTest {
found = false;
for (Evidence e : result.getVersionEvidence()) {
if (e.getName().equals("Implementation-Version") && e.getValue().equals("4.2.27")) {
if (e.getName().equalsIgnoreCase("Implementation-Version")
&& e.getValue().equalsIgnoreCase("4.2.27")) {
found = true;
break;
}

View File

@@ -98,11 +98,16 @@ public class CPEAnalyzerTest extends BaseIndexTestCase {
JarAnalyzer jarAnalyzer = new JarAnalyzer();
Dependency depends = new Dependency(file);
jarAnalyzer.analyze(depends);
File fileSpring = new File(this.getClass().getClassLoader().getResource("spring-core-2.5.5.jar").getPath());
Dependency spring = new Dependency(fileSpring);
jarAnalyzer.analyze(spring);
CPEAnalyzer instance = new CPEAnalyzer();
instance.open();
String expResult = "cpe:/a:apache:struts:2.1.2";
instance.determineCPE(depends);
instance.determineCPE(spring);
instance.close();
assertTrue("Incorrect match", depends.getIdentifiers().size() == 1);
assertTrue("Incorrect match", depends.getIdentifiers().get(0).getValue().equals(expResult));
@@ -131,7 +136,7 @@ public class CPEAnalyzerTest extends BaseIndexTestCase {
expResult = "cpe:/a:apache:struts:2.3.1.2";
result = instance.searchCPE(vendor, product, version);
assertEquals(expResult, result.get(0).getName());
instance.close();
}

View File

@@ -35,7 +35,7 @@ public class EntryTest extends TestCase {
String name = "cpe:/a:apache:struts:1.1:rc2";
Entry instance = new Entry();
instance.setName(name);
instance.parseName(name);
assertEquals(name,instance.getName());
assertEquals("apache", instance.getVendor());

Binary file not shown.