diff --git a/maven/pom.xml b/maven/pom.xml index 47b84eeb1f..8042a70a5c 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -153,8 +153,8 @@ Copyright (c) 2013 Jeremy Long. All Rights Reserved. <artifactId>maven-reporting-api</artifactId> </dependency> <dependency> - <groupId>org.sonatype.plexus</groupId> - <artifactId>plexus-sec-dispatcher</artifactId> + <groupId>org.apache.maven</groupId> + <artifactId>maven-settings-builder</artifactId> </dependency> <dependency> <groupId>org.apache.maven.shared</groupId> diff --git a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java index f96b481811..53ff41061c 100644 --- a/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java +++ b/maven/src/main/java/org/owasp/dependencycheck/maven/BaseDependencyCheckMojo.java @@ -42,6 +42,10 @@ import org.apache.maven.reporting.MavenReportException; import org.apache.maven.settings.Proxy; import org.apache.maven.settings.Server; +import org.apache.maven.settings.building.SettingsProblem; +import org.apache.maven.settings.crypto.DefaultSettingsDecryptionRequest; +import org.apache.maven.settings.crypto.SettingsDecrypter; +import org.apache.maven.settings.crypto.SettingsDecryptionResult; import org.apache.maven.shared.transfer.artifact.DefaultArtifactCoordinate; import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolver; import org.apache.maven.shared.transfer.artifact.resolve.ArtifactResolverException; @@ -74,12 +78,8 @@ import org.owasp.dependencycheck.utils.Downloader; import org.owasp.dependencycheck.utils.InvalidSettingException; import org.owasp.dependencycheck.utils.Settings; -import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher; -import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; -import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException; import java.io.File; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -885,11 +885,13 @@ public abstract class BaseDependencyCheckMojo extends AbstractMojo implements Ma @SuppressWarnings("CanBeFinal") @Parameter(defaultValue = "${settings}", readonly = true, required = true) private org.apache.maven.settings.Settings settingsXml; + /** - * The security dispatcher that can decrypt passwords in the settings.xml. + * The settingsDecryptor from Maven to decrypt passwords from Settings.xml servers section */ - @Component(role = SecDispatcher.class, hint = "default") - private SecDispatcher securityDispatcher; + @Component + private SettingsDecrypter settingsDecrypter; + /** * The database user name. */ @@ -2559,12 +2561,15 @@ private void configureCredentials(String serverId, String usernameValue, String * @throws InitializationException When both serverId and at least one other property value are filled. */ private void configureFromServer(Server server, String userKey, String passwordKey, String tokenKey, String serverId) throws InitializationException { + final SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(server)); final String username = server.getUsername(); - String password = server.getPassword(); - try { - password = decryptPasswordFromSettings(password); - } catch (SecDispatcherException ex) { - password = handleSecDispatcherException("server", serverId, server.getPassword(), ex); + final String password; + if (result.getProblems().isEmpty()) { + password = result.getServer().getPassword(); + } else { + logProblems(result.getProblems(), "server setting for " + serverId); + getLog().debug("Using raw password from settings.xml for server " + serverId); + password = server.getPassword(); } if (username != null) { if (userKey != null && passwordKey != null) { @@ -2600,13 +2605,16 @@ private void setProxyServerSysPropsFromMavenProxy(Proxy mavenProxy, String proto if (mavenProxy.getUsername() != null && !mavenProxy.getUsername().isEmpty()) { System.setProperty(protocol + ".proxyUser", mavenProxy.getUsername()); } - String password = mavenProxy.getPassword(); + final SettingsDecryptionResult result = settingsDecrypter.decrypt(new DefaultSettingsDecryptionRequest(mavenProxy)); + final String password; + if (result.getProblems().isEmpty()) { + password = result.getProxy().getPassword(); + } else { + logProblems(result.getProblems(), "proxy settings for " + mavenProxy.getId()); + getLog().debug("Using raw password from settings.xml for proxy " + mavenProxy.getId()); + password = mavenProxy.getPassword(); + } if (password != null && !password.isEmpty()) { - try { - password = decryptPasswordFromSettings(password); - } catch (SecDispatcherException ex) { - password = handleSecDispatcherException("proxy", mavenProxy.getId(), password, ex); - } System.setProperty(protocol + ".proxyPassword", password); } } @@ -2645,62 +2653,27 @@ private void configureServerCredentialsApiKey(String serverId, String apiKeySett } /** - * Decrypts a password from the Maven settings if it needs to be decrypted. - * If it's not encrypted the input password will be returned unchanged. + * Logs the problems encountered during settings decryption of a {@code <}server>} or {@code <proxy>} config + * from the maven settings.<br/> + * Logs a generic message about decryption problems at WARN level. If debug logging is enabled a additional message is logged at DEBUG level + * detailing all the encountered problems and their underlying exceptions. * - * @param password the original password value from the settings.xml - * @return the decrypted password from the Maven configuration - * @throws SecDispatcherException thrown if there is an error decrypting the - * password - */ - private String decryptPasswordFromSettings(String password) throws SecDispatcherException { - //The following fix was copied from: - // https://github.com/bsorrentino/maven-confluence-plugin/blob/master/maven-confluence-reporting-plugin/src/main/java/org/bsc/maven/confluence/plugin/AbstractBaseConfluenceMojo.java - // - // FIX to resolve - // org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException: - // java.io.FileNotFoundException: ~/.settings-security.xml (No such file or directory) - // - if (securityDispatcher instanceof DefaultSecDispatcher) { - ((DefaultSecDispatcher) securityDispatcher).setConfigurationFile("~/.m2/settings-security.xml"); - } - - return securityDispatcher.decrypt(password); - } - - /** - * Handles a SecDispatcherException that was thrown at an attempt to decrypt - * an encrypted password from the Maven settings. - * - * @param settingsElementName - "server" or "proxy" - * @param settingsElementId - value of the id attribute of the proxy resp. - * server element to which the password belongs - * @param passwordValueFromSettings - original, undecrypted password value - * from the settings - * @param ex - the Exception to handle - * @return the password fallback value to go on with, might be a not working - * one. - */ - private String handleSecDispatcherException(String settingsElementName, String settingsElementId, String passwordValueFromSettings, - SecDispatcherException ex) { - String password = passwordValueFromSettings; - if (ex.getCause() instanceof FileNotFoundException - || (ex.getCause() != null && ex.getCause().getCause() instanceof FileNotFoundException)) { - //maybe its not encrypted? - final String tmp = passwordValueFromSettings; - if (tmp.startsWith("{") && tmp.endsWith("}")) { - getLog().error(String.format( - "Unable to decrypt the %s password for %s id '%s' in settings.xml%n\tCause: %s", - settingsElementName, settingsElementName, settingsElementId, ex.getMessage())); - } else { - password = tmp; + * @param problems The problems as reported by the settingsDecrypter. + * @param credentialDesc an identification of what was attempted to be decrypted + */ + private void logProblems(List<SettingsProblem> problems, String credentialDesc) { + final String message = "Problems while decrypting " + credentialDesc; + getLog().warn(message); + if (getLog().isDebugEnabled()) { + final StringBuilder dbgMessage = new StringBuilder("Problems while decrypting ").append(credentialDesc).append(": "); + boolean first = true; + for (SettingsProblem problem : problems) { + dbgMessage.append(first ? "" : ", ").append(problem.getMessage()); + dbgMessage.append("caused by ").append(problem.getException()); + first = false; } - } else { - getLog().error(String.format( - "Unable to decrypt the %s password for %s id '%s' in settings.xml%n\tCause: %s", - settingsElementName, settingsElementName, settingsElementId, ex.getMessage())); + getLog().debug(dbgMessage.toString()); } - return password; } /** diff --git a/pom.xml b/pom.xml index bf94417671..139ddeea00 100644 --- a/pom.xml +++ b/pom.xml @@ -163,7 +163,6 @@ Copyright (c) 2012 - Jeremy Long <maven-plugin-annotations.version>3.15.1</maven-plugin-annotations.version> <maven-reporting-api.version>4.0.0</maven-reporting-api.version> <org.apache.velocity.version>2.4.1</org.apache.velocity.version> - <plexus-sec-dispatcher.version>1.4</plexus-sec-dispatcher.version> <maven-dependency-tree.version>3.3.0</maven-dependency-tree.version> <org.glassfish.javax.json.version>1.1.4</org.glassfish.javax.json.version> <maven-artifact-transfer.version>0.13.1</maven-artifact-transfer.version> @@ -1191,6 +1190,12 @@ Copyright (c) 2012 - Jeremy Long <version>${maven.api.version}</version> <scope>provided</scope> </dependency> + <dependency> + <groupId>org.apache.maven</groupId> + <artifactId>maven-settings-builder</artifactId> + <version>${maven.api.version}</version> + <scope>provided</scope> + </dependency> <dependency> <groupId>org.apache.maven.plugin-testing</groupId> <artifactId>maven-plugin-testing-harness</artifactId> @@ -1217,11 +1222,6 @@ Copyright (c) 2012 - Jeremy Long <artifactId>velocity-engine-core</artifactId> <version>${org.apache.velocity.version}</version> </dependency> - <dependency> - <groupId>org.sonatype.plexus</groupId> - <artifactId>plexus-sec-dispatcher</artifactId> - <version>${plexus-sec-dispatcher.version}</version> - </dependency> <!-- upgrading beyond 2.2 requires reworking the dependency resolution --> <dependency> <groupId>org.apache.maven.shared</groupId>