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?


---

Reply via email to