Merge branch 'master' into jacoco

This commit is contained in:
Jeremy Long
2017-04-30 17:20:23 -04:00
39 changed files with 961 additions and 87 deletions

View File

@@ -245,11 +245,12 @@ public final class CpeMemoryIndex {
* @throws IOException is thrown if there is an issue with the underlying
* Index
*/
public TopDocs search(String searchString, int maxQueryResults) throws ParseException, IOException {
public synchronized TopDocs search(String searchString, int maxQueryResults) throws ParseException, IOException {
if (searchString == null || searchString.trim().isEmpty()) {
throw new ParseException("Query is null or empty");
}
LOGGER.debug(searchString);
resetFieldAnalyzer();
final Query query = queryParser.parse(searchString);
return search(query, maxQueryResults);
}
@@ -263,7 +264,7 @@ public final class CpeMemoryIndex {
* @throws CorruptIndexException thrown if the Index is corrupt
* @throws IOException thrown if there is an IOException
*/
public TopDocs search(Query query, int maxQueryResults) throws CorruptIndexException, IOException {
public synchronized TopDocs search(Query query, int maxQueryResults) throws CorruptIndexException, IOException {
resetFieldAnalyzer();
return indexSearcher.search(query, maxQueryResults);
}

View File

@@ -17,6 +17,9 @@
*/
package org.owasp.dependencycheck.data.update;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.MalformedURLException;
import java.util.Calendar;
import java.util.HashMap;
@@ -24,6 +27,8 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.net.URL;
import java.nio.channels.FileLock;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -31,6 +36,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.owasp.dependencycheck.data.nvdcve.ConnectionFactory;
import org.owasp.dependencycheck.data.nvdcve.CveDB;
import org.owasp.dependencycheck.data.nvdcve.DatabaseException;
import org.owasp.dependencycheck.data.nvdcve.DatabaseProperties;
@@ -89,32 +95,52 @@ public class NvdCveUpdater implements CachedWebDataSource {
/**
* Downloads the latest NVD CVE XML file from the web and imports it into
* the current CVE Database.
* the current CVE Database. A lock on a file is obtained in an attempt to
* prevent more then one thread/JVM from updating the database at the same
* time. This method may sleep upto 5 minutes.
*
* @throws UpdateException is thrown if there is an error updating the
* database
*/
@Override
public void update() throws UpdateException {
try {
if (!Settings.getBoolean(Settings.KEYS.UPDATE_NVDCVE_ENABLED, true)) {
return;
}
} catch (InvalidSettingException ex) {
LOGGER.trace("invalid setting UPDATE_NVDCVE_ENABLED", ex);
}
boolean autoUpdate = true;
try {
autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
} catch (InvalidSettingException ex) {
LOGGER.debug("Invalid setting for auto-update; using true.");
}
if (!autoUpdate) {
public synchronized void update() throws UpdateException {
if (isUpdateConfiguredFalse()) {
return;
}
initializeExecutorServices();
FileLock lock = null;
RandomAccessFile ulFile = null;
File lockFile = null;
try {
if (ConnectionFactory.isH2Connection()) {
final File dir = Settings.getDataDirectory();
lockFile = new File(dir, "odc.update.lock");
if (lockFile.isFile() && getFileAge(lockFile) > 5 && !lockFile.delete()) {
LOGGER.warn("An old db update lock file was found but the system was unable to delete the file. Consider manually deleting " + lockFile.getAbsolutePath());
}
int ctr = 0;
do {
try {
if (!lockFile.exists() && lockFile.createNewFile()) {
ulFile = new RandomAccessFile(lockFile, "rw");
lock = ulFile.getChannel().lock();
}
} catch (IOException ex) {
LOGGER.trace("Expected error as another thread has likely locked the file", ex);
}
if (lock == null || !lock.isValid()) {
try {
LOGGER.debug(String.format("Sleeping thread %s for 5 seconds because we could not obtain the update lock.", Thread.currentThread().getName()));
Thread.sleep(5000);
} catch (InterruptedException ex) {
LOGGER.trace("ignorable error, sleep was interrupted.", ex);
}
}
} while (++ctr < 60 && (lock == null || !lock.isValid()));
if (lock == null || !lock.isValid()) {
throw new UpdateException("Unable to obtain the update lock, skipping the database update. Skippinig the database update.");
}
}
initializeExecutorServices();
cveDb = CveDB.getInstance();
dbProperties = cveDb.getDatabaseProperties();
@@ -137,12 +163,66 @@ public class NvdCveUpdater implements CachedWebDataSource {
throw new UpdateException("Unable to download the NVD CVE data.", ex);
} catch (DatabaseException ex) {
throw new UpdateException("Database Exception, unable to update the data to use the most current data.", ex);
} catch (IOException ex) {
throw new UpdateException("Database Exception", ex);
} finally {
shutdownExecutorServices();
cveDb.close();
if (lock != null) {
try {
lock.release();
} catch (IOException ex) {
LOGGER.trace("Ignorable exception", ex);
}
}
if (ulFile != null) {
try {
ulFile.close();
} catch (IOException ex) {
LOGGER.trace("Ignorable exception", ex);
}
}
if (lockFile != null) {
lockFile.delete();
}
}
}
/**
* Checks if the system is configured NOT to update.
*
* @return false if the system is configured to perform an update; otherwise
* true
*/
private boolean isUpdateConfiguredFalse() {
try {
if (!Settings.getBoolean(Settings.KEYS.UPDATE_NVDCVE_ENABLED, true)) {
return true;
}
} catch (InvalidSettingException ex) {
LOGGER.trace("invalid setting UPDATE_NVDCVE_ENABLED", ex);
}
boolean autoUpdate = true;
try {
autoUpdate = Settings.getBoolean(Settings.KEYS.AUTO_UPDATE);
} catch (InvalidSettingException ex) {
LOGGER.debug("Invalid setting for auto-update; using true.");
}
return !autoUpdate;
}
/**
* Returns the age of the file in minutes.
*
* @param file the file to calculate the age
* @return the age of the file
*/
private long getFileAge(File file) {
final Date d = new Date();
final long modified = file.lastModified();
return (d.getTime() - modified) / 1000 / 60;
}
/**
* Initialize the executor services for download and processing of the NVD
* CVE XML data.

View File

@@ -545,4 +545,20 @@
<gav regex="true">^javax\.servlet:servlet-api:.*$</gav>
<cpe>cpe:/a:sun:one_application_server</cpe>
</suppress>
<suppress base="true">
<notes><![CDATA[
False positives per issue #684.
]]></notes>
<gav regex="true">^org\.apache\.tomcat\.embed:tomcat-embed.*$</gav>
<cve>CVE-2017-6056</cve>
<cve>CVE-2016-6325</cve>
<cve>CVE-2016-5425</cve>
</suppress>
<suppress base="true">
<notes><![CDATA[
False positive per issue #691
]]></notes>
<gav regex="true">^org\.springframework\.boot:spring-boot-starter-data-jpa:.*$</gav>
<cve>CVE-2016-6652</cve>
</suppress>
</suppressions>

View File

@@ -8,7 +8,7 @@ import org.owasp.dependencycheck.utils.Settings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.util.List;
@@ -50,7 +50,7 @@ public class CentralSearchTest extends BaseTest {
// This test does generate network traffic and communicates with a host
// you may not be able to reach. Remove the @Ignore annotation if you want to
// test it anyway
@Test(expected = FileNotFoundException.class)
@Test(expected = IOException.class)
public void testMissingSha1() throws Exception {
searcher.searchSha1("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
}