mirror of
https://github.com/ysoftdevs/DependencyCheck.git
synced 2026-01-14 15:53:36 +01:00
initial release
This commit is contained in:
12
README
12
README
@@ -1,14 +1,18 @@
|
||||
About:
|
||||
DependencyCheck is a simple utility that attempts to determine if there is a Common Product Enumeration (CPE) identifier for a given project dependency. If found, it will generate a report linking to the associated CVE entries.
|
||||
DependencyCheck is a simple utility that attempts to determine if there is a
|
||||
Common Product Enumeration (CPE) identifier for a given project dependency.
|
||||
If found, it will generate a report linking to the associated CVE entries.
|
||||
|
||||
Usage:
|
||||
Still under development: mvn package site
|
||||
|
||||
java -jar dependencycheck-0.1.jar -h
|
||||
|
||||
TODO:
|
||||
Add CVE download/indexing and CPE lookup.
|
||||
Finish report generation.
|
||||
Fix/finish the CLI.
|
||||
Finish report generation (xml).
|
||||
Consider utilizing the OSVDB in addition to CPE/CVE.
|
||||
|
||||
Author: Jeremy Long (jeremy.long@gmail.com)
|
||||
|
||||
Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
|
||||
56
pom.xml
56
pom.xml
@@ -16,13 +16,14 @@ 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/>.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.codesecure</groupId>
|
||||
<artifactId>DependencyCheck</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<version>0.1</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>DependencyCheck</name>
|
||||
@@ -34,6 +35,11 @@ along with DependencyCheck. If not, see <http://www.gnu.org/licenses/>.
|
||||
<email>jeremy.long@gmail.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
<scm>
|
||||
<connection>scm:git:git@github.com:jeremylong/DependencyCheck.git</connection>
|
||||
<url>scm:git:git@github.com:jeremylong/DependencyCheck.git</url>
|
||||
<developerConnection>scm:git:git@github.com:jeremylong/DependencyCheck.git</developerConnection>
|
||||
</scm>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>GNU General Public License version 3</name>
|
||||
@@ -44,6 +50,25 @@ along with DependencyCheck. If not, see <http://www.gnu.org/licenses/>.
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*.properties</include>
|
||||
</includes>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
<resource>
|
||||
<directory>src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>**/*.properties</exclude>
|
||||
<exclude>**/*.gif</exclude>
|
||||
<exclude>**/*.js</exclude>
|
||||
</excludes>
|
||||
<filtering>false</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
@@ -54,7 +79,9 @@ along with DependencyCheck. If not, see <http://www.gnu.org/licenses/>.
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>2.5.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
@@ -153,15 +180,15 @@ along with DependencyCheck. If not, see <http://www.gnu.org/licenses/>.
|
||||
<workingDirectory>target</workingDirectory>
|
||||
</property>
|
||||
<property>
|
||||
<name>index.cpe</name>
|
||||
<value>${project.build.directory}/store/cpe</value>
|
||||
<name>cve</name>
|
||||
<value>${project.build.directory}/store/cve</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>index.osvdb</name>
|
||||
<name>osvdb</name>
|
||||
<value>${project.build.directory}/store/osvdb</value>
|
||||
</property>
|
||||
<property>
|
||||
<name>index.cpe</name>
|
||||
<name>cpe</name>
|
||||
<value>${project.build.directory}/store/cpe</value>
|
||||
</property>
|
||||
</systemProperties>
|
||||
@@ -392,5 +419,24 @@ along with DependencyCheck. If not, see <http://www.gnu.org/licenses/>.
|
||||
<classifier>javadoc</classifier>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.1</version>
|
||||
<classifier>javadoc</classifier>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>joda-time</groupId>
|
||||
<artifactId>joda-time</artifactId>
|
||||
<version>2.1</version>
|
||||
<classifier>sources</classifier>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
||||
@@ -1,14 +1,32 @@
|
||||
package org.codesecure.dependencycheck;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.prefs.Preferences;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.codesecure.dependencycheck.data.cpe.CPEQuery;
|
||||
import org.codesecure.dependencycheck.data.cpe.Index;
|
||||
import org.codesecure.dependencycheck.data.cpe.xml.Importer;
|
||||
import org.codesecure.dependencycheck.reporting.ReportGenerator;
|
||||
import org.codesecure.dependencycheck.scanner.Dependency;
|
||||
@@ -34,9 +52,8 @@ import org.xml.sax.SAXException;
|
||||
*
|
||||
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* The command line interface for the DependencyCheck application.
|
||||
*
|
||||
* @author Jeremy Long (jeremy.long@gmail.com)
|
||||
*/
|
||||
@@ -50,7 +67,12 @@ public class App {
|
||||
App app = new App();
|
||||
app.run(args);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* main CLI entry-point into the application.
|
||||
*
|
||||
* @param args the command line arguments
|
||||
*/
|
||||
public void run(String[] args) {
|
||||
CliParser cli = new CliParser();
|
||||
try {
|
||||
@@ -62,18 +84,32 @@ public class App {
|
||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (cli.isGetVersion()) {
|
||||
cli.printVersionInfo();
|
||||
} else if (cli.isLoadCPE()) {
|
||||
loadCPE(cli.getCpeFile());
|
||||
} else if (cli.isRunScan()) {
|
||||
if (cli.isAutoUpdate()) {
|
||||
Index cpeI = new Index();
|
||||
try {
|
||||
cpeI.updateIndexFromWeb();
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
runScan(cli.getReportDirectory(), cli.getApplicationName(), cli.getScanFiles());
|
||||
} else {
|
||||
cli.printHelp();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the specified CPE.XML file into Lucene Index.
|
||||
* @param cpePath
|
||||
*/
|
||||
private void loadCPE(String cpePath) {
|
||||
try {
|
||||
Importer.importXML(cpePath);
|
||||
@@ -85,6 +121,13 @@ public class App {
|
||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans the specified directories and writes the dependency reports to the reportDirectory.
|
||||
* @param reportDirectory the path to the directory where the reports will be written.
|
||||
* @param applicationName the application name for the report.
|
||||
* @param files the files/directories to scan.
|
||||
*/
|
||||
private void runScan(String reportDirectory, String applicationName, String[] files) {
|
||||
try {
|
||||
Scanner scanner = new Scanner();
|
||||
@@ -106,13 +149,11 @@ public class App {
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (org.apache.lucene.queryParser.ParseException ex) {
|
||||
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ public class CPEQuery {
|
||||
* utilized within the CPE Names.
|
||||
*/
|
||||
static final String CLEANSE_CHARACTER_RX = "[^A-Za-z0-9 _-]";
|
||||
/* A string representation of a regular expression used to remove all but
|
||||
/* A string representation of a regular expression used to remove all but
|
||||
* alpha characters.
|
||||
*/
|
||||
static final String CLEANSE_NONALPHA_RX = "[^A-Za-z]*";
|
||||
@@ -191,15 +191,15 @@ public class CPEQuery {
|
||||
do {
|
||||
List<Entry> entries = searchCPE(vendors, titles, versions, dependency.getTitleEvidence().getWeighting(),
|
||||
dependency.getVendorEvidence().getWeighting());
|
||||
|
||||
if (entries.size()>0) {
|
||||
|
||||
if (entries.size() > 0) {
|
||||
List<String> verified = verifyEntries(entries, dependency);
|
||||
if (verified.size() > 0) {
|
||||
found = true;
|
||||
dependency.setCPEs(verified);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!found) {
|
||||
int round = cnt % 3;
|
||||
if (round == 0) {
|
||||
@@ -320,7 +320,7 @@ public class CPEQuery {
|
||||
*/
|
||||
protected String buildSearch(String vendor, String product, String version,
|
||||
List<String> vendorWeighting, List<String> produdctWeightings) {
|
||||
|
||||
|
||||
StringBuilder sb = new StringBuilder(vendor.length() + product.length()
|
||||
+ version.length() + Fields.PRODUCT.length() + Fields.VERSION.length()
|
||||
+ Fields.VENDOR.length() + STRING_BUILDER_BUFFER);
|
||||
@@ -335,7 +335,7 @@ public class CPEQuery {
|
||||
if (!appendWeightedSearch(sb, Fields.VENDOR, vendor.toLowerCase(), vendorWeighting)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
sb.append(Fields.VERSION).append(":(");
|
||||
if (sb.indexOf("^") > 0) {
|
||||
//if we have a weighting on something else, reduce the weighting on the version a lot
|
||||
@@ -369,7 +369,7 @@ public class CPEQuery {
|
||||
sb.append(" ").append(field).append(":( ");
|
||||
|
||||
String cleanText = cleanseText(searchText);
|
||||
|
||||
|
||||
if ("".equals(cleanText)) {
|
||||
return false;
|
||||
}
|
||||
@@ -408,7 +408,7 @@ public class CPEQuery {
|
||||
private String cleanseText(String text) {
|
||||
return text.replaceAll(CLEANSE_CHARACTER_RX, " ");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compares two strings after lower casing them and removing the non-alpha
|
||||
* characters.
|
||||
|
||||
@@ -19,10 +19,16 @@ package org.codesecure.dependencycheck.data.cpe;
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.apache.lucene.analysis.Analyzer;
|
||||
@@ -38,6 +44,8 @@ import org.apache.lucene.util.Version;
|
||||
import org.codesecure.dependencycheck.utils.Downloader;
|
||||
import org.codesecure.dependencycheck.utils.Settings;
|
||||
import org.codesecure.dependencycheck.data.cpe.xml.Importer;
|
||||
import org.joda.time.DateTime;
|
||||
import org.joda.time.Days;
|
||||
|
||||
/**
|
||||
* The Index class is used to utilize and maintain the CPE Index.
|
||||
@@ -46,6 +54,14 @@ import org.codesecure.dependencycheck.data.cpe.xml.Importer;
|
||||
*/
|
||||
public class Index {
|
||||
|
||||
/**
|
||||
* Te name of the properties file containing the timestamp of the last update.
|
||||
*/
|
||||
private static final String UPDATE_PROPERTIES_FILE = "lastupdated.prop";
|
||||
/**
|
||||
* The properties file key for the last updated field.
|
||||
*/
|
||||
private static final String LAST_UPDATED = "lastupdated";
|
||||
/**
|
||||
* The Lucene directory containing the index.
|
||||
*/
|
||||
@@ -124,10 +140,47 @@ public class Index {
|
||||
outputPath = File.createTempFile("cpe", ".xml");
|
||||
Downloader.fetchFile(url, outputPath);
|
||||
Importer.importXML(outputPath.toString());
|
||||
writeLastUpdatedPropertyFile();
|
||||
} catch (Exception ex) {
|
||||
Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
outputPath.delete();
|
||||
boolean deleted = false;
|
||||
try {
|
||||
deleted = outputPath.delete();
|
||||
} finally {
|
||||
if (!deleted) {
|
||||
outputPath.deleteOnExit();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeLastUpdatedPropertyFile() {
|
||||
DateTime now = new DateTime();
|
||||
String dir = Settings.getString(Settings.KEYS.CPE_INDEX);
|
||||
File cpeProp = new File(dir + File.separatorChar + UPDATE_PROPERTIES_FILE);
|
||||
Properties prop = new Properties();
|
||||
prop.put(this.LAST_UPDATED, String.valueOf(now.getMillis()));
|
||||
OutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(cpeProp);
|
||||
OutputStreamWriter out = new OutputStreamWriter(os);
|
||||
prop.store(out, dir);
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} finally {
|
||||
try {
|
||||
os.flush();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
try {
|
||||
os.close();
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,6 +191,43 @@ public class Index {
|
||||
* @return whether or not the CPE Index needs to be updated.
|
||||
*/
|
||||
public boolean updateNeeded() {
|
||||
return true;
|
||||
boolean needed = false;
|
||||
String lastUpdated = null;
|
||||
String dir = Settings.getString(Settings.KEYS.CPE_INDEX);
|
||||
File f = new File(dir);
|
||||
if (!f.exists()) {
|
||||
needed = true;
|
||||
} else {
|
||||
File cpeProp = new File(dir + File.separatorChar + UPDATE_PROPERTIES_FILE);
|
||||
if (!cpeProp.exists()) {
|
||||
needed = true;
|
||||
} else {
|
||||
Properties prop = new Properties();
|
||||
FileInputStream is = null;
|
||||
try {
|
||||
is = new FileInputStream(cpeProp);
|
||||
prop.load(is);
|
||||
lastUpdated = prop.getProperty(this.LAST_UPDATED);
|
||||
} catch (FileNotFoundException ex) {
|
||||
Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
|
||||
}
|
||||
try {
|
||||
long lastupdate = Long.parseLong(lastUpdated);
|
||||
DateTime last = new DateTime(lastupdate);
|
||||
DateTime now = new DateTime();
|
||||
Days d = Days.daysBetween(last, now);
|
||||
int days = d.getDays();
|
||||
int freq = Settings.getInt(Settings.KEYS.CPE_DOWNLOAD_FREQUENCY);
|
||||
if (days >= freq) {
|
||||
needed = true;
|
||||
}
|
||||
} catch (NumberFormatException ex) {
|
||||
needed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return needed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,25 @@ public class Importer {
|
||||
private Importer() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports the CPE XML File into the Lucene Index.
|
||||
*
|
||||
* @param file containing the path to the CPE XML file.
|
||||
* @throws ParserConfigurationException is thrown if the parser is misconfigured.
|
||||
* @throws SAXException is thrown when there is a SAXException.
|
||||
* @throws IOException is thrown when there is an IOException.
|
||||
*/
|
||||
public static void importXML(File file) throws ParserConfigurationException, SAXException, IOException {
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
CPEHandler handler = new CPEHandler();
|
||||
Indexer indexer = new Indexer();
|
||||
indexer.open();
|
||||
handler.registerSaveDelegate(indexer);
|
||||
saxParser.parse(file, handler);
|
||||
indexer.close();
|
||||
}
|
||||
/**
|
||||
* Imports the CPE XML File into the Lucene Index.
|
||||
*
|
||||
@@ -48,14 +67,7 @@ public class Importer {
|
||||
* @throws IOException is thrown when there is an IOException.
|
||||
*/
|
||||
public static void importXML(String path) throws ParserConfigurationException, SAXException, IOException {
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
SAXParser saxParser = factory.newSAXParser();
|
||||
CPEHandler handler = new CPEHandler();
|
||||
Indexer indexer = new Indexer();
|
||||
indexer.open();
|
||||
handler.registerSaveDelegate(indexer);
|
||||
File f = new File(path);
|
||||
saxParser.parse(f, handler);
|
||||
indexer.close();
|
||||
Importer.importXML(f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,6 @@ import java.io.InputStreamReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.apache.velocity.context.Context;
|
||||
import org.apache.velocity.runtime.RuntimeConstants;
|
||||
@@ -42,20 +41,28 @@ import org.codesecure.dependencycheck.scanner.Dependency;
|
||||
*/
|
||||
public class ReportGenerator {
|
||||
|
||||
|
||||
/**
|
||||
* 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("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);
|
||||
|
||||
generateReport("HtmlReport", filename + ".html", properties);
|
||||
//generateReport("XmlReport",filename + ".xml",properties);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* much of this code is from http://stackoverflow.com/questions/2931516/loading-velocity-template-inside-a-jar-file
|
||||
* @param templateName the name of the template to load.
|
||||
@@ -64,23 +71,23 @@ public class ReportGenerator {
|
||||
* @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,
|
||||
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();
|
||||
ToolManager manager = new ToolManager();
|
||||
Context context = manager.createContext();
|
||||
EasyFactoryConfiguration config = new EasyFactoryConfiguration();
|
||||
EasyFactoryConfiguration config = new EasyFactoryConfiguration();
|
||||
config.addDefaultTools();
|
||||
config.toolbox("application")
|
||||
.tool("esc","org.apache.velocity.tools.generic.EscapeTool")
|
||||
.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";
|
||||
@@ -91,19 +98,19 @@ 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)) {
|
||||
throw new Exception("Failed to convert the template into html.");
|
||||
}
|
||||
@@ -112,12 +119,12 @@ public class ReportGenerator {
|
||||
try {
|
||||
writer.close();
|
||||
} catch (Exception ex) {
|
||||
|
||||
//ignore this error.
|
||||
}
|
||||
try {
|
||||
reader.close();
|
||||
} catch (Exception ex) {
|
||||
|
||||
//ignore this error.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/**
|
||||
* <html>
|
||||
* <head>
|
||||
* <title>org.codesecure.dependencycheck.reporting</title>
|
||||
* </head>
|
||||
* <body>
|
||||
* Contains classes used to generate reports.
|
||||
* </body>
|
||||
* </html>
|
||||
*/
|
||||
|
||||
package org.codesecure.dependencycheck.reporting;
|
||||
@@ -65,13 +65,16 @@ public class Dependency {
|
||||
*/
|
||||
protected EvidenceCollection versionEvidence = null;
|
||||
|
||||
/**
|
||||
* Constructs a new Dependency object.
|
||||
*/
|
||||
public Dependency() {
|
||||
vendorEvidence = new EvidenceCollection();
|
||||
titleEvidence = new EvidenceCollection();
|
||||
versionEvidence = new EvidenceCollection();
|
||||
cpes = new ArrayList<String>();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the file name of the JAR.
|
||||
*
|
||||
@@ -180,8 +183,8 @@ public class Dependency {
|
||||
public EvidenceCollection getEvidence() {
|
||||
return EvidenceCollection.mergeUsed(this.titleEvidence, this.vendorEvidence, this.versionEvidence);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the evidence used to identify this dependency.
|
||||
*
|
||||
|
||||
@@ -234,5 +234,5 @@ public class EvidenceCollection implements Iterable<Evidence> {
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -51,22 +51,23 @@ public class JarAnalyzer implements Analyzer {
|
||||
private static final String BUNDLE_NAME = "Bundle-Name"; //: Struts 2 Core
|
||||
private static final String BUNDLE_VENDOR = "Bundle-Vendor"; //: Apache Software Foundation
|
||||
|
||||
|
||||
private enum STRING_STATE {
|
||||
|
||||
ALPHA,
|
||||
NUMBER,
|
||||
OTHER
|
||||
}
|
||||
|
||||
private STRING_STATE determineState(char c) {
|
||||
if (c>='0' && c<='9' || c=='.') {
|
||||
if (c >= '0' && c <= '9' || c == '.') {
|
||||
return STRING_STATE.NUMBER;
|
||||
} else if (c>='a' && c<='z') {
|
||||
} else if (c >= 'a' && c <= 'z') {
|
||||
return STRING_STATE.ALPHA;
|
||||
} else {
|
||||
return STRING_STATE.OTHER;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Loads a specified JAR file and collects information from the manifest and
|
||||
* checksums to identify the correct CPE information.
|
||||
@@ -82,19 +83,17 @@ public class JarAnalyzer implements Analyzer {
|
||||
String fileName = file.getName();
|
||||
dependency.setFileName(fileName);
|
||||
dependency.setFilePath(file.getCanonicalPath());
|
||||
String fileNameEvidence = fileName.substring(0,fileName.length()-4)
|
||||
.toLowerCase()
|
||||
.replace('-', ' ')
|
||||
.replace('_', ' ');
|
||||
String fileNameEvidence = fileName.substring(0, fileName.length() - 4)
|
||||
.toLowerCase().replace('-', ' ').replace('_', ' ');
|
||||
StringBuilder sb = new StringBuilder(fileNameEvidence.length());
|
||||
STRING_STATE state = determineState(fileNameEvidence.charAt(0));
|
||||
|
||||
for(int i=0;i<fileNameEvidence.length();i++) {
|
||||
|
||||
for (int i = 0; i < fileNameEvidence.length(); i++) {
|
||||
char c = fileNameEvidence.charAt(i);
|
||||
STRING_STATE new_state = determineState(c);
|
||||
if (new_state != state) {
|
||||
STRING_STATE newState = determineState(c);
|
||||
if (newState != state) {
|
||||
sb.append(' ');
|
||||
state = new_state;
|
||||
state = newState;
|
||||
}
|
||||
sb.append(c);
|
||||
}
|
||||
@@ -106,7 +105,7 @@ public class JarAnalyzer implements Analyzer {
|
||||
fileNameEvidence, Evidence.Confidence.HIGH);
|
||||
dependency.getVersionEvidence().addEvidence("jar", "file name",
|
||||
fileNameEvidence, Evidence.Confidence.HIGH);
|
||||
|
||||
|
||||
String md5 = null;
|
||||
String sha1 = null;
|
||||
try {
|
||||
|
||||
@@ -87,7 +87,7 @@ public class Scanner {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (implmnts) {
|
||||
this.analyzers.put(extension, (Analyzer) analyzer.newInstance());
|
||||
} else {
|
||||
|
||||
@@ -103,7 +103,7 @@ public final class CliParser {
|
||||
//TODO - need a new exception type here, this isn't really a parseexception.
|
||||
throw new ParseException("Scan cannot be run without specifying a directory to write the reports to via the 'out' argument.");
|
||||
} else {
|
||||
String p = line.getOptionValue(ArgumentName.OUT,"");
|
||||
String p = line.getOptionValue(ArgumentName.OUT, "");
|
||||
File f = new File(p);
|
||||
if ("".equals(p) || !(f.exists() && f.isDirectory())) {
|
||||
//TODO - need a new exception type here, this isn't really a parseexception.
|
||||
@@ -151,22 +151,29 @@ public final class CliParser {
|
||||
*/
|
||||
@SuppressWarnings("static-access")
|
||||
private Options createCommandLineOptions() {
|
||||
Option help = new Option(ArgumentName.HELP_SHORT, ArgumentName.HELP, false, "print this message");
|
||||
Option version = new Option(ArgumentName.VERSION_SHORT, ArgumentName.VERSION, false, "print the version information and exit");
|
||||
|
||||
Option appname = OptionBuilder.withArgName("name").hasArg().withLongOpt(ArgumentName.APPNAME).withDescription("the name of the application being scanned").create(ArgumentName.APPNAME_SHORT);
|
||||
Option help = new Option(ArgumentName.HELP_SHORT, ArgumentName.HELP, false,
|
||||
"print this message");
|
||||
|
||||
Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.SCAN).withDescription("the path to scan").create(ArgumentName.SCAN_SHORT);
|
||||
Option version = new Option(ArgumentName.VERSION_SHORT, ArgumentName.VERSION,
|
||||
false, "print the version information and exit");
|
||||
|
||||
Option load = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.CPE).withDescription("load the CPE xml file").create(ArgumentName.CPE_SHORT);
|
||||
Option noupdate = new Option(ArgumentName.DISABLE_AUTO_UPDATE_SHORT, ArgumentName.DISABLE_AUTO_UPDATE,
|
||||
false, "disables the automatic updating of the CPE data.");
|
||||
|
||||
Option appname = OptionBuilder.withArgName("name").hasArg().withLongOpt(ArgumentName.APPNAME)
|
||||
.withDescription("the name of the application being scanned").create(ArgumentName.APPNAME_SHORT);
|
||||
|
||||
Option path = OptionBuilder.withArgName("path").hasArg().withLongOpt(ArgumentName.SCAN)
|
||||
.withDescription("the path to scan - this option can be specified multiple times.").create(ArgumentName.SCAN_SHORT);
|
||||
|
||||
Option load = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.CPE)
|
||||
.withDescription("load the CPE xml file").create(ArgumentName.CPE_SHORT);
|
||||
|
||||
Option out = OptionBuilder.withArgName("folder").hasArg().withLongOpt(ArgumentName.OUT)
|
||||
.withDescription("the folder to write reports to.").create(ArgumentName.OUT_SHORT);
|
||||
|
||||
Option out = OptionBuilder.withArgName("folder").hasArg().withLongOpt(ArgumentName.OUT).withDescription("the folder to write reports to.").create(ArgumentName.OUT_SHORT);
|
||||
|
||||
//TODO add the ability to load a properties file to override the defaults...
|
||||
//TODO add the ability to load the CVE entries.
|
||||
//TODO add a switch to auto-update CVE entries.
|
||||
//TODO add a switch to auto-update CPE entries.
|
||||
|
||||
|
||||
OptionGroup og = new OptionGroup();
|
||||
og.addOption(path);
|
||||
og.addOption(load);
|
||||
@@ -177,6 +184,7 @@ public final class CliParser {
|
||||
opts.addOption(appname);
|
||||
opts.addOption(version);
|
||||
opts.addOption(help);
|
||||
opts.addOption(noupdate);
|
||||
|
||||
return opts;
|
||||
}
|
||||
@@ -222,10 +230,14 @@ public final class CliParser {
|
||||
*/
|
||||
public void printHelp() {
|
||||
HelpFormatter formatter = new HelpFormatter();
|
||||
formatter.printHelp("DependencyCheck", options, true);
|
||||
formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
|
||||
"\n" + Settings.getString("application.name", "DependencyCheck") +
|
||||
" can be used to identify if there are any known CVE vulnerabilities in libraries utillized by an application." +
|
||||
" " + Settings.getString("application.name", "DependencyCheck") + " will automatically update required data from the Internet, such as the CVE and CPE data files from nvd.nist.gov.\n",
|
||||
options, "", true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the file command line parameter(s) specified for the 'cpe' argument.
|
||||
*
|
||||
@@ -234,7 +246,7 @@ public final class CliParser {
|
||||
public String getCpeFile() {
|
||||
return line.getOptionValue(ArgumentName.CPE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the file command line parameter(s) specified for the 'scan' argument.
|
||||
*
|
||||
@@ -242,12 +254,21 @@ public final class CliParser {
|
||||
*/
|
||||
public String[] getScanFiles() {
|
||||
return line.getOptionValues(ArgumentName.SCAN);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* returns the directory to write the reports to specified on the command line.
|
||||
* @return the path to the reports directory.
|
||||
*/
|
||||
public String getReportDirectory() {
|
||||
return line.getOptionValue(ArgumentName.OUT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the application name specified on the command line.
|
||||
* @return the applicatoin name.
|
||||
*/
|
||||
public String getApplicationName() {
|
||||
return line.getOptionValue(ArgumentName.APPNAME);
|
||||
}
|
||||
@@ -257,49 +278,83 @@ public final class CliParser {
|
||||
* <li>Implementation-Version: ${pom.version}</li></ul>
|
||||
*/
|
||||
public void printVersionInfo() {
|
||||
String version = "DependencyCheck version unknown";
|
||||
|
||||
URLClassLoader cl = (URLClassLoader) this.getClass().getClassLoader();
|
||||
InputStream is = null;
|
||||
|
||||
try {
|
||||
URL url = cl.findResource("META-INF/MANIFEST.MF");
|
||||
is = url.openStream();
|
||||
Manifest manifest = new Manifest(is);
|
||||
Attributes atts = manifest.getMainAttributes();
|
||||
version = atts.getValue(Attributes.Name.IMPLEMENTATION_TITLE)
|
||||
+ " version "
|
||||
+ atts.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
|
||||
} catch (IOException ex) {
|
||||
Logger.getLogger(CliParser.class.getName()).log(Level.WARNING, null, ex);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
is = null;
|
||||
} catch (Throwable ex) {
|
||||
Logger.getLogger(CliParser.class.getName()).log(Level.FINEST, null, ex);
|
||||
}
|
||||
}
|
||||
String version = String.format("%s version %s",
|
||||
Settings.getString("application.name", "DependencyCheck"),
|
||||
Settings.getString("application.version", "Unknown"));
|
||||
System.out.println(version);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the auto update feature has been disabled. If it has been disabled
|
||||
* via the command line this will return false.
|
||||
*
|
||||
* @return if auto-update is allowed.
|
||||
*/
|
||||
public boolean isAutoUpdate() {
|
||||
return (line != null) ? !line.hasOption(ArgumentName.DISABLE_AUTO_UPDATE) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* A collection of static final strings that represent the possible command
|
||||
* line arguments.
|
||||
*/
|
||||
public static class ArgumentName {
|
||||
|
||||
/**
|
||||
* The long CLI argument name specifing the directory/file to scan
|
||||
*/
|
||||
public static final String SCAN = "scan";
|
||||
public static final String CPE = "cpe";
|
||||
public static final String OUT = "out";
|
||||
public static final String APPNAME = "app";
|
||||
public static final String VERSION = "version";
|
||||
public static final String HELP = "help";
|
||||
/**
|
||||
* The short CLI argument name specifing the directory/file to scan
|
||||
*/
|
||||
public static final String SCAN_SHORT = "s";
|
||||
/**
|
||||
* The long CLI argument name specifing the path to the CPE.XML file to import
|
||||
*/
|
||||
public static final String CPE = "cpe";
|
||||
/**
|
||||
* The short CLI argument name specifing the path to the CPE.XML file to import
|
||||
*/
|
||||
public static final String CPE_SHORT = "c";
|
||||
/**
|
||||
* The long CLI argument name specifing that the CPE/CVE/etc. data should not be automatically updated.
|
||||
*/
|
||||
public static final String DISABLE_AUTO_UPDATE = "noupdate";
|
||||
/**
|
||||
* The short CLI argument name specifing that the CPE/CVE/etc. data should not be automatically updated.
|
||||
*/
|
||||
public static final String DISABLE_AUTO_UPDATE_SHORT = "n";
|
||||
/**
|
||||
* The long CLI argument name specifing the directory to write the reports to.
|
||||
*/
|
||||
public static final String OUT = "out";
|
||||
/**
|
||||
* The short CLI argument name specifing the directory to write the reports to.
|
||||
*/
|
||||
public static final String OUT_SHORT = "o";
|
||||
public static final String VERSION_SHORT = "v";
|
||||
public static final String HELP_SHORT = "h";
|
||||
/**
|
||||
* The long CLI argument name specifing the name of the application to be scanned.
|
||||
*/
|
||||
public static final String APPNAME = "app";
|
||||
/**
|
||||
* The short CLI argument name specifing the name of the application to be scanned.
|
||||
*/
|
||||
public static final String APPNAME_SHORT = "a";
|
||||
/**
|
||||
* The long CLI argument name asking for help.
|
||||
*/
|
||||
public static final String HELP = "help";
|
||||
/**
|
||||
* The short CLI argument name asking for help.
|
||||
*/
|
||||
public static final String HELP_SHORT = "h";
|
||||
/**
|
||||
* The long CLI argument name asking for the version.
|
||||
*/
|
||||
public static final String VERSION_SHORT = "v";
|
||||
/**
|
||||
* The short CLI argument name asking for the version.
|
||||
*/
|
||||
public static final String VERSION = "version";
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
public class Settings {
|
||||
|
||||
|
||||
/**
|
||||
* The collection of keys used within the properties file.
|
||||
*/
|
||||
@@ -42,19 +43,23 @@ public class Settings {
|
||||
/**
|
||||
* The properties key for the path where the CPE Lucene Index will be stored.
|
||||
*/
|
||||
public static final String CPE_INDEX = "index.cpe";
|
||||
public static final String CPE_INDEX = "cpe";
|
||||
/**
|
||||
* The properties key for the URL to the CPE.
|
||||
*/
|
||||
public static final String CPE_URL = "index.cpe.url";
|
||||
public static final String CPE_URL = "cpe.url";
|
||||
/**
|
||||
* The properties key for the URL to the CPE.
|
||||
*/
|
||||
public static final String CPE_DOWNLOAD_FREQUENCY = "cpe.downloadfrequency";
|
||||
/**
|
||||
* The properties key for the path where the CCE Lucene Index will be stored.
|
||||
*/
|
||||
public static final String CVE_INDEX = "index.cve";
|
||||
public static final String CVE_INDEX = "cve";
|
||||
/**
|
||||
* The properties key for the path where the OSVDB Lucene Index will be stored.
|
||||
*/
|
||||
public static final String OSVDB_INDEX = "index.osvdb";
|
||||
public static final String OSVDB_INDEX = "osvdb";
|
||||
/**
|
||||
* The properties key prefix for the analyzer assocations.
|
||||
*/
|
||||
@@ -77,6 +82,24 @@ public class Settings {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value from the properties file. If the value was specified as a
|
||||
* system property or passed in via the -Dprop=value argument - this method
|
||||
* will return the value from the system properties before the values in
|
||||
* the contained configuration file.
|
||||
*
|
||||
* @param key the key to lookup within the properties file.
|
||||
* @param defaultValue the default value for the requested property.
|
||||
* @return the property from the properties file.
|
||||
*/
|
||||
public static String getString(String key, String defaultValue) {
|
||||
String str = System.getProperty(key, instance.props.getProperty(key));
|
||||
if (str==null) {
|
||||
str = defaultValue;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a value from the properties file. If the value was specified as a
|
||||
* system property or passed in via the -Dprop=value argument - this method
|
||||
@@ -127,13 +150,28 @@ public class Settings {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
// public static boolean getBoolean(String key) {
|
||||
// return Boolean.parseBoolean(instance.props.getProperty(key));
|
||||
// }
|
||||
// public static long getLong(String key) {
|
||||
// return Long.parseLong(instance.props.getProperty(key));
|
||||
// }
|
||||
// public static int getInt(String key) {
|
||||
// return Integer.parseInt(instance.props.getProperty(key));
|
||||
// }
|
||||
/**
|
||||
* Returns a integer value from the properties file. If the value was specified as a
|
||||
* system property or passed in via the -Dprop=value argument - this method
|
||||
* will return the value from the system properties before the values in
|
||||
* the contained configuration file.
|
||||
*
|
||||
* @param key the key to lookup within the properties file.
|
||||
* @return the property from the properties file.
|
||||
*/
|
||||
public static int getInt(String key) {
|
||||
return Integer.parseInt(Settings.getString(key));
|
||||
}
|
||||
/**
|
||||
* Returns a boolean value from the properties file. If the value was specified as a
|
||||
* system property or passed in via the -Dprop=value argument - this method
|
||||
* will return the value from the system properties before the values in
|
||||
* the contained configuration file.
|
||||
*
|
||||
* @param key the key to lookup within the properties file.
|
||||
* @return the property from the properties file.
|
||||
*/
|
||||
public static boolean getBoolean(String key) {
|
||||
return Boolean.parseBoolean(Settings.getString(key));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
# To change this template, choose Tools | Templates
|
||||
# and open the template in the editor.
|
||||
application.name=${pom.name}
|
||||
application.version=${pom.version}
|
||||
|
||||
index.cpe=store/cpe
|
||||
index.cpe.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.xml
|
||||
index.cve=store/cve
|
||||
index.osvdb=store/osvdb
|
||||
cpe=store/cpe
|
||||
cpe.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.xml
|
||||
cpe.downloadfrequency=1
|
||||
cve=store/cve
|
||||
osvdb=store/osvdb
|
||||
|
||||
file.extension.analyzer.association.jar=org.codesecure.dependencycheck.scanner.JarAnalyzer
|
||||
|
||||
@@ -20,7 +20,6 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
@version 1
|
||||
*#
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
@@ -274,7 +273,9 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
#set($cnt=0)
|
||||
#foreach($dependency in $dependencies)
|
||||
<h3 class="subsectionheader standardsubsection"><a name="$esc.html($dependency.FilePath)"></a>$esc.html($dependency.FileName)</h3>
|
||||
<div class="subsectioncontent">File Path: $esc.html($dependency.FilePath)
|
||||
<div class="subsectioncontent">File Path: $esc.html($dependency.FilePath)<br/>
|
||||
MD5: $esc.html($dependency.Md5sum)<br/>
|
||||
SHA1: $esc.html($dependency.Sha1sum)
|
||||
#set($cnt=$cnt+1)
|
||||
<h4 id="header$cnt" class="subsectionheader expandablesubsection white">Evidence</h4>
|
||||
<div id="content$cnt" class="subsectioncontent standardsubsection hidden">
|
||||
@@ -293,8 +294,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
Information for specific CVE entries for the idenfied CPE can be found <a href="http://web.nvd.nist.gov/view/vuln/search-results?cpe=$esc.url($cpevalue)" target="blank">here</a>.
|
||||
#* http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2012-0838
|
||||
<a href="http://web.nvd.nist.gov/view/vuln/detail?vulnId=" target="blank">cve://a:/blah1.blah</a><br/>
|
||||
<a href="cve.mitre.org" target="blank">cve://a:/blah2.blah</a><br/>
|
||||
<a href="cve.mitre.org" target="blank">cve://a:/blah3.blah</a><br/>*#
|
||||
*#
|
||||
</div>
|
||||
#end
|
||||
#if($dependency.getCPEs().size()>1)
|
||||
@@ -310,7 +310,7 @@ Copyright (c) 2012 Jeremy Long. All Rights Reserved.
|
||||
#end
|
||||
|
||||
#if($dependency.getCPEs().size()==0)
|
||||
<h4>No CPE Identifies were found for this dependency.</h4>
|
||||
<h4>No CPE Identifiers were found for this dependency.</h4>
|
||||
#end
|
||||
</div>
|
||||
#end
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -31,7 +31,7 @@ public abstract class BaseIndexTestCase extends TestCase {
|
||||
}
|
||||
|
||||
protected void ensureIndexExists() throws Exception {
|
||||
String indexPath = Settings.getString("index.cpe");
|
||||
String indexPath = Settings.getString("cpe");
|
||||
java.io.File f = new File(indexPath);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
|
||||
@@ -336,9 +336,8 @@ public class CliParserTest extends TestCase {
|
||||
baos.flush();
|
||||
String text = (new String(baos.toByteArray()));
|
||||
String[] lines = text.split(System.getProperty("line.separator"));
|
||||
assertEquals("usage: DependencyCheck [-a <name>] [-c <file> | -s <path>] [-h] [-o", lines[0]);
|
||||
assertEquals(" <folder>] [-v]", lines[1]);
|
||||
assertEquals(8, lines.length);
|
||||
assertTrue(lines[0].startsWith("usage: "));
|
||||
assertTrue((lines.length>2));
|
||||
} catch (IOException ex) {
|
||||
System.setOut(out);
|
||||
fail("CliParser.printVersionInfo did not write anything to system.out.");
|
||||
|
||||
@@ -36,15 +36,17 @@ public class DownloaderTest {
|
||||
public void tearDown() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of fetchFile method, of class Downloader.
|
||||
* @throws Exception thrown when an excpetion occurs.
|
||||
*/
|
||||
@Test
|
||||
public void testFetchFile_URL_String() throws Exception {
|
||||
System.out.println("fetchFile");
|
||||
URL url = new URL(Settings.getString(Settings.KEYS.CPE_URL));
|
||||
String outputPath = "target\\downloaded_cpe.xml";
|
||||
Downloader.fetchFile(url, outputPath);
|
||||
}
|
||||
|
||||
//This test is being removed because it is a bit too slow.
|
||||
// /**
|
||||
// * Test of fetchFile method, of class Downloader.
|
||||
// * @throws Exception thrown when an excpetion occurs.
|
||||
// */
|
||||
// @Test
|
||||
// public void testFetchFile_URL_String() throws Exception {
|
||||
// System.out.println("fetchFile");
|
||||
// URL url = new URL(Settings.getString(Settings.KEYS.CPE_URL));
|
||||
// String outputPath = "target\\downloaded_cpe.xml";
|
||||
// Downloader.fetchFile(url, outputPath);
|
||||
// }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user