diff --git a/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/AuthenticationProviderService.java b/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/AuthenticationProviderService.java index da32f72eb..22a63bddc 100644 --- a/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/AuthenticationProviderService.java @@ -44,6 +44,7 @@ import javax.xml.bind.DatatypeConverter; import org.apache.guacamole.environment.Environment; import org.apache.guacamole.form.Field; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.GuacamoleServerException; import org.apache.guacamole.net.auth.Credentials; import org.apache.guacamole.net.auth.credentials.CredentialsInfo; import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException; @@ -166,32 +167,38 @@ public class AuthenticationProviderService { throws GuacamoleException { // If we get nothing, we return nothing. - if (encryptedPassword == null || encryptedPassword.isEmpty()) + if (encryptedPassword == null || encryptedPassword.isEmpty()) { + logger.warn("No or empty encrypted password, no password will be available."); return null; + } + + final PrivateKey clearpassKey = confService.getClearpassKey(); + if (clearpassKey == null) { + logger.warn("No private key available to decrypt password."); + return null; + } try { - final Cipher cipher = confService.getClearpassCipher(); + final Cipher cipher = Cipher.getInstance(clearpassKey.getAlgorithm()); - if (cipher != null) { + if (cipher == null) + throw new GuacamoleServerException("Failed to initialize cipher object with private key."); - // Decode and decrypt, and return a new string. - final byte[] pass64 = DatatypeConverter.parseBase64Binary(encryptedPassword); - final byte[] cipherData = cipher.doFinal(pass64); - return new String(cipherData); + // Initialize the Cipher in decrypt mode. + cipher.init(Cipher.DECRYPT_MODE, clearpassKey); - } + // Decode and decrypt, and return a new string. + final byte[] pass64 = DatatypeConverter.parseBase64Binary(encryptedPassword); + final byte[] cipherData = cipher.doFinal(pass64); + return new String(cipherData); } catch (Throwable t) { - logger.error("Failed to decrypt the data, password token will not be available."); logger.debug("Failed to either convert Base64 or decrypt the password. CAS Password will not be available inside Guacamole. Exception is: {}", t); - return null; + throw new GuacamoleServerException("Failed to decrypt CAS ClearPass password.", t); } - logger.warn("Encrypted password provided by CAS, but no Private Key was available to decrypt it."); - return null; - } } diff --git a/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/conf/CASGuacamoleProperties.java b/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/conf/CASGuacamoleProperties.java index 7a600c91b..aa4a06ef4 100644 --- a/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/conf/CASGuacamoleProperties.java +++ b/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/conf/CASGuacamoleProperties.java @@ -19,7 +19,7 @@ package org.apache.guacamole.auth.cas.conf; -import org.apache.guacamole.properties.CipherGuacamoleProperty; +import org.apache.guacamole.properties.PrivateKeyGuacamoleProperty; import org.apache.guacamole.properties.StringGuacamoleProperty; /** @@ -62,8 +62,8 @@ public class CASGuacamoleProperties { * The location of the private key file used to retrieve the * password if CAS is configured to support ClearPass. */ - public static final CipherGuacamoleProperty CAS_CLEARPASS_KEY = - new CipherGuacamoleProperty() { + public static final PrivateKeyGuacamoleProperty CAS_CLEARPASS_KEY = + new PrivateKeyGuacamoleProperty() { @Override public String getName() { return "cas-clearpass-key"; } diff --git a/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/conf/ConfigurationService.java b/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/conf/ConfigurationService.java index ba969d409..409097e54 100644 --- a/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/conf/ConfigurationService.java @@ -21,7 +21,7 @@ package org.apache.guacamole.auth.cas.conf; import com.google.inject.Inject; import java.io.File; -import javax.crypto.Cipher; +import java.security.PrivateKey; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.environment.Environment; @@ -82,7 +82,7 @@ public class ConfigurationService { * @throws GuacamoleException * If guacamole.properties cannot be parsed. */ - public Cipher getClearpassCipher() throws GuacamoleException { + public PrivateKey getClearpassKey() throws GuacamoleException { return environment.getProperty(CASGuacamoleProperties.CAS_CLEARPASS_KEY); } diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/properties/CipherGuacamoleProperty.java b/guacamole-ext/src/main/java/org/apache/guacamole/properties/PrivateKeyGuacamoleProperty.java similarity index 65% rename from guacamole-ext/src/main/java/org/apache/guacamole/properties/CipherGuacamoleProperty.java rename to guacamole-ext/src/main/java/org/apache/guacamole/properties/PrivateKeyGuacamoleProperty.java index d4d763f7f..904a4d1de 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/properties/CipherGuacamoleProperty.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/properties/PrivateKeyGuacamoleProperty.java @@ -33,29 +33,25 @@ import java.security.PrivateKey; import java.security.spec.InvalidKeySpecException; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; -import javax.crypto.Cipher; -import javax.crypto.NoSuchPaddingException; -import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.GuacamoleServerException; import org.apache.guacamole.environment.Environment; import org.apache.guacamole.environment.LocalEnvironment; /** * A GuacamoleProperty whose value is derived from a private key file. */ -public abstract class CipherGuacamoleProperty implements GuacamoleProperty { +public abstract class PrivateKeyGuacamoleProperty implements GuacamoleProperty { @Override - public Cipher parseValue(String value) throws GuacamoleException { + public PrivateKey parseValue(String value) throws GuacamoleServerException { if (value == null || value.isEmpty()) return null; try { - final Environment environment = new LocalEnvironment(); - // Open and read the file specified in the configuration. - File keyFile = new File(environment.getGuacamoleHome(), value); + File keyFile = new File(value); InputStream keyInput = new BufferedInputStream(new FileInputStream(keyFile)); final byte[] keyBytes = new byte[(int) keyFile.length()]; keyInput.read(keyBytes); @@ -64,30 +60,20 @@ public abstract class CipherGuacamoleProperty implements GuacamoleProperty