Github user necouchman commented on a diff in the pull request:
https://github.com/apache/incubator-guacamole-client/pull/183#discussion_r142027025
--- Diff:
extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/ticket/TicketValidationService.java
---
@@ -70,14 +85,93 @@ public String processUsername(String ticket) throws
GuacamoleException {
try {
String confRedirectURI = confService.getRedirectURI();
Assertion a = validator.validate(ticket, confRedirectURI);
- principal = a.getPrincipal();
+ AttributePrincipal principal = a.getPrincipal();
+
+ // Retrieve username and set the credentials.
+ String username = principal.getName();
+ if (username != null)
+ credentials.setUsername(username);
+
+ // Retrieve password, attempt decryption, and set credentials.
+ Object credObj = principal.getAttributes().get("credential");
+ if (credObj != null) {
+ String clearPass = decryptPassword(credObj.toString());
+ if (clearPass != null && !clearPass.isEmpty())
+ credentials.setPassword(clearPass);
+ }
+
+ return username;
+
}
catch (TicketValidationException e) {
throw new GuacamoleException("Ticket validation failed.", e);
}
- // Return the principal name as the username.
- return principal.getName();
+ }
+
+ /**
+ * Takes an encrypted string representing a password provided by
+ * the CAS ClearPass service and decrypts it using the private
+ * key configured for this extension. Returns null if it is
+ * unable to decrypt the password.
+ *
+ * @param encryptedPassword
+ * A string with the encrypted password provided by the
+ * CAS service.
+ *
+ * @return
+ * The decrypted password, or null if it is unable to
+ * decrypt the password.
+ *
+ * @throws GuacamoleException
+ * If unable to get Guacamole configuration data
+ */
+ private final String decryptPassword(String encryptedPassword)
+ throws GuacamoleException {
+
+ // If we get nothing, we return nothing.
+ 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 =
Cipher.getInstance(clearpassKey.getAlgorithm());
+
+ if (cipher == null)
+ throw new GuacamoleServerException("Failed to initialize
cipher object with private key.");
+
+ // 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);
--- End diff --
I'll have to dig into the CAS side and see.
Is there a preferred way to convert byte[] data to a String in Java that is
considered production-safe?
---