diff --git a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/AuthenticationProviderService.java b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/AuthenticationProviderService.java index ae9f6bfd7..852eb7206 100644 --- a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/AuthenticationProviderService.java @@ -21,8 +21,11 @@ package org.apache.guacamole.auth.radius; import com.google.inject.Inject; import com.google.inject.Provider; +import java.lang.IllegalArgumentException; +import java.nio.charset.Charset; import java.util.Arrays; import javax.servlet.http.HttpServletRequest; +import javax.xml.bind.DatatypeConverter; import org.apache.guacamole.auth.radius.user.AuthenticatedUser; import org.apache.guacamole.auth.radius.form.RadiusChallengeResponseField; import org.apache.guacamole.auth.radius.form.RadiusStateField; @@ -97,7 +100,7 @@ public class AuthenticationProviderService { // We have the required attributes - convert to strings and then generate the additional login box/field String replyMsg = replyAttr.toString(); - String radiusState = new String(stateAttr.getValue().getBytes()); + String radiusState = DatatypeConverter.printHexBinary(stateAttr.getValue().getBytes()); Field radiusResponseField = new RadiusChallengeResponseField(replyMsg); Field radiusStateField = new RadiusStateField(radiusState); @@ -155,9 +158,21 @@ public class AuthenticationProviderService { // This is a response to a previous challenge, authenticate with that. else { try { + String stateString = request.getParameter(RadiusStateField.PARAMETER_NAME); + if (stateString == null) { + logger.warn("Expected state parameter was not present in challenge/response."); + throw new GuacamoleInvalidCredentialsException("Authentication error.", CredentialsInfo.USERNAME_PASSWORD); + } + + byte[] stateBytes = DatatypeConverter.parseHexBinary(stateString); radPack = radiusService.sendChallengeResponse(credentials.getUsername(), - challengeResponse, - request.getParameter(RadiusStateField.PARAMETER_NAME)); + challengeResponse, + stateBytes); + } + catch (IllegalArgumentException e) { + logger.warn("Illegal hexadecimal value while parsing RADIUS state string: {}", e.getMessage()); + logger.debug("Encountered exception while attempting to parse the hexidecimal state value.", e); + throw new GuacamoleInvalidCredentialsException("Authentication error.", CredentialsInfo.USERNAME_PASSWORD); } catch (GuacamoleException e) { logger.error("Cannot configure RADIUS server: {}", e.getMessage()); diff --git a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusConnectionService.java b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusConnectionService.java index 43c0b2d8a..ec82a63ee 100644 --- a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusConnectionService.java +++ b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusConnectionService.java @@ -187,7 +187,7 @@ public class RadiusConnectionService { * @throws GuacamoleException * If an error occurs while talking to the server. */ - public RadiusPacket authenticate(String username, String secret, String state) + public RadiusPacket authenticate(String username, String secret, byte[] state) throws GuacamoleException { // If a username wasn't passed, we quit @@ -219,7 +219,7 @@ public class RadiusConnectionService { try { AttributeList radAttrs = new AttributeList(); radAttrs.add(new Attr_UserName(username)); - if (state != null && !state.isEmpty()) + if (state != null && state.length > 0) radAttrs.add(new Attr_State(state)); radAttrs.add(new Attr_UserPassword(secret)); radAttrs.add(new Attr_CleartextPassword(secret)); @@ -282,7 +282,7 @@ public class RadiusConnectionService { * @throws GuacamoleException * If an error is encountered trying to talk to the RADIUS server. */ - public RadiusPacket sendChallengeResponse(String username, String response, String state) + public RadiusPacket sendChallengeResponse(String username, String response, byte[] state) throws GuacamoleException { if (username == null || username.isEmpty()) { @@ -290,7 +290,7 @@ public class RadiusConnectionService { return null; } - if (state == null || state.isEmpty()) { + if (state == null || state.length == 0) { logger.error("Challenge/response to RADIUS requires a prior state."); return null; }