Github user mike-jumper commented on a diff in the pull request:

    
https://github.com/apache/incubator-guacamole-client/pull/183#discussion_r143890461
  
    --- Diff: 
extensions/guacamole-auth-cas/src/main/java/org/apache/guacamole/auth/cas/ticket/TicketValidationService.java
 ---
    @@ -36,48 +47,134 @@
     public class TicketValidationService {
     
         /**
    +     * Logger for this class.
    +     */
    +    private static final Logger logger = 
LoggerFactory.getLogger(TicketValidationService.class);
    +
    +    /**
          * Service for retrieving CAS configuration information.
          */
         @Inject
         private ConfigurationService confService;
     
         /**
    -     * Validates and parses the given ID ticket, returning the username 
contained
    -     * therein, as defined by the username claim type given in
    -     * guacamole.properties. If the username claim type is missing or the 
ID
    -     * ticket is invalid, an exception is thrown instead.
    +     * Validates and parses the given ID ticket, returning the username
    +     * provided by the CAS server in the ticket.  If the
    +     * ticket is invalid an exception is thrown.
          *
          * @param ticket
          *     The ID ticket to validate and parse.
          *
    +     * @param credentials
    +     *     The Credentials object to store retrieved username and
    +     *     password values in.
    +     *
          * @return
    -     *     The username contained within the given ID ticket.
    +     *     The username derived from the ticket.
          *
          * @throws GuacamoleException
    -     *     If the ID ticket is not valid, the username claim type is 
missing, or
    -     *     guacamole.properties could not be parsed.
    +     *     If the ID ticket is not valid or guacamole.properties could
    +     *     not be parsed.
          */
    -    public String processUsername(String ticket) throws GuacamoleException 
{
    -
    -        AttributePrincipal principal = null;
    +    public String validateTicket(String ticket, Credentials credentials) 
throws GuacamoleException {
     
             // Retrieve the configured CAS URL, establish a ticket validator,
             // and then attempt to validate the supplied ticket.  If that 
succeeds,
             // grab the principal returned by the validator.
             String casServerUrl = confService.getAuthorizationEndpoint();
             Cas20ProxyTicketValidator validator = new 
Cas20ProxyTicketValidator(casServerUrl);
             validator.setAcceptAnyProxy(true);
    +        validator.setEncoding("UTF-8");
             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.debug("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, Charset.forName("UTF-8"));
    +
    +        }
    +        catch (BadPaddingException e) {
    +            throw new GuacamoleServerException("Bad padding when 
decrypting cipher data.", e);
    +        }
    +        catch (IllegalBlockSizeException e) {
    +            throw new GuacamoleServerException("Illegal block size while 
opening private key.", e);
    +        }
    +        catch (InvalidKeyException e) {
    +            throw new GuacamoleServerException("Specified private key for 
ClearPass decryption is invalid.", e);
    +        }
    +        catch (NoSuchAlgorithmException e) {
    +            throw new GuacamoleServerException("Unexpected algorithm for 
the private key.", e);
    +        }
    +        catch (NoSuchPaddingException e) {
    +            throw new GuacamoleServerException("No such padding tryingto 
initialize cipher with private key.", e);
    --- End diff --
    
    "tryingto"


---

Reply via email to