renamed modules and fixed errors with various lifecycle stages

This commit is contained in:
Jeremy Long
2018-01-25 06:54:01 -05:00
parent 3736161e39
commit 62a5db6b8b
740 changed files with 40 additions and 12 deletions

View File

@@ -0,0 +1,201 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Includes methods to generate the MD5 and SHA1 checksum.
*
* @author Jeremy Long
*
*/
public final class Checksum {
/**
* Hex code characters used in getHex.
*/
private static final String HEXES = "0123456789abcdef";
/**
* The logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(Checksum.class);
/**
* Private constructor for a utility class.
*/
private Checksum() {
}
/**
* <p>
* Creates the cryptographic checksum of a given file using the specified
* algorithm.</p>
*
* @param algorithm the algorithm to use to calculate the checksum
* @param file the file to calculate the checksum for
* @return the checksum
* @throws IOException when the file does not exist
* @throws NoSuchAlgorithmException when an algorithm is specified that does
* not exist
*/
public static byte[] getChecksum(String algorithm, File file) throws NoSuchAlgorithmException, IOException {
final MessageDigest md = MessageDigest.getInstance(algorithm);
try (FileInputStream fis = new FileInputStream(file);
FileChannel ch = fis.getChannel()) {
final ByteBuffer buf = ByteBuffer.allocateDirect(8192);
int b = ch.read(buf);
while (b != -1 && b != 0) {
buf.flip();
final byte[] bytes = new byte[b];
buf.get(bytes);
md.update(bytes, 0, b);
buf.clear();
b = ch.read(buf);
}
return md.digest();
}
}
/**
* Calculates the MD5 checksum of a specified file.
*
* @param file the file to generate the MD5 checksum
* @return the hex representation of the MD5 hash
* @throws IOException when the file passed in does not exist
* @throws NoSuchAlgorithmException when the MD5 algorithm is not available
*/
public static String getMD5Checksum(File file) throws IOException, NoSuchAlgorithmException {
final byte[] b = getChecksum("MD5", file);
return getHex(b);
}
/**
* Calculates the SHA1 checksum of a specified file.
*
* @param file the file to generate the MD5 checksum
* @return the hex representation of the SHA1 hash
* @throws IOException when the file passed in does not exist
* @throws NoSuchAlgorithmException when the SHA1 algorithm is not available
*/
public static String getSHA1Checksum(File file) throws IOException, NoSuchAlgorithmException {
final byte[] b = getChecksum("SHA1", file);
return getHex(b);
}
/**
* Calculates the MD5 checksum of a specified bytes.
*
* @param algorithm the algorithm to use (md5, sha1, etc.) to calculate the
* message digest
* @param bytes the bytes to generate the MD5 checksum
* @return the hex representation of the MD5 hash
*/
public static String getChecksum(String algorithm, byte[] bytes) {
MessageDigest digest = getMessageDigest(algorithm);
final byte[] b = digest.digest(bytes);
return getHex(b);
}
/**
* Calculates the MD5 checksum of the specified text.
*
* @param text the text to generate the MD5 checksum
* @return the hex representation of the MD5
*/
public static String getMD5Checksum(String text) {
final byte[] data = stringToBytes(text);
return getChecksum("MD5", data);
}
/**
* Calculates the SHA1 checksum of the specified text.
*
* @param text the text to generate the SHA1 checksum
* @return the hex representation of the SHA1
*/
public static String getSHA1Checksum(String text) {
final byte[] data = stringToBytes(text);
return getChecksum("SHA1", data);
}
/**
* Converts the given text into bytes.
*
* @param text the text to convert
* @return the bytes
*/
private static byte[] stringToBytes(String text) {
byte[] data;
try {
data = text.getBytes(Charset.forName("UTF-8"));
} catch (UnsupportedCharsetException ex) {
data = text.getBytes(Charset.defaultCharset());
}
return data;
}
/**
* <p>
* Converts a byte array into a hex string.</p>
*
* <p>
* This method was copied from <a
* href="http://www.rgagnon.com/javadetails/java-0596.html">http://www.rgagnon.com/javadetails/java-0596.html</a></p>
*
* @param raw a byte array
* @return the hex representation of the byte array
*/
public static String getHex(byte[] raw) {
if (raw == null) {
return null;
}
final StringBuilder hex = new StringBuilder(2 * raw.length);
for (final byte b : raw) {
hex.append(HEXES.charAt((b & 0xF0) >> 4)).append(HEXES.charAt(b & 0x0F));
}
return hex.toString();
}
/**
* Returns the message digest.
*
* @param algorithm the algorithm for the message digest
* @return the message digest
*/
private static MessageDigest getMessageDigest(String algorithm) {
try {
return MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
LOGGER.error(e.getMessage());
final String msg = String.format("Failed to obtain the %s message digest.", algorithm);
throw new IllegalStateException(msg, e);
}
}
}

View File

@@ -0,0 +1,68 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.IOException;
/**
* An exception used when a download fails.
*
* @author Jeremy Long
*/
public class DownloadFailedException extends IOException {
/**
* The serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new DownloadFailedException.
*/
public DownloadFailedException() {
super();
}
/**
* Creates a new DownloadFailedException.
*
* @param msg a message for the exception.
*/
public DownloadFailedException(String msg) {
super(msg);
}
/**
* Creates a new DownloadFailedException.
*
* @param ex the cause of the download failure.
*/
public DownloadFailedException(Throwable ex) {
super(ex);
}
/**
* Creates a new DownloadFailedException.
*
* @param msg a message for the exception.
* @param ex the cause of the download failure.
*/
public DownloadFailedException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -0,0 +1,368 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.BufferedOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.security.InvalidAlgorithmParameterException;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;
import static java.lang.String.format;
/**
* A utility to download files from the Internet.
*
* @author Jeremy Long
*/
public final class Downloader {
/**
* The logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(Downloader.class);
/**
* The maximum number of redirects that will be followed when attempting to
* download a file.
*/
private static final int MAX_REDIRECT_ATTEMPTS = 5;
/**
* The default HTTP request method for query timestamp
*/
private static final String HEAD = "HEAD";
/**
* The HTTP request method which can be used by query timestamp
*/
private static final String GET = "GET";
/**
* The configured settings.
*/
private final Settings settings;
/**
* The URL connection facctory.
*/
private final URLConnectionFactory connFactory;
/**
* Constructs a new downloader object.
*
* @param settings the configured settings
*/
public Downloader(Settings settings) {
this.settings = settings;
this.connFactory = new URLConnectionFactory(settings);
}
/**
* Retrieves a file from a given URL and saves it to the outputPath.
*
* @param url the URL of the file to download
* @param outputPath the path to the save the file to
* @throws DownloadFailedException is thrown if there is an error
* downloading the file
*/
public void fetchFile(URL url, File outputPath) throws DownloadFailedException {
fetchFile(url, outputPath, true);
}
/**
* Retrieves a file from a given URL and saves it to the outputPath.
*
* @param url the URL of the file to download
* @param outputPath the path to the save the file to
* @param useProxy whether to use the configured proxy when downloading
* files
* @throws DownloadFailedException is thrown if there is an error
* downloading the file
*/
public void fetchFile(URL url, File outputPath, boolean useProxy) throws DownloadFailedException {
if ("file".equalsIgnoreCase(url.getProtocol())) {
File file;
try {
file = new File(url.toURI());
} catch (URISyntaxException ex) {
final String msg = format("Download failed, unable to locate '%s'", url.toString());
throw new DownloadFailedException(msg);
}
if (file.exists()) {
try {
org.apache.commons.io.FileUtils.copyFile(file, outputPath);
} catch (IOException ex) {
final String msg = format("Download failed, unable to copy '%s' to '%s'", url.toString(), outputPath.getAbsolutePath());
throw new DownloadFailedException(msg, ex);
}
} else {
final String msg = format("Download failed, file ('%s') does not exist", url.toString());
throw new DownloadFailedException(msg);
}
} else {
HttpURLConnection conn = null;
try {
LOGGER.debug("Attempting download of {}", url.toString());
conn = connFactory.createHttpURLConnection(url, useProxy);
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
conn.connect();
int status = conn.getResponseCode();
int redirectCount = 0;
while ((status == HttpURLConnection.HTTP_MOVED_TEMP
|| status == HttpURLConnection.HTTP_MOVED_PERM
|| status == HttpURLConnection.HTTP_SEE_OTHER)
&& MAX_REDIRECT_ATTEMPTS > redirectCount++) {
final String location = conn.getHeaderField("Location");
try {
conn.disconnect();
} finally {
conn = null;
}
LOGGER.debug("Download is being redirected from {} to {}", url.toString(), location);
conn = connFactory.createHttpURLConnection(new URL(location), useProxy);
conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
conn.connect();
status = conn.getResponseCode();
}
if (status != 200) {
try {
conn.disconnect();
} finally {
conn = null;
}
final String msg = format("Error downloading file %s; received response code %s.", url.toString(), status);
throw new DownloadFailedException(msg);
}
} catch (IOException ex) {
try {
if (conn != null) {
conn.disconnect();
}
} finally {
conn = null;
}
if ("Connection reset".equalsIgnoreCase(ex.getMessage())) {
final String msg = format("TLS Connection Reset%nPlease see "
+ "http://jeremylong.github.io/DependencyCheck/data/tlsfailure.html "
+ "for more information regarding how to resolve the issue.");
LOGGER.error(msg);
throw new DownloadFailedException(msg, ex);
}
final String msg = format("Error downloading file %s; unable to connect.", url.toString());
throw new DownloadFailedException(msg, ex);
}
final String encoding = conn.getContentEncoding();
InputStream reader = null;
try (OutputStream out = new FileOutputStream(outputPath);
BufferedOutputStream writer = new BufferedOutputStream(out)) {
if (encoding != null && "gzip".equalsIgnoreCase(encoding)) {
reader = new GZIPInputStream(conn.getInputStream());
} else if (encoding != null && "deflate".equalsIgnoreCase(encoding)) {
reader = new InflaterInputStream(conn.getInputStream());
} else {
reader = conn.getInputStream();
}
final byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = reader.read(buffer)) > 0) {
writer.write(buffer, 0, bytesRead);
}
LOGGER.debug("Download of {} complete", url.toString());
} catch (IOException ex) {
checkForCommonExceptionTypes(ex);
final String msg = format("Error saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n",
url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding);
throw new DownloadFailedException(msg, ex);
} catch (Exception ex) {
final String msg = format("Unexpected exception saving '%s' to file '%s'%nConnection Timeout: %d%nEncoding: %s%n",
url.toString(), outputPath.getAbsolutePath(), conn.getConnectTimeout(), encoding);
throw new DownloadFailedException(msg, ex);
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException ex) {
LOGGER.trace("Error closing the reader in Downloader.", ex);
}
}
try {
conn.disconnect();
} finally {
conn = null;
}
}
}
}
/**
* Makes an HTTP Head request to retrieve the last modified date of the
* given URL. If the file:// protocol is specified, then the lastTimestamp
* of the file is returned.
*
* @param url the URL to retrieve the timestamp from
* @return an epoch timestamp
* @throws DownloadFailedException is thrown if an exception occurs making
* the HTTP request
*/
public long getLastModified(URL url) throws DownloadFailedException {
return getLastModified(url, false);
}
/**
* Makes an HTTP Head request to retrieve the last modified date of the
* given URL. If the file:// protocol is specified, then the lastTimestamp
* of the file is returned.
*
* @param url the URL to retrieve the timestamp from
* @param isRetry indicates if this is a retry - to prevent endless loop and
* stack overflow
* @return an epoch timestamp
* @throws DownloadFailedException is thrown if an exception occurs making
* the HTTP request
*/
private long getLastModified(URL url, boolean isRetry) throws DownloadFailedException {
long timestamp = 0;
//TODO add the FTP protocol?
if ("file".equalsIgnoreCase(url.getProtocol())) {
File lastModifiedFile;
try {
lastModifiedFile = new File(url.toURI());
} catch (URISyntaxException ex) {
final String msg = format("Unable to locate '%s'", url.toString());
throw new DownloadFailedException(msg, ex);
}
timestamp = lastModifiedFile.lastModified();
} else {
final String httpMethod = determineHttpMethod();
HttpURLConnection conn = null;
try {
conn = connFactory.createHttpURLConnection(url);
conn.setRequestMethod(httpMethod);
conn.connect();
final int t = conn.getResponseCode();
if (t >= 200 && t < 300) {
timestamp = conn.getLastModified();
} else {
throw new DownloadFailedException(format("%s request returned a non-200 status code", httpMethod));
}
} catch (URLConnectionFailureException ex) {
throw new DownloadFailedException(format("Error creating URL Connection for HTTP %s request.", httpMethod), ex);
} catch (IOException ex) {
checkForCommonExceptionTypes(ex);
LOGGER.error("IO Exception: " + ex.getMessage());
LOGGER.debug("Exception details", ex);
if (ex.getCause() != null) {
LOGGER.debug("IO Exception cause: " + ex.getCause().getMessage(), ex.getCause());
}
try {
//retry
if (!isRetry && settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP)) {
settings.setBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, false);
return getLastModified(url, true);
}
} catch (InvalidSettingException ex1) {
LOGGER.debug("invalid setting?", ex1);
}
throw new DownloadFailedException(format("Error making HTTP %s request.", httpMethod), ex);
} finally {
if (conn != null) {
try {
conn.disconnect();
} finally {
conn = null;
}
}
}
}
return timestamp;
}
/**
* Analyzes the IOException, logs the appropriate information for debugging
* purposes, and then throws a DownloadFailedException that wraps the IO
* Exception for common IO Exceptions. This is to provide additional details
* to assist in resolution of the exception.
*
* @param ex the original exception
* @throws DownloadFailedException a wrapper exception that contains the
* original exception as the cause
*/
protected synchronized void checkForCommonExceptionTypes(IOException ex) throws DownloadFailedException {
Throwable cause = ex;
while (cause != null) {
if (cause instanceof java.net.UnknownHostException) {
final String msg = format("Unable to resolve domain '%s'", cause.getMessage());
LOGGER.error(msg);
throw new DownloadFailedException(msg);
}
if (cause instanceof InvalidAlgorithmParameterException) {
final String keystore = System.getProperty("javax.net.ssl.keyStore");
final String version = System.getProperty("java.version");
final String vendor = System.getProperty("java.vendor");
LOGGER.info("Error making HTTPS request - InvalidAlgorithmParameterException");
LOGGER.info("There appears to be an issue with the installation of Java and the cacerts."
+ "See closed issue #177 here: https://github.com/jeremylong/DependencyCheck/issues/177");
LOGGER.info("Java Info:\njavax.net.ssl.keyStore='{}'\njava.version='{}'\njava.vendor='{}'",
keystore, version, vendor);
throw new DownloadFailedException("Error making HTTPS request. Please see the log for more details.");
}
cause = cause.getCause();
}
}
/**
* Returns the HEAD or GET HTTP method. HEAD is the default.
*
* @return the HTTP method to use
*/
private String determineHttpMethod() {
return isQuickQuery() ? HEAD : GET;
}
/**
* Determines if the HTTP method GET or HEAD should be used to check the
* timestamp on external resources.
*
* @return true if configured to use HEAD requests
*/
private boolean isQuickQuery() {
boolean quickQuery;
try {
quickQuery = settings.getBoolean(Settings.KEYS.DOWNLOADER_QUICK_QUERY_TIMESTAMP, true);
} catch (InvalidSettingException e) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Invalid settings : {}", e.getMessage(), e);
}
quickQuery = true;
}
return quickQuery;
}
}

View File

@@ -0,0 +1,72 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2016 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidClassException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.annotation.concurrent.NotThreadSafe;
/**
* An ObjectInputStream that will only deserialize expected classes.
*
* @author Jeremy Long
*/
@NotThreadSafe
public class ExpectedObjectInputStream extends ObjectInputStream {
/**
* The list of fully qualified class names that are able to be deserialized.
*/
private final List<String> expected = new ArrayList<>();
/**
* Constructs a new ExpectedOjectInputStream that can be used to securely deserialize an object by restricting the classes
* that can deserialized to a known set of expected classes.
*
* @param inputStream the input stream that contains the object to deserialize
* @param expected the fully qualified class names of the classes that can be deserialized
* @throws IOException thrown if there is an error reading from the stream
*/
public ExpectedObjectInputStream(InputStream inputStream, String... expected) throws IOException {
super(inputStream);
this.expected.addAll(Arrays.asList(expected));
}
/**
* Only deserialize instances of expected classes by validating the class name prior to deserialization.
*
* @param desc the class from the object stream to validate
* @return the resolved class
* @throws java.io.IOException thrown if the class being read is not one of the expected classes or if there is an error
* reading from the stream
* @throws java.lang.ClassNotFoundException thrown if there is an error finding the class to deserialize
*/
@Override
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
if (!this.expected.contains(desc.getName())) {
throw new InvalidClassException("Unexpected deserialization ", desc.getName());
}
return super.resolveClass(desc);
}
}

View File

@@ -0,0 +1,68 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2013 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.IOException;
/**
* An exception used when a file is unable to be un-zipped.
*
* @author Jeremy Long
*/
public class ExtractionException extends IOException {
/**
* The serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new ExtractionException.
*/
public ExtractionException() {
super();
}
/**
* Creates a new ExtractionException.
*
* @param msg a message for the exception.
*/
public ExtractionException(String msg) {
super(msg);
}
/**
* Creates a new ExtractionException.
*
* @param ex the cause of the download failure.
*/
public ExtractionException(Throwable ex) {
super(ex);
}
/**
* Creates a new ExtractionException.
*
* @param msg a message for the exception.
* @param ex the cause of the download failure.
*/
public ExtractionException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -0,0 +1,146 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.Closeable;
import org.apache.commons.io.FilenameUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.UUID;
import org.apache.commons.lang3.SystemUtils;
/**
* A collection of utilities for processing information about files.
*
* @author Jeremy Long
*/
public final class FileUtils {
/**
* The logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(FileUtils.class);
/**
* Bit bucket for non-Windows systems
*/
private static final String BIT_BUCKET_UNIX = "/dev/null";
/**
* Bit bucket for Windows systems (yes, only one 'L')
*/
private static final String BIT_BUCKET_WIN = "NUL";
/**
* Private constructor for a utility class.
*/
private FileUtils() {
}
/**
* Returns the (lowercase) file extension for a specified file.
*
* @param fileName the file name to retrieve the file extension from.
* @return the file extension.
*/
public static String getFileExtension(String fileName) {
final String fileExt = FilenameUtils.getExtension(fileName);
return null == fileExt || fileExt.isEmpty() ? null : fileExt.toLowerCase();
}
/**
* Deletes a file. If the File is a directory it will recursively delete the
* contents.
*
* @param file the File to delete
* @return true if the file was deleted successfully, otherwise false
*/
public static boolean delete(File file) {
final boolean success = org.apache.commons.io.FileUtils.deleteQuietly(file);
if (!success) {
LOGGER.debug("Failed to delete file: {}; attempting to delete on exit.", file.getPath());
file.deleteOnExit();
}
return success;
}
/**
* Creates a unique temporary directory in the given directory.
*
* @param base the base directory to create a temporary directory within
* @return the temporary directory
* @throws IOException thrown when a directory cannot be created within the
* base directory
*/
public static File createTempDirectory(File base) throws IOException {
final File tempDir = new File(base, "dctemp" + UUID.randomUUID().toString());
if (tempDir.exists()) {
return createTempDirectory(base);
}
if (!tempDir.mkdirs()) {
throw new IOException("Could not create temp directory `" + tempDir.getAbsolutePath() + "`");
}
LOGGER.debug("Temporary directory is `{}`", tempDir.getAbsolutePath());
return tempDir;
}
/**
* Return the bit bucket for the OS. '/dev/null' for Unix and 'NUL' for
* Windows
*
* @return a String containing the bit bucket
*/
public static String getBitBucket() {
if (SystemUtils.IS_OS_WINDOWS) {
return BIT_BUCKET_WIN;
} else {
return BIT_BUCKET_UNIX;
}
}
/**
* Close the given {@link Closeable} instance, ignoring nulls, and logging
* any thrown {@link IOException}.
*
* @param closeable to be closed
*/
public static void close(Closeable closeable) {
if (null != closeable) {
try {
closeable.close();
} catch (IOException ex) {
LOGGER.trace("", ex);
}
}
}
/**
* Gets the {@link InputStream} for this resource.
*
* @param resource path
* @return the input stream for the given resource
*/
public static InputStream getResourceAsStream(String resource) {
return FileUtils.class.getClassLoader() != null
? FileUtils.class.getClassLoader().getResourceAsStream(resource)
: ClassLoader.getSystemResourceAsStream(resource);
}
}

View File

@@ -0,0 +1,68 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.IOException;
/**
* An exception used when an error occurs reading a setting.
*
* @author Jeremy Long
*/
public class InvalidSettingException extends IOException {
/**
* The serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new InvalidSettingException.
*/
public InvalidSettingException() {
super();
}
/**
* Creates a new InvalidSettingException.
*
* @param msg a message for the exception.
*/
public InvalidSettingException(String msg) {
super(msg);
}
/**
* Creates a new InvalidSettingException.
*
* @param ex the cause of the setting exception.
*/
public InvalidSettingException(Throwable ex) {
super(ex);
}
/**
* Creates a new InvalidSettingException.
*
* @param msg a message for the exception.
* @param ex the cause of the setting exception.
*/
public InvalidSettingException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -0,0 +1,307 @@
package org.owasp.dependencycheck.utils;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class is used to enable additional ciphers used by the SSL Socket. This
* is specifically because the NVD stopped supporting TLS 1.0 and Java 6 and 7
* clients by default were unable to connect to download the NVD data feeds.
*
* The following code was copied from
* http://stackoverflow.com/questions/1037590/which-cipher-suites-to-enable-for-ssl-socket/23365536#23365536
*
* @author <a href="http://stackoverflow.com/users/608639/jww">jww</a>
*/
public class SSLSocketFactoryEx extends SSLSocketFactory {
/**
* The Logger for use throughout the class.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(SSLSocketFactoryEx.class);
/**
* The SSL context.
*/
private SSLContext sslCtxt;
/**
* The protocols.
*/
private String[] protocols;
/**
* The configured settings.
*/
private final Settings settings;
/**
* Constructs a new SSLSocketFactory.
*
* @param settings reference to the configured settings
* @throws NoSuchAlgorithmException thrown when an algorithm is not
* supported
* @throws KeyManagementException thrown if initialization fails
*/
public SSLSocketFactoryEx(Settings settings) throws NoSuchAlgorithmException, KeyManagementException {
this.settings = settings;
initSSLSocketFactoryEx(null, null, null);
}
/**
* Constructs a new SSLSocketFactory.
*
* @param km the key manager
* @param tm the trust manager
* @param random secure random
* @param settings reference to the configured settings
* @throws NoSuchAlgorithmException thrown when an algorithm is not
* supported
* @throws KeyManagementException thrown if initialization fails
*/
public SSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random, Settings settings)
throws NoSuchAlgorithmException, KeyManagementException {
this.settings = settings;
initSSLSocketFactoryEx(km, tm, random);
}
/**
* Constructs a new SSLSocketFactory.
*
* @param ctx the SSL context
* @param settings reference to the configured settings
* @throws NoSuchAlgorithmException thrown when an algorithm is not
* supported
* @throws KeyManagementException thrown if initialization fails
*/
public SSLSocketFactoryEx(SSLContext ctx, Settings settings) throws NoSuchAlgorithmException, KeyManagementException {
this.settings = settings;
initSSLSocketFactoryEx(ctx);
}
/**
* Returns the default cipher suites.
*
* @return the default cipher suites
*/
@Override
public String[] getDefaultCipherSuites() {
return sslCtxt.getSocketFactory().getDefaultCipherSuites();
}
/**
* Returns the supported cipher suites.
*
* @return the supported cipher suites
*/
@Override
public String[] getSupportedCipherSuites() {
return sslCtxt.getSocketFactory().getSupportedCipherSuites();
}
/**
* Returns the default protocols.
*
* @return the default protocols
*/
public String[] getDefaultProtocols() {
return Arrays.copyOf(protocols, protocols.length);
}
/**
* Returns the supported protocols.
*
* @return the supported protocols
*/
public String[] getSupportedProtocols() {
return Arrays.copyOf(protocols, protocols.length);
}
/**
* Creates an SSL Socket.
*
* @param s the base socket
* @param host the host
* @param port the port
* @param autoClose if the socket should auto-close
* @return the SSL Socket
* @throws IOException thrown if the creation fails
*/
@Override
public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {
final SSLSocketFactory factory = sslCtxt.getSocketFactory();
final SSLSocket ss = (SSLSocket) factory.createSocket(s, host, port, autoClose);
ss.setEnabledProtocols(protocols);
return ss;
}
/**
* Creates a new SSL Socket.
*
* @param address the address to connect to
* @param port the port number
* @param localAddress the local address
* @param localPort the local port
* @return the SSL Socket
* @throws IOException thrown if the creation fails
*/
@Override
public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
final SSLSocketFactory factory = sslCtxt.getSocketFactory();
final SSLSocket ss = (SSLSocket) factory.createSocket(address, port, localAddress, localPort);
ss.setEnabledProtocols(protocols);
return ss;
}
/**
* Creates a new SSL Socket.
*
* @param host the host to connect to
* @param port the port to connect to
* @param localHost the local host
* @param localPort the local port
* @return the SSL Socket
* @throws IOException thrown if the creation fails
*/
@Override
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
final SSLSocketFactory factory = sslCtxt.getSocketFactory();
final SSLSocket ss = (SSLSocket) factory.createSocket(host, port, localHost, localPort);
ss.setEnabledProtocols(protocols);
return ss;
}
/**
* Creates a new SSL Socket.
*
* @param host the host to connect to
* @param port the port to connect to
* @return the SSL Socket
* @throws IOException thrown if the creation fails
*/
@Override
public Socket createSocket(InetAddress host, int port) throws IOException {
final SSLSocketFactory factory = sslCtxt.getSocketFactory();
final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
ss.setEnabledProtocols(protocols);
return ss;
}
/**
* Creates a new SSL Socket.
*
* @param host the host to connect to
* @param port the port to connect to
* @return the SSL Socket
* @throws IOException thrown if the creation fails
*/
@Override
public Socket createSocket(String host, int port) throws IOException {
final SSLSocketFactory factory = sslCtxt.getSocketFactory();
final SSLSocket ss = (SSLSocket) factory.createSocket(host, port);
ss.setEnabledProtocols(protocols);
return ss;
}
/**
* Initializes the SSL Socket Factory Extension.
*
* @param km the key managers
* @param tm the trust managers
* @param random the secure random number generator
* @throws NoSuchAlgorithmException thrown when an algorithm is not
* supported
* @throws KeyManagementException thrown if initialization fails
*/
private void initSSLSocketFactoryEx(KeyManager[] km, TrustManager[] tm, SecureRandom random)
throws NoSuchAlgorithmException, KeyManagementException {
sslCtxt = SSLContext.getInstance("TLS");
sslCtxt.init(km, tm, random);
protocols = getProtocolList();
}
/**
* Initializes the SSL Socket Factory Extension.
*
* @param ctx the SSL context
* @throws NoSuchAlgorithmException thrown when an algorithm is not
* supported
* @throws KeyManagementException thrown if initialization fails
*/
private void initSSLSocketFactoryEx(SSLContext ctx)
throws NoSuchAlgorithmException, KeyManagementException {
sslCtxt = ctx;
protocols = getProtocolList();
}
/**
* Returns the protocol list.
*
* @return the protocol list
*/
protected String[] getProtocolList() {
SSLSocket socket = null;
String[] availableProtocols = null;
final String[] preferredProtocols = settings.getString(
Settings.KEYS.DOWNLOADER_TLS_PROTOCOL_LIST,
"TLSv1,TLSv1.1,TLSv1.2,TLSv1.3")
.split(",");
try {
final SSLSocketFactory factory = sslCtxt.getSocketFactory();
socket = (SSLSocket) factory.createSocket();
availableProtocols = socket.getSupportedProtocols();
Arrays.sort(availableProtocols);
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Available Protocols:");
for (String p : availableProtocols) {
LOGGER.debug(p);
}
}
} catch (Exception ex) {
LOGGER.debug("Error getting protocol list, using TLSv1", ex);
return new String[]{"TLSv1"};
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException ex) {
LOGGER.trace("Error closing socket", ex);
}
}
}
final List<String> aa = new ArrayList<>();
for (String preferredProtocol : preferredProtocols) {
final int idx = Arrays.binarySearch(availableProtocols, preferredProtocol);
if (idx >= 0) {
aa.add(preferredProtocol);
}
}
return aa.toArray(new String[0]);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,220 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.net.Authenticator;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.SocketAddress;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import javax.net.ssl.HttpsURLConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* A URLConnection Factory to create new connections. This encapsulates several
* configuration checks to ensure that the connection uses the correct proxy
* settings.
*
* @author Jeremy Long
*/
public final class URLConnectionFactory {
/**
* The logger.
*/
private static final Logger LOGGER = LoggerFactory.getLogger(URLConnectionFactory.class);
/**
* The configured settings.
*/
private final Settings settings;
/**
* Private constructor for this factory.
*
* @param settings reference to the configured settings
*/
public URLConnectionFactory(Settings settings) {
this.settings = settings;
}
/**
* Utility method to create an HttpURLConnection. If the application is
* configured to use a proxy this method will retrieve the proxy settings
* and use them when setting up the connection.
*
* @param url the url to connect to
* @return an HttpURLConnection
* @throws URLConnectionFailureException thrown if there is an exception
*/
@SuppressFBWarnings(value = "RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE", justification = "Just being extra safe")
public HttpURLConnection createHttpURLConnection(URL url) throws URLConnectionFailureException {
HttpURLConnection conn = null;
final String proxyHost = settings.getString(Settings.KEYS.PROXY_SERVER);
try {
if (proxyHost != null && !matchNonProxy(url)) {
final int proxyPort = settings.getInt(Settings.KEYS.PROXY_PORT);
final SocketAddress address = new InetSocketAddress(proxyHost, proxyPort);
final String username = settings.getString(Settings.KEYS.PROXY_USERNAME);
final String password = settings.getString(Settings.KEYS.PROXY_PASSWORD);
if (username != null && password != null) {
final Authenticator auth = new Authenticator() {
@Override
public PasswordAuthentication getPasswordAuthentication() {
if (proxyHost.equals(getRequestingHost()) || getRequestorType().equals(Authenticator.RequestorType.PROXY)) {
LOGGER.debug("Using the configured proxy username and password");
try {
if (settings.getBoolean(Settings.KEYS.PROXY_DISABLE_SCHEMAS, true)) {
System.setProperty("jdk.http.auth.tunneling.disabledSchemes", "");
}
} catch (InvalidSettingException ex) {
LOGGER.trace("This exception can be ignored", ex);
}
return new PasswordAuthentication(username, password.toCharArray());
}
return super.getPasswordAuthentication();
}
};
Authenticator.setDefault(auth);
}
final Proxy proxy = new Proxy(Proxy.Type.HTTP, address);
conn = (HttpURLConnection) url.openConnection(proxy);
} else {
conn = (HttpURLConnection) url.openConnection();
}
final int connectionTimeout = settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000);
conn.setConnectTimeout(connectionTimeout);
conn.setInstanceFollowRedirects(true);
} catch (IOException ex) {
if (conn != null) {
try {
conn.disconnect();
} finally {
conn = null;
}
}
throw new URLConnectionFailureException("Error getting connection.", ex);
}
configureTLS(url, conn);
return conn;
}
/**
* Check if hostname matches nonProxy settings
*
* @param url the url to connect to
* @return matching result. true: match nonProxy
*/
private boolean matchNonProxy(final URL url) {
final String host = url.getHost();
// code partially from org.apache.maven.plugins.site.AbstractDeployMojo#getProxyInfo
final String nonProxyHosts = settings.getString(Settings.KEYS.PROXY_NON_PROXY_HOSTS);
if (null != nonProxyHosts) {
final String[] nonProxies = nonProxyHosts.split("(,)|(;)|(\\|)");
for (final String nonProxyHost : nonProxies) {
//if ( StringUtils.contains( nonProxyHost, "*" ) )
if (null != nonProxyHost && nonProxyHost.contains("*")) {
// Handle wildcard at the end, beginning or middle of the nonProxyHost
final int pos = nonProxyHost.indexOf('*');
final String nonProxyHostPrefix = nonProxyHost.substring(0, pos);
final String nonProxyHostSuffix = nonProxyHost.substring(pos + 1);
// prefix*
if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && StringUtils.isEmpty(nonProxyHostSuffix)) {
return true;
}
// *suffix
if (StringUtils.isEmpty(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix) && host.endsWith(nonProxyHostSuffix)) {
return true;
}
// prefix*suffix
if (!StringUtils.isEmpty(nonProxyHostPrefix) && host.startsWith(nonProxyHostPrefix) && !StringUtils.isEmpty(nonProxyHostSuffix)
&& host.endsWith(nonProxyHostSuffix)) {
return true;
}
} else if (host.equals(nonProxyHost)) {
return true;
}
}
}
return false;
}
/**
* Utility method to create an HttpURLConnection. The use of a proxy here is
* optional as there may be cases where a proxy is configured but we don't
* want to use it (for example, if there's an internal repository
* configured)
*
* @param url the URL to connect to
* @param proxy whether to use the proxy (if configured)
* @return a newly constructed HttpURLConnection
* @throws URLConnectionFailureException thrown if there is an exception
*/
public HttpURLConnection createHttpURLConnection(URL url, boolean proxy) throws URLConnectionFailureException {
if (proxy) {
return createHttpURLConnection(url);
}
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
final int timeout = settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 10000);
conn.setConnectTimeout(timeout);
conn.setInstanceFollowRedirects(true);
} catch (IOException ioe) {
throw new URLConnectionFailureException("Error getting connection.", ioe);
}
configureTLS(url, conn);
return conn;
}
/**
* If the protocol is HTTPS, this will configure the cipher suites so that
* connections can be made to the NVD, and others, using older versions of
* Java.
*
* @param url the URL
* @param conn the connection
*/
private void configureTLS(URL url, URLConnection conn) {
if ("https".equals(url.getProtocol())) {
try {
final HttpsURLConnection secCon = (HttpsURLConnection) conn;
final SSLSocketFactoryEx factory = new SSLSocketFactoryEx(settings);
secCon.setSSLSocketFactory(factory);
} catch (NoSuchAlgorithmException ex) {
LOGGER.debug("Unsupported algorithm in SSLSocketFactoryEx", ex);
} catch (KeyManagementException ex) {
LOGGER.debug("Key management exception in SSLSocketFactoryEx", ex);
}
}
}
}

View File

@@ -0,0 +1,68 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2014 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.IOException;
/**
* An exception used when the creation of an URLConnection fails.
*
* @author Jeremy Long
*/
public class URLConnectionFailureException extends IOException {
/**
* The serial version UID.
*/
private static final long serialVersionUID = 1L;
/**
* Creates a new URLConnectionFailureException.
*/
public URLConnectionFailureException() {
super();
}
/**
* Creates a new URLConnectionFailureException.
*
* @param msg a message for the exception.
*/
public URLConnectionFailureException(String msg) {
super(msg);
}
/**
* Creates a new URLConnectionFailureException.
*
* @param ex the cause of the download failure.
*/
public URLConnectionFailureException(Throwable ex) {
super(ex);
}
/**
* Creates a new URLConnectionFailureException.
*
* @param msg a message for the exception.
* @param ex the cause of the download failure.
*/
public URLConnectionFailureException(String msg, Throwable ex) {
super(msg, ex);
}
}

View File

@@ -0,0 +1,180 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2016 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.InputStream;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
import org.xml.sax.SAXNotRecognizedException;
import org.xml.sax.SAXNotSupportedException;
import org.xml.sax.SAXParseException;
/**
* Collection of XML related code.
*
* @author Jeremy Long
*/
public final class XmlUtils {
/**
* JAXP Schema Language. Source:
* http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
*/
public static final String JAXP_SCHEMA_LANGUAGE = "http://java.sun.com/xml/jaxp/properties/schemaLanguage";
/**
* W3C XML Schema. Source:
* http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
*/
public static final String W3C_XML_SCHEMA = "http://www.w3.org/2001/XMLSchema";
/**
* JAXP Schema Source. Source:
* http://docs.oracle.com/javase/tutorial/jaxp/sax/validation.html
*/
public static final String JAXP_SCHEMA_SOURCE = "http://java.sun.com/xml/jaxp/properties/schemaSource";
/**
* Private constructor for a utility class.
*/
private XmlUtils() {
}
/**
* Constructs a validating secure SAX Parser.
*
* @param schemaStream One or more inputStreams with the schema(s) that the
* parser should be able to validate the XML against, one InputStream per
* schema
* @return a SAX Parser
* @throws ParserConfigurationException is thrown if there is a parser
* configuration exception
* @throws SAXNotRecognizedException thrown if there is an unrecognized
* feature
* @throws SAXNotSupportedException thrown if there is a non-supported
* feature
* @throws SAXException is thrown if there is a SAXException
*/
public static SAXParser buildSecureSaxParser(InputStream... schemaStream) throws ParserConfigurationException,
SAXNotRecognizedException, SAXNotSupportedException, SAXException {
final SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
factory.setValidating(true);
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
//setting the following unfortunately breaks reading the old suppression files (version 1).
//factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
final SAXParser saxParser = factory.newSAXParser();
saxParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
saxParser.setProperty(JAXP_SCHEMA_SOURCE, schemaStream);
return saxParser;
}
/**
* Converts an attribute value representing an xsd:boolean value to a
* boolean using the rules as stated in the XML specification.
*
* @param lexicalXSDBoolean The string-value of the boolean
* @return the boolean value represented by {@code lexicalXSDBoolean}
* @throws IllegalArgumentException When {@code lexicalXSDBoolean} does fit
* the lexical space of the XSD boolean datatype
*/
public static boolean parseBoolean(String lexicalXSDBoolean) {
final boolean result;
switch (lexicalXSDBoolean) {
case "true":
case "1":
result = true;
break;
case "false":
case "0":
result = false;
break;
default:
throw new IllegalArgumentException("'" + lexicalXSDBoolean + "' is not a valid xs:boolean value");
}
return result;
}
/**
* Constructs a secure SAX Parser.
*
* @return a SAX Parser
* @throws ParserConfigurationException thrown if there is a parser
* configuration exception
* @throws SAXNotRecognizedException thrown if there is an unrecognized
* feature
* @throws SAXNotSupportedException thrown if there is a non-supported
* feature
* @throws SAXException is thrown if there is a SAXException
*/
public static SAXParser buildSecureSaxParser() throws ParserConfigurationException,
SAXNotRecognizedException, SAXNotSupportedException, SAXException {
final SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
return factory.newSAXParser();
}
/**
* Constructs a new document builder with security features enabled.
*
* @return a new document builder
* @throws ParserConfigurationException thrown if there is a parser
* configuration exception
*/
public static DocumentBuilder buildSecureDocumentBuilder() throws ParserConfigurationException {
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
return factory.newDocumentBuilder();
}
/**
* Builds a prettier exception message.
*
* @param ex the SAXParseException
* @return an easier to read exception message
*/
public static String getPrettyParseExceptionInfo(SAXParseException ex) {
final StringBuilder sb = new StringBuilder();
if (ex.getSystemId() != null) {
sb.append("systemId=").append(ex.getSystemId()).append(", ");
}
if (ex.getPublicId() != null) {
sb.append("publicId=").append(ex.getPublicId()).append(", ");
}
if (ex.getLineNumber() > 0) {
sb.append("Line=").append(ex.getLineNumber());
}
if (ex.getColumnNumber() > 0) {
sb.append(", Column=").append(ex.getColumnNumber());
}
sb.append(": ").append(ex.getMessage());
return sb.toString();
}
}

View File

@@ -0,0 +1,4 @@
/**
* Includes various utility classes such as a Settings wrapper, utilities to make URL Connections, etc.
*/
package org.owasp.dependencycheck.utils;

View File

@@ -0,0 +1,4 @@
About
=====
OWASP dependency-check-utils is a collection of common utility classes used within dependency-check
that might be useful in other projects.

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 11 KiB

32
utils/src/site/site.xml Normal file
View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
This file is part of dependency-check-ant.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Copyright (c) 2014 Jeremy Long. All Rights Reserved.
-->
<project name="dependency-check-utils">
<bannerLeft>
<name>OWASP dependency-check-utils</name>
<alt>OWASP dependency-check-utils</alt>
<src>./images/dc-utils.svg</src>
</bannerLeft>
<body>
<breadcrumbs>
<item name="dependency-check" href="../index.html"/>
</breadcrumbs>
<menu ref="Project Documentation" />
<menu ref="reports" />
</body>
</project>

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2014 OWASP.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.owasp.dependencycheck.utils;
import org.junit.After;
import org.junit.Before;
/**
*
* @author Jeremy Long
*/
public class BaseTest {
/**
* The configured settings.
*/
private Settings settings;
/**
* Initialize the {@link Settings}.
*/
@Before
public void setUp() {
settings = new Settings();
}
/**
* Clean the {@link Settings}.
*/
@After
public void tearDown() {
settings.cleanup(true);
}
/**
* Returns the settings for the test cases.
*
* @return
*/
protected Settings getSettings() {
return settings;
}
}

View File

@@ -0,0 +1,196 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.File;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import org.junit.After;
import org.junit.AfterClass;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
/**
*
* @author Jeremy Long
*/
public class ChecksumTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
/**
* Test of getChecksum method, of class Checksum.
*
* @throws Exception thrown when an exception occurs.
*/
@Test
public void testGetChecksum() throws Exception {
String algorithm = "MD5";
File file = new File(this.getClass().getClassLoader().getResource("checkSumTest.file").toURI().getPath());
byte[] expResult = {-16, -111, 92, 95, 70, -72, -49, -94, -125, -27, -83, 103, -96, -101, 55, -109};
byte[] result = Checksum.getChecksum(algorithm, file);
assertArrayEquals(expResult, result);
}
/**
* Test of getChecksum method, of class Checksum. This checks that an exception is thrown when an invalid path is specified.
*
* @throws Exception is thrown when an exception occurs.
*/
@Test
public void testGetChecksum_FileNotFound() throws Exception {
String algorithm = "MD5";
File file = new File("not a valid file");
expectedException.expect(IOException.class);
Checksum.getChecksum(algorithm, file);
fail("exception should be thrown");
}
/**
* Test of getChecksum method, of class Checksum. This checks that an exception is thrown when an invalid algorithm is
* specified.
*
* @throws Exception is thrown when an exception occurs.
*/
@Test
public void testGetChecksum_NoSuchAlgorithm() throws Exception {
String algorithm = "some unknown algorithm";
File file = new File(this.getClass().getClassLoader().getResource("checkSumTest.file").getPath());
expectedException.expect(NoSuchAlgorithmException.class);
Checksum.getChecksum(algorithm, file);
}
/**
* Test of getMD5Checksum method, of class Checksum.
*
* @throws Exception is thrown when an exception occurs.
*/
@Test
public void testGetMD5Checksum() throws Exception {
File file = new File(this.getClass().getClassLoader().getResource("checkSumTest.file").toURI().getPath());
//String expResult = "F0915C5F46B8CFA283E5AD67A09B3793";
String expResult = "f0915c5f46b8cfa283e5ad67a09b3793";
String result = Checksum.getMD5Checksum(file);
assertEquals(expResult, result);
}
/**
* Test of getSHA1Checksum method, of class Checksum.
*
* @throws Exception is thrown when an exception occurs.
*/
@Test
public void testGetSHA1Checksum() throws Exception {
File file = new File(this.getClass().getClassLoader().getResource("checkSumTest.file").toURI().getPath());
//String expResult = "B8A9FF28B21BCB1D0B50E24A5243D8B51766851A";
String expResult = "b8a9ff28b21bcb1d0b50e24a5243d8b51766851a";
String result = Checksum.getSHA1Checksum(file);
assertEquals(expResult, result);
}
/**
* Test of getHex method, of class Checksum.
*/
@Test
public void testGetHex() {
byte[] raw = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
//String expResult = "000102030405060708090A0B0C0D0E0F10";
String expResult = "000102030405060708090a0b0c0d0e0f10";
String result = Checksum.getHex(raw);
assertEquals(expResult, result);
}
/**
* Test of getChecksum method, of class Checksum.
*/
@Test
public void testGetChecksum_String_File() throws Exception {
String algorithm = "MD5";
File file = new File(this.getClass().getClassLoader().getResource("checkSumTest.file").toURI().getPath());
byte[] expResult = {-16, -111, 92, 95, 70, -72, -49, -94, -125, -27, -83, 103, -96, -101, 55, -109};
byte[] result = Checksum.getChecksum(algorithm, file);
assertArrayEquals(expResult, result);
}
/**
* Test of getMD5Checksum method, of class Checksum.
*/
@Test
public void testGetMD5Checksum_File() throws Exception {
File file = new File(this.getClass().getClassLoader().getResource("checkSumTest.file").toURI().getPath());
String expResult = "f0915c5f46b8cfa283e5ad67a09b3793";
String result = Checksum.getMD5Checksum(file);
assertEquals(expResult, result);
}
/**
* Test of getSHA1Checksum method, of class Checksum.
*/
@Test
public void testGetSHA1Checksum_File() throws Exception {
File file = new File(this.getClass().getClassLoader().getResource("checkSumTest.file").toURI().getPath());
String expResult = "b8a9ff28b21bcb1d0b50e24a5243d8b51766851a";
String result = Checksum.getSHA1Checksum(file);
assertEquals(expResult, result);
}
/**
* Test of getChecksum method, of class Checksum.
*/
@Test
public void testGetChecksum_String_byteArr() {
String algorithm = "SHA1";
byte[] bytes = {-16, -111, 92, 95, 70, -72, -49, -94, -125, -27, -83, 103, -96, -101, 55, -109};
String expResult = "89268a389a97f0bfba13d3ff2370d8ad436e36f6";
String result = Checksum.getChecksum(algorithm, bytes);
assertEquals(expResult, result);
}
/**
* Test of getMD5Checksum method, of class Checksum.
*/
@Test
public void testGetMD5Checksum_String() {
String text = "test string";
String expResult = "6f8db599de986fab7a21625b7916589c";
String result = Checksum.getMD5Checksum(text);
assertEquals(expResult, result);
}
/**
* Test of getSHA1Checksum method, of class Checksum.
*/
@Test
public void testGetSHA1Checksum_String() {
String text = "test string";
String expResult = "661295c9cbf9d6b2f6428414504a8deed3020641";
String result = Checksum.getSHA1Checksum(text);
assertEquals(expResult, result);
}
}

View File

@@ -0,0 +1,57 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.File;
import java.net.URL;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import static org.junit.Assert.assertTrue;
/**
*
* @author Jeremy Long
*/
public class DownloaderIT extends BaseTest {
/**
* Test of fetchFile method, of class Downloader.
*
* @throws Exception thrown when an exception occurs.
*/
@Test
public void testFetchFile() throws Exception {
// Settings.setString(Settings.KEYS.CONNECTION_TIMEOUT, "1000");
// Settings.setString(Settings.KEYS.PROXY_PORT, "8080");
// Settings.setString(Settings.KEYS.PROXY_SERVER, "127.0.0.1");
URL url = new URL(getSettings().getString(Settings.KEYS.CVE_MODIFIED_20_URL));
File outputPath = new File("target/downloaded_cve.xml");
Downloader downloader = new Downloader(getSettings());
downloader.fetchFile(url, outputPath);
assertTrue(outputPath.isFile());
}
@Test
public void testGetLastModified() throws Exception {
URL url = new URL(getSettings().getString(Settings.KEYS.CVE_MODIFIED_20_URL));
Downloader downloader = new Downloader(getSettings());
long timestamp = downloader.getLastModified(url);
assertTrue("timestamp equal to zero?", timestamp > 0);
}
}

View File

@@ -0,0 +1,36 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.File;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
/**
*
* @author Jeremy Long
*/
public class DownloaderTest extends BaseTest {
@Test
public void testGetLastModified_file() throws Exception {
Downloader instance = new Downloader(getSettings());
long timestamp = instance.getLastModified(new File("target/test-classes/dependencycheck.properties").toURI().toURL());
assertTrue("timestamp equal to zero?", timestamp > 0);
}
}

View File

@@ -0,0 +1,77 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2016 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.fail;
import org.junit.Test;
import static org.junit.Assert.fail;
/**
*
* @author jeremy
*/
public class ExpectedObjectInputStreamTest {
/**
* Test of resolveClass method, of class ExpectedObjectInputStream.
*/
@Test
public void testResolveClass() {
List<SimplePojo> data = new ArrayList<>();
data.add(new SimplePojo());
try (ByteArrayOutputStream mem = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(mem))) {
out.writeObject(data);
out.flush();
byte[] buf = mem.toByteArray();
ByteArrayInputStream in = new ByteArrayInputStream(buf);
ExpectedObjectInputStream instance = new ExpectedObjectInputStream(in, "java.util.ArrayList", "org.owasp.dependencycheck.utils.SimplePojo", "java.lang.Integer", "java.lang.Number");
instance.readObject();
} catch (IOException | ClassNotFoundException ex) {
fail(ex.getMessage());
}
}
/**
* Test of resolveClass method, of class ExpectedObjectInputStream.
*/
@Test(expected = java.io.InvalidClassException.class)
public void testResolveClassException() throws Exception {
List<SimplePojo> data = new ArrayList<>();
data.add(new SimplePojo());
ByteArrayOutputStream mem = new ByteArrayOutputStream();
byte[] buf;
try (ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(mem))) {
out.writeObject(data);
out.flush();
buf = mem.toByteArray();
}
ByteArrayInputStream in = new ByteArrayInputStream(buf);
ExpectedObjectInputStream instance = new ExpectedObjectInputStream(in, "java.util.ArrayList", "org.owasp.dependencycheck.utils.SimplePojo");
instance.readObject();
}
}

View File

@@ -0,0 +1,61 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import java.io.File;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.Test;
/**
*
* @author Jeremy Long
*/
public class FileUtilsTest extends BaseTest {
/**
* Test of getFileExtension method, of class FileUtils.
*/
@Test
public void testGetFileExtension() {
String[] fileName = {"something-0.9.5.jar", "lib2-1.1.js", "dir.tmp/noext"};
String[] expResult = {"jar", "js", null};
for (int i = 0; i < fileName.length; i++) {
String result = FileUtils.getFileExtension(fileName[i]);
assertEquals("Failed extraction on \"" + fileName[i] + "\".", expResult[i], result);
}
}
/**
* Test of delete method, of class FileUtils.
*/
@Test
public void testDelete() throws Exception {
File file = File.createTempFile("tmp", "deleteme", getSettings().getTempDirectory());
if (!file.exists()) {
fail("Unable to create a temporary file.");
}
boolean status = FileUtils.delete(file);
assertTrue("delete returned a failed status", status);
assertFalse("Temporary file exists after attempting deletion", file.exists());
}
}

View File

@@ -0,0 +1,328 @@
/*
* This file is part of dependency-check-core.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) 2012 Jeremy Long. All Rights Reserved.
*/
package org.owasp.dependencycheck.utils;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.hamcrest.core.IsNull.nullValue;
import static org.junit.Assert.assertThat;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import org.junit.Assert;
import org.junit.Test;
/**
*
* @author Jeremy Long
*/
public class SettingsTest extends BaseTest {
/**
* Test of getString method, of class Settings.
*/
@Test
public void testGetString() {
String key = Settings.KEYS.CVE_MODIFIED_VALID_FOR_DAYS;
String expResult = "7";
String result = getSettings().getString(key);
Assert.assertTrue(result.endsWith(expResult));
}
/**
* Test of getDataFile method, of class Settings.
*/
@Test
public void testGetDataFile() throws IOException {
String key = Settings.KEYS.DATA_DIRECTORY;
String expResult = "data";
File result = getSettings().getDataFile(key);
Assert.assertTrue(result.getAbsolutePath().endsWith(expResult));
}
/**
* Test of mergeProperties method, of class Settings.
* @throws java.io.IOException thrown when the test fails
* @throws java.net.URISyntaxException thrown when the test fails
*/
@Test
public void testMergeProperties_String() throws IOException, URISyntaxException {
String key = Settings.KEYS.PROXY_PORT;
String expResult = getSettings().getString(key);
File f = new File(this.getClass().getClassLoader().getResource("test.properties").toURI());
//InputStream in = this.getClass().getClassLoader().getResourceAsStream("test.properties");
getSettings().mergeProperties(f.getAbsolutePath());
String result = getSettings().getString(key);
Assert.assertTrue("setting didn't change?", (expResult == null && result != null) || !expResult.equals(result));
}
/**
* Test of setString method, of class Settings.
*/
@Test
public void testSetString() {
String key = "newProperty";
String value = "someValue";
getSettings().setString(key, value);
String expResults = getSettings().getString(key);
Assert.assertEquals(expResults, value);
}
/**
* Test of setStringIfNotNull method, of class Settings.
*/
@Test
public void testSetStringIfNotNull() {
String key = "nullableProperty";
String value = "someValue";
getSettings().setString(key, value);
getSettings().setStringIfNotNull(key, null); // NO-OP
String expResults = getSettings().getString(key);
Assert.assertEquals(expResults, value);
}
/**
* Test of setStringIfNotNull method, of class Settings.
*/
@Test
public void testSetStringIfNotEmpty() {
String key = "optionalProperty";
String value = "someValue";
getSettings().setString(key, value);
getSettings().setStringIfNotEmpty(key, ""); // NO-OP
String expResults = getSettings().getString(key);
Assert.assertEquals(expResults, value);
}
/**
* Test of getString method, of class Settings.
*/
@Test
public void testGetString_String_String() {
String key = "key That Doesn't Exist";
String defaultValue = "blue bunny";
String expResult = "blue bunny";
String result = getSettings().getString(key);
Assert.assertTrue(result == null);
result = getSettings().getString(key, defaultValue);
Assert.assertEquals(expResult, result);
}
/**
* Test of getString method, of class Settings.
*/
@Test
public void testGetString_String() {
String key = Settings.KEYS.CONNECTION_TIMEOUT;
String result = getSettings().getString(key);
Assert.assertTrue(result == null);
}
/**
* Test of getInt method, of class Settings.
*/
@Test
public void testGetInt() throws InvalidSettingException {
String key = "SomeNumber";
int expResult = 85;
getSettings().setString(key, "85");
int result = getSettings().getInt(key);
Assert.assertEquals(expResult, result);
}
/**
* Test of getInt method, of class Settings.
*/
@Test
public void testGetIntDefault() throws InvalidSettingException {
String key = "SomeKey";
int expResult = 85;
getSettings().setString(key, "blue");
int result = getSettings().getInt(key, expResult);
Assert.assertEquals(expResult, result);
}
/**
* Test of getLong method, of class Settings.
*/
@Test
public void testGetLong() throws InvalidSettingException {
String key = "SomeNumber";
long expResult = 300L;
getSettings().setString(key, "300");
long result = getSettings().getLong(key);
Assert.assertEquals(expResult, result);
}
/**
* Test of getBoolean method, of class Settings.
*/
@Test
public void testGetBoolean() throws InvalidSettingException {
String key = "SomeBoolean";
getSettings().setString(key, "false");
boolean expResult = false;
boolean result = getSettings().getBoolean(key);
Assert.assertEquals(expResult, result);
key = "something that does not exist";
expResult = true;
result = getSettings().getBoolean(key, true);
Assert.assertEquals(expResult, result);
}
/**
* Test of removeProperty method, of class Settings.
*/
@Test
public void testRemoveProperty() {
String key = "SomeKey";
String value = "value";
String dfault = "default";
getSettings().setString(key, value);
String ret = getSettings().getString(key);
Assert.assertEquals(value, ret);
getSettings().removeProperty(key);
ret = getSettings().getString(key, dfault);
Assert.assertEquals(dfault, ret);
}
/**
* Test of getConnectionString.
*/
@Test
public void testGetConnectionString() throws Exception {
String value = getSettings().getConnectionString(Settings.KEYS.DB_CONNECTION_STRING, Settings.KEYS.DB_FILE_NAME);
Assert.assertNotNull(value);
String msg = null;
try {
value = getSettings().getConnectionString("invalidKey", null);
} catch (InvalidSettingException e) {
msg = e.getMessage();
}
Assert.assertNotNull(msg);
}
/**
* Test of getTempDirectory.
*/
@Test
public void testGetTempDirectory() throws Exception {
File tmp = getSettings().getTempDirectory();
Assert.assertTrue(tmp.exists());
}
/**
* Assert {@link Settings#getArray(String)} from a delimited string returns
* multiple values in an array.
*/
@Test
public void testGetArrayFromADelimitedString() {
// GIVEN a delimited string
final String delimitedString = "value1,value2";
getSettings().setString("key", delimitedString);
// WHEN getting the array
final String[] array = getSettings().getArray("key");
// THEN the split array is returned
assertThat("Expected the array to be non-null", array, notNullValue());
assertThat("Expected the array to have two values", array.length, is(2));
assertThat("Expected the first array value to be value1", array[0], is("value1"));
assertThat("Expected the second array value to be value2", array[1], is("value2"));
}
/**
* Assert {@link Settings#getArray(String)} returns {@code null} if the
* property is not set.
*/
@Test
public void testGetArrayWhereThePropertyIsNotSet() {
// WHEN getting the array
final String[] array = getSettings().getArray("key");
// THEN null is returned
assertThat("Expected the array to be null", array, nullValue());
}
/**
* Assert {@link Settings#setArrayIfNotEmpty(String, String[])} with an
* empty array is ignored.
*/
@Test
public void testSetArrayNotEmptyIgnoresAnEmptyArray() {
// GIVEN an empty array
final String[] array = {};
// WHEN setting the array
getSettings().setArrayIfNotEmpty("key", array);
// THEN the property was not set
assertThat("Expected the property to not be set", getSettings().getString("key"), nullValue());
}
/**
* Assert {@link Settings#setArrayIfNotEmpty(String, String[])} with a null
* array is ignored.
*/
@Test
public void testSetArrayNotEmptyIgnoresAnNullArray() {
// GIVEN a null array
final String[] array = null;
// WHEN setting the array
getSettings().setArrayIfNotEmpty("key", array);
// THEN the property was not set
assertThat("Expected the property to not be set", getSettings().getString("key"), nullValue());
}
/**
* Assert {@link Settings#setArrayIfNotEmpty(String, String[])} with
* multiple values sets a delimited string.
*/
@Test
public void testSetArrayNotEmptySetsADelimitedString() {
// GIVEN an array with values
final String[] array = {"value1", "value2"};
// WHEN setting the array
getSettings().setArrayIfNotEmpty("key", array);
// THEN the property is set
assertThat("Expected the property to be set", getSettings().getString("key"), is("value1,value2"));
}
/**
* Assert {@link Settings#setArrayIfNotEmpty(String, String[])} with a
* single values sets a string.
*/
@Test
public void testSetArrayNotEmptyWithSingleValueSetsAString() {
// GIVEN an array with a value
final String[] array = {"value1"};
// WHEN setting the array
getSettings().setArrayIfNotEmpty("key", array);
// THEN the property is set
assertThat("Expected the property to be set", getSettings().getString("key"), is("value1"));
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2016 OWASP.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.owasp.dependencycheck.utils;
import java.io.Serializable;
/**
* Simple pojo used to test the ExpectedObjectInputStream.
*
* @author jeremy
*/
public class SimplePojo implements Serializable {
/**
* The serial version UID for serialization.
*/
private static final long serialVersionUID = 1L;
public String s = "3";
public Integer i = 3;
}

View File

@@ -0,0 +1 @@
this is a test file used to check the checksums.

View File

@@ -0,0 +1,70 @@
application.name=${pom.name}
application.version=${pom.version}
autoupdate=true
# the url to obtain the current engine version from
engine.version.url=http://jeremylong.github.io/DependencyCheck/current.txt
#temp.directory defaults to System.getProperty("java.io.tmpdir")
#temp.directory=[path to temp directory]
# the path to the data directory; the [JAR] signifies to use the relative path
# to the dependency-check-core JAR file. This path is only used to construct
# the connection string for the H2 driver (or other drivers that require a file path
# to be supplied. If you are using another database (MySQL, Oracle, etc.) this property
# will not be used. The data.directory will be resolved and if the connection string
# below contains a %s then the data.directory will replace the %s.
data.directory=[JAR]/data
data.file_name=dc.h2.db
data.version=3.0
data.connection_string=jdbc:h2:file:%s;MV_STORE=FALSE;AUTOCOMMIT=ON;
#data.connection_string=jdbc:h2:file:%s;AUTO_SERVER=TRUE;AUTOCOMMIT=ON;
#data.connection_string=jdbc:mysql://localhost:3306/dependencycheck
# user name and password for the database connection. The inherent case is to use H2.
# As such, this unsecure username/password exist.
data.user=dcuser
data.password=DC-Pass1337!
# The following are only used if the DB Driver is not JDBC4 compliant and/or the driver
# is not in the current classpath. Setting these properties will add the give path(s) to
# the class loader and then register the driver with the DriverManager. If the class is
# not in the path you must specify both the driver name (aka the fully qualified driver name)
# and the driver path. The driver path can be a semi-colon separated list of files/directories
# to ensure any and all needed files can be added to the classpath to load the driver.
# For non-JDBC4 drivers in the classpath only the driver_name needs to be set.
# For MOST situations these properties likely do not need to be set.
data.driver_name=org.h2.Driver
data.driver_path=
proxy.disableSchemas=true
# the path to the cpe xml file
cpe.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.xml.gz
# the path to the cpe meta data file.
cpe.meta.url=http://static.nvd.nist.gov/feeds/xml/cpe/dictionary/official-cpe-dictionary_v2.2.meta
# the number of days that the modified nvd cve data holds data for. We don't need
# to update the other files if we are within this timespan. Per NIST this file
# holds 8 days of updates, we are using 7 just to be safe.
cve.url.modified.validfordays=7
# the path to the modified nvd cve xml file.
cve.startyear=2014
cve.url-1.2.modified=https://nvd.nist.gov/download/nvdcve-Modified.xml.gz
#cve.url-1.2.modified=http://nvd.nist.gov/download/nvdcve-modified.xml
cve.url-2.0.modified=https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-Modified.xml.gz
#cve.url-2.0.modified=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-modified.xml
cve.url-1.2.base=https://nvd.nist.gov/download/nvdcve-%d.xml.gz
#cve.url-1.2.base=http://nvd.nist.gov/download/nvdcve-%d.xml
cve.url-2.0.base=https://nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml.gz
#cve.url-2.0.base=http://static.nvd.nist.gov/feeds/xml/cve/nvdcve-2.0-%d.xml
# the URL for searching Nexus for SHA-1 hashes and whether it's enabled
analyzer.nexus.enabled=true
analyzer.nexus.url=https://repository.sonatype.org/service/local/
# If set to true, the proxy will still ONLY be used if the proxy properties (proxy.url, proxy.port)
# are configured
analyzer.nexus.proxy=true
# use HEAD (default) or GET as HTTP request method for query timestamp
downloader.quick.query.timestamp=true
downloader.tls.protocols=TLSv1,TLSv1.1,TLSv1.2,TLSv1.3

View File

@@ -0,0 +1,13 @@
<configuration>
<contextName>dependency-check</contextName>
<!-- Logging configuration -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<Target>System.out</Target>
<encoder>
<pattern>[%level] %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="console"/>
</root>
</configuration>

View File

@@ -0,0 +1 @@
proxy.port=80