mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-07 13:41:21 +00:00
GUACAMOLE-96: Verify TOTP of all users against hard-coded key.
This commit is contained in:
@@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
package org.apache.guacamole.auth.totp;
|
package org.apache.guacamole.auth.totp;
|
||||||
|
|
||||||
|
import com.google.common.io.BaseEncoding;
|
||||||
|
import java.security.InvalidKeyException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import org.apache.guacamole.GuacamoleClientException;
|
import org.apache.guacamole.GuacamoleClientException;
|
||||||
@@ -30,12 +32,20 @@ import org.apache.guacamole.net.auth.Credentials;
|
|||||||
import org.apache.guacamole.net.auth.UserContext;
|
import org.apache.guacamole.net.auth.UserContext;
|
||||||
import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
|
import org.apache.guacamole.net.auth.credentials.CredentialsInfo;
|
||||||
import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
|
import org.apache.guacamole.net.auth.credentials.GuacamoleInsufficientCredentialsException;
|
||||||
|
import org.apache.guacamole.totp.TOTPGenerator;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for verifying the identity of a user using TOTP.
|
* Service for verifying the identity of a user using TOTP.
|
||||||
*/
|
*/
|
||||||
public class UserVerificationService {
|
public class UserVerificationService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logger for this class.
|
||||||
|
*/
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(UserVerificationService.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the HTTP parameter which will contain the TOTP code provided
|
* The name of the HTTP parameter which will contain the TOTP code provided
|
||||||
* by the user to verify their identity.
|
* by the user to verify their identity.
|
||||||
@@ -56,6 +66,30 @@ public class UserVerificationService {
|
|||||||
Collections.singletonList(TOTP_FIELD)
|
Collections.singletonList(TOTP_FIELD)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseEncoding instance which decoded/encodes base32.
|
||||||
|
*/
|
||||||
|
private static final BaseEncoding BASE32 = BaseEncoding.base32();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the base32-encoded TOTP key associated with user having the
|
||||||
|
* given UserContext. If no TOTP key is associated with the user, null is
|
||||||
|
* returned.
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* The UserContext of the user whose TOTP key should be retrieved.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The base32-encoded TOTP key associated with user having the given
|
||||||
|
* UserContext, or null if no TOTP key is associated with the user.
|
||||||
|
*/
|
||||||
|
public String getKey(UserContext context){
|
||||||
|
|
||||||
|
// FIXME: Hard-coded key
|
||||||
|
return "JBSWY3DPEHPK3PXP";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies the identity of the given user using TOTP. If a authentication
|
* Verifies the identity of the given user using TOTP. If a authentication
|
||||||
* code from the user's TOTP device has not already been provided, a code is
|
* code from the user's TOTP device has not already been provided, a code is
|
||||||
@@ -77,24 +111,47 @@ public class UserVerificationService {
|
|||||||
public void verifyIdentity(UserContext context,
|
public void verifyIdentity(UserContext context,
|
||||||
AuthenticatedUser authenticatedUser) throws GuacamoleException {
|
AuthenticatedUser authenticatedUser) throws GuacamoleException {
|
||||||
|
|
||||||
|
// Ignore anonymous users
|
||||||
|
String username = authenticatedUser.getIdentifier();
|
||||||
|
if (username.equals(AuthenticatedUser.ANONYMOUS_IDENTIFIER))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Ignore users which do not have an associated key
|
||||||
|
String encodedKey = getKey(context);
|
||||||
|
if (encodedKey == null)
|
||||||
|
return;
|
||||||
|
|
||||||
// Pull the original HTTP request used to authenticate
|
// Pull the original HTTP request used to authenticate
|
||||||
Credentials credentials = authenticatedUser.getCredentials();
|
Credentials credentials = authenticatedUser.getCredentials();
|
||||||
HttpServletRequest request = credentials.getRequest();
|
HttpServletRequest request = credentials.getRequest();
|
||||||
|
|
||||||
// Ignore anonymous users
|
|
||||||
if (authenticatedUser.getIdentifier().equals(AuthenticatedUser.ANONYMOUS_IDENTIFIER))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Retrieve TOTP from request
|
// Retrieve TOTP from request
|
||||||
String totp = request.getParameter(TOTP_PARAMETER_NAME);
|
String code = request.getParameter(TOTP_PARAMETER_NAME);
|
||||||
|
|
||||||
// If no TOTP provided, request one
|
// If no TOTP provided, request one
|
||||||
if (totp == null)
|
if (code == null)
|
||||||
throw new GuacamoleInsufficientCredentialsException(
|
throw new GuacamoleInsufficientCredentialsException(
|
||||||
"LOGIN.INFO_TOTP_REQUIRED", TOTP_CREDENTIALS);
|
"LOGIN.INFO_TOTP_REQUIRED", TOTP_CREDENTIALS);
|
||||||
|
|
||||||
// FIXME: Hard-coded code
|
try {
|
||||||
if (!totp.equals("123456"))
|
|
||||||
|
// Verify provided TOTP against value produced by generator
|
||||||
|
byte[] key = BASE32.decode(encodedKey);
|
||||||
|
TOTPGenerator totp = new TOTPGenerator(key, TOTPGenerator.Mode.SHA1, 6);
|
||||||
|
if (code.equals(totp.generate()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
catch (InvalidKeyException e) {
|
||||||
|
logger.warn("User \"{}\" is associated with an invalid TOTP key.", username);
|
||||||
|
logger.debug("TOTP key is not valid.", e);
|
||||||
|
}
|
||||||
|
catch (IllegalArgumentException e) {
|
||||||
|
logger.warn("TOTP key of user \"{}\" is not valid base32.", username);
|
||||||
|
logger.debug("TOTP key is not valid base32.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Provided code is not valid
|
||||||
throw new GuacamoleClientException("LOGIN.INFO_TOTP_VERIFICATION_FAILED");
|
throw new GuacamoleClientException("LOGIN.INFO_TOTP_VERIFICATION_FAILED");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user