GUACAMOLE-197: Collapse authenticate methods together into single method, add minimal method for challenge/response.

This commit is contained in:
Nick Couchman
2017-07-16 14:25:55 -04:00
parent 84276af007
commit fa820cb46f
2 changed files with 34 additions and 102 deletions

View File

@@ -153,7 +153,7 @@ public class AuthenticationProviderService {
try { try {
radPack = radiusService.authenticate(credentials.getUsername(), radPack = radiusService.authenticate(credentials.getUsername(),
credentials.getPassword()); credentials.getPassword(), null);
} }
catch (GuacamoleException e) { catch (GuacamoleException e) {
logger.error("Cannot configure RADIUS server: {}", e.getMessage()); logger.error("Cannot configure RADIUS server: {}", e.getMessage());
@@ -168,9 +168,9 @@ public class AuthenticationProviderService {
// This is a response to a previous challenge, authenticate with that. // This is a response to a previous challenge, authenticate with that.
else { else {
try { try {
radPack = radiusService.authenticate(credentials.getUsername(), radPack = radiusService.sendChallengeResponse(credentials.getUsername(),
request.getParameter(RadiusStateField.PARAMETER_NAME), challengeResponse,
challengeResponse); request.getParameter(RadiusStateField.PARAMETER_NAME));
} }
catch (GuacamoleException e) { catch (GuacamoleException e) {
logger.error("Cannot configure RADIUS server: {}", e.getMessage()); logger.error("Cannot configure RADIUS server: {}", e.getMessage());

View File

@@ -164,91 +164,6 @@ 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)
throws GuacamoleException {
// If a username hasn't been provided, stop
if (username == null || username.isEmpty()) {
logger.warn("Anonymous access not allowed with RADIUS client.");
return null;
}
// If a password hasn't been provided, stop
if (password == null || password.isEmpty()) {
logger.warn("Password required for RADIUS authentication.");
return null;
}
// Create the connection and load the attribute dictionary
createRadiusConnection();
AttributeFactory.loadAttributeDictionary("net.jradius.dictionary.AttributeDictionaryImpl");
// If the client is null, we return null - something has gone wrong
if (radiusClient == null)
return null;
RadiusAuthenticator radAuth = setupRadiusAuthenticator();
if (radAuth == null)
throw new GuacamoleException("Unknown RADIUS authentication protocol.");
// Set up attributes, create the access request, and send the packet
try {
AttributeList radAttrs = new AttributeList();
radAttrs.add(new Attr_UserName(username));
radAttrs.add(new Attr_UserPassword(password));
radAttrs.add(new Attr_CleartextPassword(password));
AccessRequest radAcc = new AccessRequest(radiusClient);
// EAP-TTLS tunnels protected attributes inside the TLS layer
if (radAuth instanceof EAPTTLSAuthenticator) {
radAuth.setUsername(new Attr_UserName(username));
((EAPTTLSAuthenticator)radAuth).setTunneledAttributes(radAttrs);
}
else
radAcc.addAttributes(radAttrs);
radAuth.setupRequest(radiusClient, radAcc);
radAuth.processRequest(radAcc);
RadiusResponse reply = radiusClient.sendReceive(radAcc, confService.getRadiusRetries());
// We receive a Challenge not asking for user input, so silently process the challenge
while((reply instanceof AccessChallenge) && (reply.findAttribute(Attr_ReplyMessage.TYPE) == null)) {
radAuth.processChallenge(radAcc, reply);
reply = radiusClient.sendReceive(radAcc, confService.getRadiusRetries());
}
return reply;
}
catch (RadiusException e) {
logger.error("Unable to complete authentication.", e.getMessage());
logger.debug("Authentication with RADIUS failed.", e);
return null;
}
catch (NoSuchAlgorithmException e) {
logger.error("No such RADIUS algorithm: {}", e.getMessage());
logger.debug("Unknown RADIUS algorithm.", e);
return null;
}
}
/** /**
* Authenticate to the RADIUS server using existing state and a response * Authenticate to the RADIUS server using existing state and a response
* *
@@ -265,7 +180,7 @@ public class RadiusConnectionService {
* @throws GuacamoleException * @throws GuacamoleException
* If an error occurs while talking to the server. * If an error occurs while talking to the server.
*/ */
public RadiusPacket authenticate(String username, String state, String response) public RadiusPacket authenticate(String username, String secret, String state)
throws GuacamoleException { throws GuacamoleException {
// If a username wasn't passed, we quit // If a username wasn't passed, we quit
@@ -274,15 +189,9 @@ public class RadiusConnectionService {
return null; return null;
} }
// If the state wasn't passed, we quit // If secret wasn't passed, we quit
if (state == null || state.isEmpty()) { if (secret == null || secret.isEmpty()) {
logger.warn("This method needs a previous RADIUS state to respond to."); logger.warn("Password/secret required for RADIUS authentication.");
return null;
}
// If the response wasn't passed, we quit
if (response == null || response.isEmpty()) {
logger.warn("Response required for RADIUS authentication.");
return null; return null;
} }
@@ -303,9 +212,10 @@ public class RadiusConnectionService {
try { try {
AttributeList radAttrs = new AttributeList(); AttributeList radAttrs = new AttributeList();
radAttrs.add(new Attr_UserName(username)); radAttrs.add(new Attr_UserName(username));
radAttrs.add(new Attr_State(state)); if (state != null && !state.isEmpty())
radAttrs.add(new Attr_UserPassword(response)); radAttrs.add(new Attr_State(state));
radAttrs.add(new Attr_CleartextPassword(response)); radAttrs.add(new Attr_UserPassword(secret));
radAttrs.add(new Attr_CleartextPassword(secret));
AccessRequest radAcc = new AccessRequest(radiusClient); AccessRequest radAcc = new AccessRequest(radiusClient);
@@ -340,6 +250,28 @@ public class RadiusConnectionService {
} }
} }
public RadiusPacket sendChallengeResponse(String username, String response, String state)
throws GuacamoleException {
if (username == null || username.isEmpty()) {
logger.error("Challenge/response to RADIUS requires a username.");
return null;
}
if (state == null || state.isEmpty()) {
logger.error("Challenge/response to RADIUS requires a prior state.");
return null;
}
if (response == null || response.isEmpty()) {
logger.error("Challenge/response to RADIUS requires a response.");
return null;
}
return authenticate(username,response,state);
}
/** /**
* Disconnects the current RADIUS connection. * Disconnects the current RADIUS connection.
*/ */