in extensions/guacamole-auth-json/src/main/java/org/apache/guacamole/auth/json/user/UserDataService.java [118:213]
public UserData fromCredentials(Credentials credentials) {
String json;
byte[] correctSignature;
// Abort if the request itself is not allowed
if (!requestService.isAuthenticationAllowed(credentials))
return null;
// Pull base64-encoded, encrypted JSON data from HTTP request, if any
// such data is present
String base64 = credentials.getParameter(ENCRYPTED_DATA_PARAMETER);
if (base64 == null)
return null;
// Decrypt base64-encoded parameter
try {
// Decrypt using defined encryption key
byte[] decrypted = cryptoService.decrypt(
cryptoService.createEncryptionKey(confService.getSecretKey()),
BaseEncoding.base64().decode(base64)
);
// Abort if decrypted value cannot possibly have a signature AND data
if (decrypted.length <= CryptoService.SIGNATURE_LENGTH) {
logger.warn("Submitted data is too small to contain both a signature and JSON.");
return null;
}
// Split data into signature and JSON portions
byte[] receivedSignature = Arrays.copyOf(decrypted, CryptoService.SIGNATURE_LENGTH);
byte[] receivedJSON = Arrays.copyOfRange(decrypted, CryptoService.SIGNATURE_LENGTH, decrypted.length);
// Produce signature for decrypted data
correctSignature = cryptoService.sign(
cryptoService.createSignatureKey(confService.getSecretKey()),
receivedJSON
);
// Verify signatures
if (!Arrays.equals(receivedSignature, correctSignature)) {
logger.warn("Signature of submitted data is incorrect.");
return null;
}
// Convert from UTF-8
json = new String(receivedJSON, "UTF-8");
}
// Fail if base64 data is not valid
catch (IllegalArgumentException e) {
logger.warn("Submitted data is not proper base64.");
logger.debug("Invalid base64 data.", e);
return null;
}
// Handle lack of standard UTF-8 support (should never happen)
catch (UnsupportedEncodingException e) {
logger.error("Unexpected lack of support for UTF-8: {}", e.getMessage());
logger.debug("Unable to decode base64 data as UTF-8.", e);
return null;
}
// Fail if decryption or key retrieval fails for any reason
catch (GuacamoleException e) {
logger.error("Decryption of received data failed: {}", e.getMessage());
logger.debug("Unable to decrypt received data.", e);
return null;
}
// Deserialize UserData from submitted JSON data
try {
// Deserialize UserData, but reject if expired
UserData userData = mapper.readValue(json, UserData.class);
if (userData.isExpired())
return null;
// Reject if data is single-use and already present in the denylist
if (userData.isSingleUse() && !denylist.add(userData, correctSignature))
return null;
return userData;
}
// Fail UserData creation if JSON is invalid/unreadable
catch (IOException e) {
logger.error("Received JSON is invalid: {}", e.getMessage());
logger.debug("Error parsing UserData JSON.", e);
return null;
}
}