mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
GUACAMOLE-197: Add some comments to document the logic and the functions.
This commit is contained in:
committed by
Nick Couchman
parent
efad91adb0
commit
731c622e8f
@@ -90,7 +90,7 @@ public class AuthenticationProviderService {
|
|||||||
public AuthenticatedUser authenticateUser(Credentials credentials)
|
public AuthenticatedUser authenticateUser(Credentials credentials)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Attempt bind
|
// Initialize Radius Packet and try to authenticate
|
||||||
RadiusPacket radPack;
|
RadiusPacket radPack;
|
||||||
try {
|
try {
|
||||||
radPack = radiusService.authenticate(credentials.getUsername(),
|
radPack = radiusService.authenticate(credentials.getUsername(),
|
||||||
@@ -107,10 +107,17 @@ public class AuthenticationProviderService {
|
|||||||
logger.debug("Nothing in the RADIUS packet.");
|
logger.debug("Nothing in the RADIUS packet.");
|
||||||
throw new GuacamoleInvalidCredentialsException("Permission denied.", CredentialsInfo.USERNAME_PASSWORD);
|
throw new GuacamoleInvalidCredentialsException("Permission denied.", CredentialsInfo.USERNAME_PASSWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we get back an AccessReject packet, login is denied.
|
||||||
else if (radPack instanceof AccessReject) {
|
else if (radPack instanceof AccessReject) {
|
||||||
logger.debug("Login has been rejected by RADIUS server.");
|
logger.debug("Login has been rejected by RADIUS server.");
|
||||||
throw new GuacamoleInvalidCredentialsException("Permission denied.", CredentialsInfo.USERNAME_PASSWORD);
|
throw new GuacamoleInvalidCredentialsException("Permission denied.", CredentialsInfo.USERNAME_PASSWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If we receive an AccessChallenge package, the server needs more information -
|
||||||
|
* We create a new form/field with the challenge message.
|
||||||
|
*/
|
||||||
else if (radPack instanceof AccessChallenge) {
|
else if (radPack instanceof AccessChallenge) {
|
||||||
try {
|
try {
|
||||||
String replyMsg = radPack.getAttributeValue("Reply-Message").toString();
|
String replyMsg = radPack.getAttributeValue("Reply-Message").toString();
|
||||||
@@ -127,6 +134,8 @@ public class AuthenticationProviderService {
|
|||||||
throw new GuacamoleInvalidCredentialsException("Authentication error.", CredentialsInfo.USERNAME_PASSWORD);
|
throw new GuacamoleInvalidCredentialsException("Authentication error.", CredentialsInfo.USERNAME_PASSWORD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If we receive AccessAccept, authentication has succeeded
|
||||||
else if (radPack instanceof AccessAccept) {
|
else if (radPack instanceof AccessAccept) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
@@ -139,6 +148,8 @@ public class AuthenticationProviderService {
|
|||||||
radiusService.disconnect();
|
radiusService.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Something else we haven't thought of has happened, so we throw an error
|
||||||
else
|
else
|
||||||
throw new GuacamoleInvalidCredentialsException("Unknown error trying to authenticate.", CredentialsInfo.USERNAME_PASSWORD);
|
throw new GuacamoleInvalidCredentialsException("Unknown error trying to authenticate.", CredentialsInfo.USERNAME_PASSWORD);
|
||||||
|
|
||||||
|
@@ -128,6 +128,17 @@ public class ConfigurationService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the number of retries for connecting to the RADIUS server
|
||||||
|
* from guacamole.properties.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The number of retries for connection to the RADIUS server,
|
||||||
|
* from guacamole.properties.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If guacamole.properties cannot be parsed.
|
||||||
|
*/
|
||||||
public int getRadiusRetries() throws GuacamoleException {
|
public int getRadiusRetries() throws GuacamoleException {
|
||||||
return environment.getProperty(
|
return environment.getProperty(
|
||||||
RadiusGuacamoleProperties.RADIUS_RETRIES,
|
RadiusGuacamoleProperties.RADIUS_RETRIES,
|
||||||
@@ -135,6 +146,17 @@ public class ConfigurationService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the timeout for connecting to the RADIUS server
|
||||||
|
* from guacamole.properties.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* The timeout for connection to the RADIUS server,
|
||||||
|
* from guacamole.properties.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If guacamole.properties cannot be parsed.
|
||||||
|
*/
|
||||||
public int getRadiusTimeout() throws GuacamoleException {
|
public int getRadiusTimeout() throws GuacamoleException {
|
||||||
return environment.getProperty(
|
return environment.getProperty(
|
||||||
RadiusGuacamoleProperties.RADIUS_TIMEOUT,
|
RadiusGuacamoleProperties.RADIUS_TIMEOUT,
|
||||||
|
@@ -77,6 +77,7 @@ public class RadiusConnectionService {
|
|||||||
private void createRadiusConnection() {
|
private void createRadiusConnection() {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
* This is commented out right now because it isn't implemented, yet.
|
||||||
// Map encryption method to proper connection and socket factory
|
// Map encryption method to proper connection and socket factory
|
||||||
EncryptionMethod encryptionMethod = confService.getEncryptionMethod();
|
EncryptionMethod encryptionMethod = confService.getEncryptionMethod();
|
||||||
switch (encryptionMethod) {
|
switch (encryptionMethod) {
|
||||||
@@ -101,6 +102,8 @@ public class RadiusConnectionService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Create the RADIUS client with the configuration parameters
|
||||||
try {
|
try {
|
||||||
radiusClient = new RadiusClient(InetAddress.getByName(confService.getRadiusServer()),
|
radiusClient = new RadiusClient(InetAddress.getByName(confService.getRadiusServer()),
|
||||||
confService.getRadiusSharedSecret(),
|
confService.getRadiusSharedSecret(),
|
||||||
@@ -126,27 +129,50 @@ public class RadiusConnectionService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate to the RADIUS server and return the response from the
|
||||||
|
* server.
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* The username for authentication.
|
||||||
|
* @param password
|
||||||
|
* The password for authentication.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A RadiusPacket with the response of the server.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If an error occurs while talking to the server.
|
||||||
|
*/
|
||||||
public RadiusPacket authenticate(String username, String password)
|
public RadiusPacket authenticate(String username, String password)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
|
// Create the connection and load the attribute dictionary
|
||||||
createRadiusConnection();
|
createRadiusConnection();
|
||||||
AttributeFactory.loadAttributeDictionary("net.jradius.dictionary.AttributeDictionaryImpl");
|
AttributeFactory.loadAttributeDictionary("net.jradius.dictionary.AttributeDictionaryImpl");
|
||||||
|
|
||||||
|
// If the client is null, we return null - something has gone wrong
|
||||||
if (radiusClient == null)
|
if (radiusClient == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
// If a username hasn't been provided, stop
|
||||||
if (username == null || username.isEmpty()) {
|
if (username == null || username.isEmpty()) {
|
||||||
logger.warn("Anonymous access not allowed with RADIUS client.");
|
logger.warn("Anonymous access not allowed with RADIUS client.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a password hasn't been provided, stop
|
||||||
if (password == null || password.isEmpty()) {
|
if (password == null || password.isEmpty()) {
|
||||||
logger.warn("Password required for RADIUS authentication.");
|
logger.warn("Password required for RADIUS authentication.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up the authentication protocol as configured
|
||||||
RadiusAuthenticator radAuth = radiusClient.getAuthProtocol(confService.getRadiusAuthProtocol());
|
RadiusAuthenticator radAuth = radiusClient.getAuthProtocol(confService.getRadiusAuthProtocol());
|
||||||
if (radAuth == null)
|
if (radAuth == null)
|
||||||
throw new GuacamoleException("Unknown RADIUS authentication protocol.");
|
throw new GuacamoleException("Unknown RADIUS authentication protocol.");
|
||||||
|
|
||||||
|
// Set up attributes, create the access request, and send the packet
|
||||||
try {
|
try {
|
||||||
AttributeList radAttrs = new AttributeList();
|
AttributeList radAttrs = new AttributeList();
|
||||||
radAttrs.add(new Attr_UserName(username));
|
radAttrs.add(new Attr_UserName(username));
|
||||||
@@ -157,11 +183,13 @@ public class RadiusConnectionService {
|
|||||||
radAuth.processRequest(radAcc);
|
radAuth.processRequest(radAcc);
|
||||||
return radiusClient.sendReceive(radAcc, confService.getRadiusRetries());
|
return radiusClient.sendReceive(radAcc, confService.getRadiusRetries());
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (RadiusException e) {
|
catch (RadiusException e) {
|
||||||
logger.error("Unable to complete authentication.", e.getMessage());
|
logger.error("Unable to complete authentication.", e.getMessage());
|
||||||
logger.debug("Authentication with RADIUS failed.", e);
|
logger.debug("Authentication with RADIUS failed.", e);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (NoSuchAlgorithmException e) {
|
catch (NoSuchAlgorithmException e) {
|
||||||
logger.error("No such RADIUS algorithm: {}", e.getMessage());
|
logger.error("No such RADIUS algorithm: {}", e.getMessage());
|
||||||
logger.debug("Unknown RADIUS algorithm.", e);
|
logger.debug("Unknown RADIUS algorithm.", e);
|
||||||
@@ -169,28 +197,56 @@ public class RadiusConnectionService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate to the RADIUS server using existing state and a response
|
||||||
|
*
|
||||||
|
* @param username
|
||||||
|
* The username for the authentication
|
||||||
|
* @param state
|
||||||
|
* The previous state of the RADIUS connection
|
||||||
|
* @param response
|
||||||
|
* The response to the RADIUS challenge
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A RadiusPacket with the response of the server.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If an error occurs while talking to the server.
|
||||||
|
*/
|
||||||
public RadiusPacket authenticate(String username, String state, String response)
|
public RadiusPacket authenticate(String username, String state, String response)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
|
// Create the RADIUS connection and set up the dictionary
|
||||||
createRadiusConnection();
|
createRadiusConnection();
|
||||||
AttributeFactory.loadAttributeDictionary("net.jradius.dictionary.AttributeDictionaryImpl");
|
AttributeFactory.loadAttributeDictionary("net.jradius.dictionary.AttributeDictionaryImpl");
|
||||||
|
|
||||||
|
// Client failed to set up, so we return null
|
||||||
if (radiusClient == null)
|
if (radiusClient == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
// If a username wasn't passed, we quit
|
||||||
if (username == null || username.isEmpty()) {
|
if (username == null || username.isEmpty()) {
|
||||||
logger.warn("Anonymous access not allowed with RADIUS client.");
|
logger.warn("Anonymous access not allowed with RADIUS client.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the state wasn't passed, we quit
|
||||||
if (state == null || state.isEmpty()) {
|
if (state == null || state.isEmpty()) {
|
||||||
logger.warn("This method needs a previous RADIUS state to respond to.");
|
logger.warn("This method needs a previous RADIUS state to respond to.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the response wasn't passed, we quit
|
||||||
if (response == null || response.isEmpty()) {
|
if (response == null || response.isEmpty()) {
|
||||||
logger.warn("Response required for RADIUS authentication.");
|
logger.warn("Response required for RADIUS authentication.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up the authenticator based on the configured protocol.
|
||||||
|
* Unless that fails, add the attributes to the packet, set up the packet
|
||||||
|
* and send the packet.
|
||||||
|
*/
|
||||||
RadiusAuthenticator radAuth = radiusClient.getAuthProtocol(confService.getRadiusAuthProtocol());
|
RadiusAuthenticator radAuth = radiusClient.getAuthProtocol(confService.getRadiusAuthProtocol());
|
||||||
if (radAuth == null)
|
if (radAuth == null)
|
||||||
throw new GuacamoleException("Unknown RADIUS authentication protocol.");
|
throw new GuacamoleException("Unknown RADIUS authentication protocol.");
|
||||||
@@ -221,8 +277,6 @@ public class RadiusConnectionService {
|
|||||||
* Disconnects the given RADIUS connection, logging any failure to do so
|
* Disconnects the given RADIUS connection, logging any failure to do so
|
||||||
* appropriately.
|
* appropriately.
|
||||||
*
|
*
|
||||||
* @param radiusConnection
|
|
||||||
* The RADIUS connection to disconnect.
|
|
||||||
*/
|
*/
|
||||||
public void disconnect() {
|
public void disconnect() {
|
||||||
|
|
||||||
|
@@ -31,11 +31,29 @@ public class RadiusChallengeResponseField extends Field {
|
|||||||
*/
|
*/
|
||||||
private final Logger logger = LoggerFactory.getLogger(RadiusChallengeResponseField.class);
|
private final Logger logger = LoggerFactory.getLogger(RadiusChallengeResponseField.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The field returned by the RADIUS challenge/response.
|
||||||
|
*/
|
||||||
private static final String RADIUS_FIELD_NAME = "guac-radius-challenge-response";
|
private static final String RADIUS_FIELD_NAME = "guac-radius-challenge-response";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of field to initialize for the challenge/response.
|
||||||
|
*/
|
||||||
private static final String RADIUS_FIELD_TYPE = "GUAC_RADIUS_CHALLENGE_RESPONSE";
|
private static final String RADIUS_FIELD_TYPE = "GUAC_RADIUS_CHALLENGE_RESPONSE";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The state of the connection passed by the previous RADIUS attempt.
|
||||||
|
*/
|
||||||
private final String radiusState;
|
private final String radiusState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The message the RADIUS server sent back in the challenge.
|
||||||
|
*/
|
||||||
private final String replyMsg;
|
private final String replyMsg;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the field with the reply message and the state.
|
||||||
|
*/
|
||||||
public RadiusChallengeResponseField(String replyMsg, String radiusState) {
|
public RadiusChallengeResponseField(String replyMsg, String radiusState) {
|
||||||
super(RADIUS_FIELD_NAME, RADIUS_FIELD_TYPE);
|
super(RADIUS_FIELD_NAME, RADIUS_FIELD_TYPE);
|
||||||
logger.debug("Initializing the RADIUS challenge/response field: {}", replyMsg);
|
logger.debug("Initializing the RADIUS challenge/response field: {}", replyMsg);
|
||||||
|
Reference in New Issue
Block a user