diff --git a/pom.xml b/pom.xml
index f544f208e..ef11cc871 100644
--- a/pom.xml
+++ b/pom.xml
@@ -232,6 +232,18 @@ along with DependencyCheck. If not, see .
org.apache.maven.plugins
maven-failsafe-plugin
2.12.4
+
+
+
+ cve
+ ../data/cve
+
+
+ cpe
+ ../data/cpe
+
+
+
diff --git a/src/main/java/org/codesecure/dependencycheck/App.java b/src/main/java/org/codesecure/dependencycheck/App.java
index a0b7ee8dc..0273d125b 100644
--- a/src/main/java/org/codesecure/dependencycheck/App.java
+++ b/src/main/java/org/codesecure/dependencycheck/App.java
@@ -22,6 +22,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
+import java.net.URLDecoder;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.LogManager;
@@ -69,11 +70,32 @@ public class App {
app.run(args);
}
+ private static File getLoggingDirectory() throws IOException {
+ String fileName = "logs";
+ String filePath = App.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+ String decodedPath = URLDecoder.decode(filePath, "UTF-8");
+ File exePath = new File(decodedPath);
+ if (!exePath.isDirectory()) {
+ exePath = exePath.getParentFile();
+ }
+ File path = new File(exePath.getCanonicalFile() + File.separator + fileName);
+ path = new File(path.getCanonicalPath());
+ return path;
+ }
+
private static void prepareLogger() {
//while java doc for JUL says to use preferences api - it throws an exception...
//Preferences.systemRoot().put("java.util.logging.config.file", "log.properties");
//System.getProperties().put("java.util.logging.config.file", "configuration/log.properties");
- File dir = new File("logs");
+ File dir;
+ try {
+ dir = getLoggingDirectory();
+ } catch (IOException ex) {
+ Logger.getLogger(App.class.getName()).log(Level.SEVERE, "Unable to get default logging location, "
+ + "using the working directory instead.", ex);
+ dir = new File("logs");
+ }
+
if (!dir.exists()) {
dir.mkdir();
}
diff --git a/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java b/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java
index 9e4fa3391..4d7354c87 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/cpe/Index.java
@@ -75,17 +75,32 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
* @throws IOException is thrown if an IOException occurs.
*/
public Directory getDirectory() throws IOException {
- String fileName = Settings.getString(Settings.KEYS.CPE_INDEX);
- String filePath = Index.class.getProtectionDomain().getCodeSource().getLocation().getPath();
- String decodedPath = URLDecoder.decode(filePath, "UTF-8");
-
- File path = new File(decodedPath + File.separator + fileName);
- path = new File(path.getCanonicalPath());
+ File path = getDataDirectory();
Directory dir = FSDirectory.open(path);
return dir;
}
+ /**
+ * Retrieves the directory that the JAR file exists in so that
+ * we can ensure we always use a common data directory.
+ *
+ * @return the data directory for this index.
+ * @throws IOException is thrown if an IOException occurs of course...
+ */
+ protected File getDataDirectory() throws IOException {
+ String fileName = Settings.getString(Settings.KEYS.CPE_INDEX);
+ String filePath = Index.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+ String decodedPath = URLDecoder.decode(filePath, "UTF-8");
+ File exePath = new File(decodedPath);
+ if (!exePath.isDirectory()) {
+ exePath = exePath.getParentFile();
+ }
+ File path = new File(exePath.getCanonicalFile() + File.separator + fileName);
+ path = new File(path.getCanonicalPath());
+ return path;
+ }
+
/**
* Creates an Analyzer for the CPE Index.
*
@@ -158,8 +173,14 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
*
* @param timeStamp the timestamp to write.
*/
- private void writeLastUpdatedPropertyFile(long timeStamp) {
- String dir = Settings.getString(Settings.KEYS.CPE_INDEX);
+ private void writeLastUpdatedPropertyFile(long timeStamp) throws UpdateException {
+ String dir;
+ try {
+ dir = getDataDirectory().getCanonicalPath();
+ } catch (IOException ex) {
+ Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
+ throw new UpdateException("Unable to locate the last updated properties file.", ex);
+ }
File cpeProp = new File(dir + File.separatorChar + UPDATE_PROPERTIES_FILE);
Properties prop = new Properties();
prop.put(Index.LAST_UPDATED, String.valueOf(timeStamp));
@@ -198,8 +219,10 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
* is incorrect.
* @throws DownloadFailedException is thrown if there is an error
* downloading the cpe.meta data file.
+ * @throws UpdateException is thrown if there is an error locating the last updated
+ * properties file.
*/
- public long updateNeeded() throws MalformedURLException, DownloadFailedException {
+ public long updateNeeded() throws MalformedURLException, DownloadFailedException, UpdateException {
long retVal = 0;
long lastUpdated = 0;
long currentlyPublishedDate = retrieveCurrentCPETimestampFromWeb();
@@ -207,12 +230,24 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
throw new DownloadFailedException("Unable to retrieve valid timestamp from cpe.meta file");
}
- String dir = Settings.getString(Settings.KEYS.CPE_INDEX);
- File f = new File(dir);
+ //String dir = Settings.getString(Settings.KEYS.CPE_INDEX);
+ File f;
+ try {
+ f = getDataDirectory(); //new File(dir);
+ } catch (IOException ex) {
+ Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
+ throw new UpdateException("Unable to locate last updated properties file.", ex);
+ }
if (!f.exists()) {
retVal = currentlyPublishedDate;
} else {
- File cpeProp = new File(dir + File.separatorChar + UPDATE_PROPERTIES_FILE);
+ File cpeProp;
+ try {
+ cpeProp = new File(f.getCanonicalPath() + File.separatorChar + UPDATE_PROPERTIES_FILE);
+ } catch (IOException ex) {
+ Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
+ throw new UpdateException("Unable to find last updated properties file.", ex);
+ }
if (!cpeProp.exists()) {
retVal = currentlyPublishedDate;
} else {
diff --git a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/Index.java b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/Index.java
index dad110f23..6a381dd21 100644
--- a/src/main/java/org/codesecure/dependencycheck/data/nvdcve/Index.java
+++ b/src/main/java/org/codesecure/dependencycheck/data/nvdcve/Index.java
@@ -67,21 +67,36 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
private static final String LAST_UPDATED_BASE = "lastupdated.";
/**
- * Returns the directory that holds the NVD CVE Index.
+ * Returns the directory that holds the NVD CVE Index. Note, this
+ * returns the path where the class or jar file exists.
*
* @return the Directory containing the NVD CVE Index.
* @throws IOException is thrown if an IOException occurs.
*/
public Directory getDirectory() throws IOException {
+ File path = getDataDirectory();
+ Directory dir = FSDirectory.open(path);
+ return dir;
+ }
+
+ /**
+ * Retrieves the directory that the JAR file exists in so that
+ * we can ensure we always use a common data directory.
+ *
+ * @return the data directory for this index.
+ * @throws IOException is thrown if an IOException occurs of course...
+ */
+ protected File getDataDirectory() throws IOException {
String fileName = Settings.getString(Settings.KEYS.CVE_INDEX);
String filePath = Index.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String decodedPath = URLDecoder.decode(filePath, "UTF-8");
-
- File path = new File(decodedPath + File.separator + fileName);
+ File exePath = new File(decodedPath);
+ if (!exePath.isDirectory()) {
+ exePath = exePath.getParentFile();
+ }
+ File path = new File(exePath.getCanonicalFile() + File.separator + fileName);
path = new File(path.getCanonicalPath());
- Directory dir = FSDirectory.open(path);
-
- return dir;
+ return path;
}
/**
@@ -171,8 +186,14 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
*
* @param timeStamp the timestamp to write.
*/
- private void writeLastUpdatedPropertyFile(Map updated) {
- String dir = Settings.getString(Settings.KEYS.CVE_INDEX);
+ private void writeLastUpdatedPropertyFile(Map updated) throws UpdateException {
+ String dir;
+ try {
+ dir = getDataDirectory().getCanonicalPath();
+ } catch (IOException ex) {
+ Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
+ throw new UpdateException("Unable to locate last updated properties file.", ex);
+ }
File cveProp = new File(dir + File.separatorChar + UPDATE_PROPERTIES_FILE);
Properties prop = new Properties();
@@ -187,8 +208,10 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
prop.store(out, dir);
} catch (FileNotFoundException ex) {
Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
+ throw new UpdateException("Unable to find last updated properties file.", ex);
} catch (IOException ex) {
Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
+ throw new UpdateException("Unable to update last updated properties file.", ex);
} finally {
try {
os.flush();
@@ -212,10 +235,11 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
* @return the NvdCveUrl of the files that need to be updated.
* @throws MalformedURLException is thrown if the URL for the NVD CVE Meta
* data is incorrect.
- * @throws DownloadFailedException is thrown if there is an error
+ * @throws DownloadFailedException is thrown if there is an error.
* downloading the nvd cve download data file.
+ * @throws UpdateException Is thrown if there is an issue with the last updated properties file.
*/
- public Map updateNeeded() throws MalformedURLException, DownloadFailedException {
+ public Map updateNeeded() throws MalformedURLException, DownloadFailedException, UpdateException {
Map currentlyPublished;
try {
@@ -227,7 +251,14 @@ public class Index extends AbstractIndex implements CachedWebDataSource {
if (currentlyPublished == null) {
throw new DownloadFailedException("Unable to retrieve valid timestamp from nvd cve downloads page");
}
- String dir = Settings.getString(Settings.KEYS.CVE_INDEX);
+ String dir;
+ try {
+ dir = getDataDirectory().getCanonicalPath();
+ } catch (IOException ex) {
+ Logger.getLogger(Index.class.getName()).log(Level.SEVERE, null, ex);
+ throw new UpdateException("Unable to locate last updated properties file.", ex);
+ }
+
File f = new File(dir);
if (f.exists()) {
File cveProp = new File(dir + File.separatorChar + UPDATE_PROPERTIES_FILE);
diff --git a/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java b/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java
index 9175f9091..6eedcb4be 100644
--- a/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java
+++ b/src/main/java/org/codesecure/dependencycheck/utils/CliParser.java
@@ -93,17 +93,20 @@ public final class CliParser {
validatePathExists(getScanFiles());
if (!line.hasOption(ArgumentName.OUT)) {
//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.");
+ 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, "");
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.
- throw new ParseException("A valid directory name must be specified for the 'out' argument.");
+ throw new ParseException("A valid directory name must be specified for "
+ + "the 'out' argument.");
}
}
if (!line.hasOption(ArgumentName.APPNAME)) {
- throw new ParseException("Scan cannot be run without specifying an application name via the 'app' argument.");
+ throw new ParseException("Scan cannot be run without specifying an application "
+ + "name via the 'app' argument.");
}
}
}
@@ -160,15 +163,25 @@ public final class CliParser {
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 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 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 load = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.CPE)
+ .withDescription("load the CPE xml file.")
+ .create(ArgumentName.CPE_SHORT);
- Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.PROP).withDescription("a property file to load.").create(ArgumentName.PROP_SHORT);
+ Option props = OptionBuilder.withArgName("file").hasArg().withLongOpt(ArgumentName.PROP)
+ .withDescription("a property file to load.")
+ .create(ArgumentName.PROP_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...
@@ -237,7 +250,8 @@ public final class CliParser {
+ "using the -p argument or by passing them in as system properties." + nl
+ nl + " " + Settings.KEYS.PROXY_URL + "\t\t the proxy URL to use when downloading resources."
+ nl + " " + Settings.KEYS.PROXY_PORT + "\t\t the proxy port to use when downloading resources."
- + nl + " " + Settings.KEYS.CONNECTION_TIMEOUT + "\t the cconnection timeout (in milliseconds) to use" + nl + "\t\t\t when downloading resources.";
+ + nl + " " + Settings.KEYS.CONNECTION_TIMEOUT + "\t the cconnection timeout (in milliseconds) to use"
+ + nl + "\t\t\t when downloading resources.";
}
formatter.printHelp(Settings.getString("application.name", "DependencyCheck"),
diff --git a/src/test/java/org/codesecure/dependencycheck/data/cpe/BaseIndexTestCase.java b/src/test/java/org/codesecure/dependencycheck/data/cpe/BaseIndexTestCase.java
index 2f13f5daa..96bee0fb5 100644
--- a/src/test/java/org/codesecure/dependencycheck/data/cpe/BaseIndexTestCase.java
+++ b/src/test/java/org/codesecure/dependencycheck/data/cpe/BaseIndexTestCase.java
@@ -9,6 +9,8 @@ import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URLDecoder;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import junit.framework.TestCase;
@@ -30,8 +32,22 @@ public abstract class BaseIndexTestCase extends TestCase {
ensureIndexExists();
}
+ protected static File getDataDirectory() throws IOException {
+ String fileName = Settings.getString(Settings.KEYS.CPE_INDEX);
+ String filePath = BaseIndexTestCase.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+ String decodedPath = URLDecoder.decode(filePath, "UTF-8");
+ File exePath = new File(decodedPath);
+ if (!exePath.isDirectory()) {
+ exePath = exePath.getParentFile();
+ }
+ File path = new File(exePath.getCanonicalFile() + File.separator + fileName);
+ path = new File(path.getCanonicalPath());
+ return path;
+ }
+
public static void ensureIndexExists() throws Exception {
- String indexPath = Settings.getString(Settings.KEYS.CPE_INDEX);
+ //String indexPath = Settings.getString(Settings.KEYS.CPE_INDEX);
+ String indexPath = getDataDirectory().getCanonicalPath();
java.io.File f = new File(indexPath);
if (!f.exists()) {
f.mkdirs();
diff --git a/src/test/java/org/codesecure/dependencycheck/data/nvdcve/BaseIndexTestCase.java b/src/test/java/org/codesecure/dependencycheck/data/nvdcve/BaseIndexTestCase.java
index 3efbc6aa6..1898b15d3 100644
--- a/src/test/java/org/codesecure/dependencycheck/data/nvdcve/BaseIndexTestCase.java
+++ b/src/test/java/org/codesecure/dependencycheck/data/nvdcve/BaseIndexTestCase.java
@@ -10,6 +10,8 @@ import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.URLDecoder;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import junit.framework.TestCase;
@@ -31,8 +33,23 @@ public abstract class BaseIndexTestCase extends TestCase {
ensureIndexExists();
}
+
+ protected static File getDataDirectory() throws IOException {
+ String fileName = Settings.getString(Settings.KEYS.CVE_INDEX);
+ String filePath = BaseIndexTestCase.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+ String decodedPath = URLDecoder.decode(filePath, "UTF-8");
+ File exePath = new File(decodedPath);
+ if (!exePath.isDirectory()) {
+ exePath = exePath.getParentFile();
+ }
+ File path = new File(exePath.getCanonicalFile() + File.separator + fileName);
+ path = new File(path.getCanonicalPath());
+ return path;
+ }
+
public static void ensureIndexExists() throws Exception {
- String indexPath = Settings.getString(Settings.KEYS.CVE_INDEX);
+ //String indexPath = Settings.getString(Settings.KEYS.CVE_INDEX);
+ String indexPath = getDataDirectory().getCanonicalPath();
java.io.File f = new File(indexPath);
if (!f.exists()) {
f.mkdirs();
diff --git a/src/test/java/org/codesecure/dependencycheck/data/nvdcve/IndexTest.java b/src/test/java/org/codesecure/dependencycheck/data/nvdcve/IndexTest.java
index 02c2a0b4b..135c63cdb 100644
--- a/src/test/java/org/codesecure/dependencycheck/data/nvdcve/IndexTest.java
+++ b/src/test/java/org/codesecure/dependencycheck/data/nvdcve/IndexTest.java
@@ -45,6 +45,8 @@ public class IndexTest extends BaseIndexTestCase {
Index instance = new Index();
String exp = File.separatorChar + "target" + File.separatorChar + "data" + File.separatorChar + "cve";
Directory result = instance.getDirectory();
- assertTrue(result.toString().contains(exp));
+
+ assertTrue("Recieved '" + result.toString() + "' and excpected '" + exp + "'.",
+ result.toString().contains(exp));
}
}
diff --git a/src/test/java/org/codesecure/dependencycheck/utils/SettingsTest.java b/src/test/java/org/codesecure/dependencycheck/utils/SettingsTest.java
index 4edcd7032..8f2e5a6fa 100644
--- a/src/test/java/org/codesecure/dependencycheck/utils/SettingsTest.java
+++ b/src/test/java/org/codesecure/dependencycheck/utils/SettingsTest.java
@@ -38,7 +38,7 @@ public class SettingsTest extends TestCase {
public void testGetString() {
System.out.println("getString");
String key = Settings.KEYS.CPE_INDEX;
- String expResult = "target/data/cpe";
+ String expResult = "../data/cpe";
String result = Settings.getString(key);
assertTrue(result.endsWith(expResult));
}