From ece69014ced87181c5a46b8eb95b02745293b98a Mon Sep 17 00:00:00 2001 From: Jeremy Long Date: Mon, 16 Mar 2015 06:50:12 -0400 Subject: [PATCH] added auth to nexus search Former-commit-id: eb0b5e8ab0dcb27fe2edcb79b9dc9898c13bcb6b --- .../data/nexus/NexusSearch.java | 48 ++++++-- .../owasp/dependencycheck/utils/Settings.java | 114 ++++++++++-------- .../utils/URLConnectionFactory.java | 29 +++++ 3 files changed, 129 insertions(+), 62 deletions(-) diff --git a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusSearch.java b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusSearch.java index 183a9f57c..1e9d5b9c7 100644 --- a/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusSearch.java +++ b/dependency-check-core/src/main/java/org/owasp/dependencycheck/data/nexus/NexusSearch.java @@ -40,20 +40,26 @@ import org.w3c.dom.Document; public class NexusSearch { /** - * The root URL for the Nexus repository service + * The root URL for the Nexus repository service. */ private final URL rootURL; /** - * Whether to use the Proxy when making requests + * Whether to use the Proxy when making requests. */ private boolean useProxy; - + /** + * The username to use if the Nexus requires authentication. + */ + private String userName = null; + /** + * The password to use if the Nexus requires authentication. + */ + private char[] password; /** * Used for logging. */ - private static final Logger LOGGER = Logger.getLogger(NexusSearch.class - .getName()); + private static final Logger LOGGER = Logger.getLogger(NexusSearch.class.getName()); /** * Creates a NexusSearch for the given repository URL. @@ -68,9 +74,23 @@ public class NexusSearch { && Settings.getBoolean(Settings.KEYS.ANALYZER_NEXUS_PROXY)) { useProxy = true; LOGGER.fine("Using proxy"); + if (Settings.getString(Settings.KEYS.ANALYZER_NEXUS_USER) != null) { + LOGGER.fine("Unable to use nexus authentication while using a proxy. Consider disabling the use of a proxy with Nexus."); + } } else { useProxy = false; LOGGER.fine("Not using proxy"); + userName = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_USER); + String tmp = Settings.getString(Settings.KEYS.ANALYZER_NEXUS_PASSWORD); + if (tmp != null) { + password = tmp.toCharArray(); + } else { + if (userName != null) { + userName = null; + LOGGER.fine("Nexus password is not set yet user name was configured. Disabling the use of authentication for Nexus."); + } + } + } } catch (InvalidSettingException ise) { useProxy = false; @@ -98,9 +118,13 @@ public class NexusSearch { // Determine if we need to use a proxy. The rules: // 1) If the proxy is set, AND the setting is set to true, use the proxy // 2) Otherwise, don't use the proxy (either the proxy isn't configured, - // or proxy is specifically - // set to false - final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); + // or proxy is specifically set to false + HttpURLConnection conn; + if (useProxy && userName == null) { + conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); + } else { + conn = URLConnectionFactory.createHttpURLConnection(url, userName, password); + } conn.setDoOutput(true); @@ -163,8 +187,14 @@ public class NexusSearch { * @return whether the repository is listening and returns the /status URL correctly */ public boolean preflightRequest() { + HttpURLConnection conn; try { - final HttpURLConnection conn = URLConnectionFactory.createHttpURLConnection(new URL(rootURL, "status"), useProxy); + URL url = new URL(rootURL, "status"); + if (useProxy && userName == null) { + conn = URLConnectionFactory.createHttpURLConnection(url, useProxy); + } else { + conn = URLConnectionFactory.createHttpURLConnection(url, userName, password); + } conn.addRequestProperty("Accept", "application/xml"); conn.connect(); if (conn.getResponseCode() != 200) { diff --git a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java index db55a7885..89c94a7de 100644 --- a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java +++ b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/Settings.java @@ -103,13 +103,13 @@ public final class Settings { */ public static final String CVE_META_URL = "cve.url.meta"; /** - * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days) using - * the 2.0 schema. + * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days) using the 2.0 + * schema. */ public static final String CVE_MODIFIED_20_URL = "cve.url-2.0.modified"; /** - * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days) using - * the 1.2 schema. + * The properties key for the URL to retrieve the recently modified and added CVE entries (last 8 days) using the 1.2 + * schema. */ public static final String CVE_MODIFIED_12_URL = "cve.url-1.2.modified"; /** @@ -117,8 +117,8 @@ public final class Settings { */ public static final String CVE_MODIFIED_VALID_FOR_DAYS = "cve.url.modified.validfordays"; /** - * The properties key for the telling us how many cve.url.* URLs exists. This is used in combination with - * CVE_BASE_URL to be able to retrieve the URLs for all of the files that make up the NVD CVE listing. + * The properties key for the telling us how many cve.url.* URLs exists. This is used in combination with CVE_BASE_URL to + * be able to retrieve the URLs for all of the files that make up the NVD CVE listing. */ public static final String CVE_START_YEAR = "cve.startyear"; /** @@ -200,6 +200,14 @@ public final class Settings { * The properties key for using the proxy to reach Nexus. */ public static final String ANALYZER_NEXUS_PROXY = "analyzer.nexus.proxy"; + /** + * The properties key for the Nexus user name. + */ + public static final String ANALYZER_NEXUS_USER = "analyzer.nexus.user"; + /** + * The properties key for the Nexus user's password. + */ + public static final String ANALYZER_NEXUS_PASSWORD = "analyzer.nexus.password"; /** * The properties key for whether the Central analyzer is enabled. */ @@ -297,16 +305,16 @@ public final class Settings { } /** - * Initializes the thread local settings object. Note, to use the settings object you must call this method. - * However, you must also call Settings.cleanup() to properly release resources. + * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must + * also call Settings.cleanup() to properly release resources. */ public static void initialize() { localSettings.set(new Settings(PROPERTIES_FILE)); } /** - * Initializes the thread local settings object. Note, to use the settings object you must call this method. - * However, you must also call Settings.cleanup() to properly release resources. + * Initializes the thread local settings object. Note, to use the settings object you must call this method. However, you must + * also call Settings.cleanup() to properly release resources. * * @param propertiesFilePath the path to the base properties file to load */ @@ -423,8 +431,8 @@ public final class Settings { } /** - * Merges a new properties file into the current properties. This method allows for the loading of a user provided - * properties file.

+ * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties + * file.

* Note: even if using this method - system properties will be loaded before properties loaded from files. * * @param filePath the path to the properties file to merge. @@ -448,8 +456,8 @@ public final class Settings { } /** - * Merges a new properties file into the current properties. This method allows for the loading of a user provided - * properties file.

+ * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties + * file.

* Note: even if using this method - system properties will be loaded before properties loaded from files. * * @param filePath the path to the properties file to merge. @@ -473,8 +481,8 @@ public final class Settings { } /** - * Merges a new properties file into the current properties. This method allows for the loading of a user provided - * properties file.

+ * Merges a new properties file into the current properties. This method allows for the loading of a user provided properties + * file.

* Note: even if using this method - system properties will be loaded before properties loaded from files. * * @param stream an Input Stream pointing at a properties file to merge @@ -486,9 +494,9 @@ public final class Settings { } /** - * Returns a value from the properties file as a File object. If the value was specified as a system property or - * passed in via the -Dprop=value argument - this method will return the value from the system properties before the - * values in the contained configuration file. + * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via + * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained + * configuration file. * * @param key the key to lookup within the properties file * @return the property from the properties file converted to a File object @@ -502,13 +510,13 @@ public final class Settings { } /** - * Returns a value from the properties file as a File object. If the value was specified as a system property or - * passed in via the -Dprop=value argument - this method will return the value from the system properties before the - * values in the contained configuration file. + * Returns a value from the properties file as a File object. If the value was specified as a system property or passed in via + * the -Dprop=value argument - this method will return the value from the system properties before the values in the contained + * configuration file. * - * This method will check the configured base directory and will use this as the base of the file path. - * Additionally, if the base directory begins with a leading "[JAR]\" sequence with the path to the folder - * containing the JAR file containing this class. + * This method will check the configured base directory and will use this as the base of the file path. Additionally, if the + * base directory begins with a leading "[JAR]\" sequence with the path to the folder containing the JAR file containing this + * class. * * @param key the key to lookup within the properties file * @return the property from the properties file converted to a File object @@ -553,9 +561,9 @@ public final class Settings { } /** - * Returns a value from the properties file. If the value was specified as a system property or passed in via the - * -Dprop=value argument - this method will return the value from the system properties before the values in the - * contained configuration file. + * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value + * argument - this method will return the value from the system properties before the values in the contained configuration + * file. * * @param key the key to lookup within the properties file * @param defaultValue the default value for the requested property @@ -591,9 +599,9 @@ public final class Settings { } /** - * Returns a value from the properties file. If the value was specified as a system property or passed in via the - * -Dprop=value argument - this method will return the value from the system properties before the values in the - * contained configuration file. + * Returns a value from the properties file. If the value was specified as a system property or passed in via the -Dprop=value + * argument - this method will return the value from the system properties before the values in the contained configuration + * file. * * @param key the key to lookup within the properties file * @return the property from the properties file @@ -612,9 +620,9 @@ public final class Settings { } /** - * Returns an int value from the properties file. If the value was specified as a system property or passed in via - * the -Dprop=value argument - this method will return the value from the system properties before the values in the - * contained configuration file. + * Returns an int value from the properties file. If the value was specified as a system property or passed in via the + * -Dprop=value argument - this method will return the value from the system properties before the values in the contained + * configuration file. * * @param key the key to lookup within the properties file * @return the property from the properties file @@ -631,14 +639,14 @@ public final class Settings { } /** - * Returns an int value from the properties file. If the value was specified as a system property or passed in via - * the -Dprop=value argument - this method will return the value from the system properties before the values in the - * contained configuration file. + * Returns an int value from the properties file. If the value was specified as a system property or passed in via the + * -Dprop=value argument - this method will return the value from the system properties before the values in the contained + * configuration file. * * @param key the key to lookup within the properties file * @param defaultValue the default value to return - * @return the property from the properties file or the defaultValue if the property does not exist or cannot be - * converted to an integer + * @return the property from the properties file or the defaultValue if the property does not exist or cannot be converted to + * an integer */ public static int getInt(String key, int defaultValue) { int value; @@ -653,9 +661,9 @@ public final class Settings { } /** - * Returns a long value from the properties file. If the value was specified as a system property or passed in via - * the -Dprop=value argument - this method will return the value from the system properties before the values in the - * contained configuration file. + * Returns a long value from the properties file. If the value was specified as a system property or passed in via the + * -Dprop=value argument - this method will return the value from the system properties before the values in the contained + * configuration file. * * @param key the key to lookup within the properties file * @return the property from the properties file @@ -672,9 +680,9 @@ public final class Settings { } /** - * Returns a boolean value from the properties file. If the value was specified as a system property or passed in - * via the -Dprop=value argument this method will return the value from the system properties before - * the values in the contained configuration file. + * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the + * -Dprop=value argument this method will return the value from the system properties before the values in the + * contained configuration file. * * @param key the key to lookup within the properties file * @return the property from the properties file @@ -691,9 +699,9 @@ public final class Settings { } /** - * Returns a boolean value from the properties file. If the value was specified as a system property or passed in - * via the -Dprop=value argument this method will return the value from the system properties before - * the values in the contained configuration file. + * Returns a boolean value from the properties file. If the value was specified as a system property or passed in via the + * -Dprop=value argument this method will return the value from the system properties before the values in the + * contained configuration file. * * @param key the key to lookup within the properties file * @param defaultValue the default value to return if the setting does not exist @@ -715,9 +723,9 @@ public final class Settings { } /** - * Returns a connection string from the configured properties. If the connection string contains a %s, this method - * will determine the 'data' directory and replace the %s with the path to the data directory. If the data directory - * does not exists it will be created. + * Returns a connection string from the configured properties. If the connection string contains a %s, this method will + * determine the 'data' directory and replace the %s with the path to the data directory. If the data directory does not + * exists it will be created. * * @param connectionStringKey the property file key for the connection string * @param dbFileNameKey the settings key for the db filename @@ -770,8 +778,8 @@ public final class Settings { } /** - * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory - * for the embedded H2 database. This is public solely for some unit tests; otherwise this should be private. + * Retrieves the directory that the JAR file exists in so that we can ensure we always use a common data directory for the + * embedded H2 database. This is public solely for some unit tests; otherwise this should be private. * * @return the data directory to store data files * @throws IOException is thrown if an IOException occurs of course... diff --git a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/URLConnectionFactory.java b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/URLConnectionFactory.java index b0b40ece8..3b3f7a5f6 100644 --- a/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/URLConnectionFactory.java +++ b/dependency-check-utils/src/main/java/org/owasp/dependencycheck/utils/URLConnectionFactory.java @@ -117,4 +117,33 @@ public final class URLConnectionFactory { } return conn; } + + /** + * Utility method to create an HttpURLConnection. This version of createHttpURLConnection does not utilize any proxy + * configuration; but does provide the ability to authenticate to the site. + * + * @param url the URL to connect to + * @param username the user name for authentication to the given site + * @param password the password for authentication to the given site + * @return a newly constructed HttpURLConnection + * @throws URLConnectionFailureException thrown if there is an exception + */ + public static HttpURLConnection createHttpURLConnection(URL url, final String username, final char[] password) + throws URLConnectionFailureException { + HttpURLConnection conn = null; + try { + Authenticator.setDefault(new Authenticator() { + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + conn = (HttpURLConnection) url.openConnection(); + final int timeout = Settings.getInt(Settings.KEYS.CONNECTION_TIMEOUT, 60000); + conn.setConnectTimeout(timeout); + conn.setInstanceFollowRedirects(true); + } catch (IOException ioe) { + throw new URLConnectionFailureException("Error getting connection.", ioe); + } + return conn; + } }