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 171e41566..96a529cc6 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 @@ -29,6 +29,8 @@ import java.security.Provider; import java.security.Security; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleServerException; +import org.apache.guacamole.auth.radius.conf.ConfigurationService; +import org.apache.guacamole.auth.radius.conf.RadiusAuthenticationProtocol; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import net.jradius.client.RadiusClient; @@ -68,6 +70,27 @@ public class RadiusConnectionService { private ConfigurationService confService; + /** + * + */ + public RadiusConnectionService() { + + RadiusAuthenticationProtocol authProtocol = confService.getAuthenticationProtocol(); + + // Check for MS-CHAP and add MD4 support + if (authProtocol == RadiusAuthenticationProtocol.MSCHAPv1 + || authProtocol == RadiusAuthenticationProtocol.MSCHAPv2) { + + Security.addProvider(new Provider("MD4", 0.00, "MD4 for MSCHAPv1/2 RADIUS") { + { + this.put("MessageDigest.MD4", org.bouncycastle.jce.provider.JDKMessageDigest.MD4.class.getName()); + } + }); + + } + + } + /** * Creates a new instance of RadiusClient, configured with parameters * from guacamole.properties. @@ -129,22 +152,10 @@ public class RadiusConnectionService { return null; } - RadiusAuthenticator radAuth = radiusClient.getAuthProtocol(confService.getRadiusAuthProtocol()); + RadiusAuthenticator radAuth = radiusClient.getAuthProtocol(confService.getRadiusAuthProtocol().toString()); if (radAuth == null) throw new GuacamoleException("Could not get a valid RadiusAuthenticator for specified protocol: " + confService.getRadiusAuthProtocol()); - // For MSCHAPv1/2, we need MD4 support - if (radAuth instanceof MSCHAPv1Authenticator - || radAuth instanceof MSCHAPv2Authenticator) { - - Security.addProvider(new Provider("MD4", 0.00, "MD4 for MSCHAPv1/2 RADIUS") { - { - this.put("MessageDigest.MD4", org.bouncycastle.jce.provider.JDKMessageDigest.MD4.class.getName()); - } - }); - - } - // If we're using any of the TLS protocols, we need to configure them if (radAuth instanceof PEAPAuthenticator || radAuth instanceof EAPTLSAuthenticator || @@ -173,11 +184,11 @@ public class RadiusConnectionService { // If we're using EAP-TTLS, we need to define tunneled protocol if (radAuth instanceof EAPTTLSAuthenticator) { - String innerProtocol = confService.getRadiusEAPTTLSInnerProtocol(); + RadiusAuthenticationProtocol innerProtocol = confService.getRadiusEAPTTLSInnerProtocol(); if (innerProtocol == null) throw new GuacamoleException("Trying to use EAP-TTLS, but no inner protocol specified."); - ((EAPTTLSAuthenticator)radAuth).setInnerProtocol(innerProtocol); + ((EAPTTLSAuthenticator)radAuth).setInnerProtocol(innerProtocol.toString()); } return radAuth; diff --git a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/ConfigurationService.java b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/ConfigurationService.java similarity index 93% rename from extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/ConfigurationService.java rename to extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/ConfigurationService.java index 381ea13a5..0cdf344f9 100644 --- a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/ConfigurationService.java +++ b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/ConfigurationService.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.guacamole.auth.radius; +package org.apache.guacamole.auth.radius.conf; import com.google.inject.Inject; import java.io.File; @@ -123,8 +123,9 @@ public class ConfigurationService { * @throws GuacamoleException * If guacamole.properties cannot be parsed. */ - public String getRadiusAuthProtocol() throws GuacamoleException { - return environment.getProperty( + public RadiusAuthenticationProtocol getRadiusAuthProtocol() + throws GuacamoleException { + return environment.getRequiredProperty( RadiusGuacamoleProperties.RADIUS_AUTH_PROTOCOL ); } @@ -309,12 +310,19 @@ public class ConfigurationService { * an EAP-TTLS RADIUS connection. * * @throws GuacamoleException - * If guacamole.properties cannot be parsed. + * If guacamole.properties cannot be parsed, or if EAP-TTLS is specified + * as the inner protocol. */ - public String getRadiusEAPTTLSInnerProtocol() throws GuacamoleException { - return environment.getProperty( + public RadiusAuthenticationProtocol getRadiusEAPTTLSInnerProtocol() + throws GuacamoleException { + + RadiusAuthenticationProtocol authProtocol = environment.getProperty( RadiusGuacamoleProperties.RADIUS_EAP_TTLS_INNER_PROTOCOL ); + + if (authProtocol == RadiusAuthenticationProtocol.EAP_TTLS) + throw new GuacamoleServerException("Invalid inner protocol specified for EAP-TTLS."); + } } diff --git a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/RadiusAuthenticationProtocol.java b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/RadiusAuthenticationProtocol.java new file mode 100644 index 000000000..526be8020 --- /dev/null +++ b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/RadiusAuthenticationProtocol.java @@ -0,0 +1,64 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.apache.guacamole.auth.radius.conf; + +/** + * This enum represents supported RADIUS authentication protocols for + * the guacamole-auth-radius extension. + */ +public enum RadiusAuthenticationProtocol { + + // Password authentication protocol + PAP("pap"), + + // Challenge-Handshake AUthentication Protocol + CHAP("chap"), + + // Microsoft CHAP version 1 + MSCHAPv1("mschapv1"), + + // Microsoft CHAP version 2 + MSCHAPv2("mschapv2"), + + // Extensible authentication protocol with MD5 hashing. + EAP_MD5("eap-md5"), + + // Extensible authentication protocol with TLS + EAP_TLS("eap-tls"), + + // Extensible authentication protocol with Tunneled TLS + EAP_TTLS("eap-ttls"); + + // Store the string value used in the configuration file. + private final String strValue; + + /** + * Create a new RadiusAuthenticationProtocol object having the + * given string value. + * + * @param strValue + * The string value of the protocol. + */ + public RadiusAuthenticationProtocol(String strValue) { + this.strValue = strValue; + } + + @Override + public String toString() { + return strValue; + } + + @Override + public static RadiusAuthenticationProtocol valueOf(String value) { + + for (RadiusAuthenticationProtocol v : values()) + if(v.toString().equals(value)) + return v; + + return null; + } + +} diff --git a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/RadiusAuthenticationProtocolProperty.java b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/RadiusAuthenticationProtocolProperty.java new file mode 100644 index 000000000..7a5eaa39a --- /dev/null +++ b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/RadiusAuthenticationProtocolProperty.java @@ -0,0 +1,38 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.apache.guacamole.auth.radius.conf; + +import org.apache.guacamole.GuacamoleServerException; + +/** + * A GuacamoleProperty whose value is a RadiusAuthenticationProtocol. + */ +public abstract class RadiusAuthenticationProtocolProperty + implements GuacamoleProperty { + + @Override + public RadiusAuthenticationProtocol parseValue(String value) + throws GuacamoleException { + + // Nothing provided, nothing returned + if (value == null) + return null; + + // Attempt to parse the string value + RadiusAuthenticationProtocol authProtocol = + RadiusAuthenticationProtocol.valueOf(value); + + // Throw an exception if nothing matched. + if (authProtocol == null) + throw new GuacamoleServerException( + "Invalid or unsupported RADIUS authentication protocol."); + + // Return the answer + return authProtocol; + + } + +} diff --git a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusGuacamoleProperties.java b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/RadiusGuacamoleProperties.java similarity index 94% rename from extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusGuacamoleProperties.java rename to extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/RadiusGuacamoleProperties.java index aaa445eda..af6839b04 100644 --- a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusGuacamoleProperties.java +++ b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/RadiusGuacamoleProperties.java @@ -17,7 +17,7 @@ * under the License. */ -package org.apache.guacamole.auth.radius; +package org.apache.guacamole.auth.radius.conf; import org.apache.guacamole.properties.BooleanGuacamoleProperty; import org.apache.guacamole.properties.FileGuacamoleProperty; @@ -81,7 +81,8 @@ public class RadiusGuacamoleProperties { /** * The authentication protocol of the RADIUS server to connect to when authenticating users. */ - public static final StringGuacamoleProperty RADIUS_AUTH_PROTOCOL = new StringGuacamoleProperty() { + public static final RadiusAuthenticationProtocolProperty RADIUS_AUTH_PROTOCOL = + new RadiusAuthenticationProtocolProperty() { @Override public String getName() { return "radius-auth-protocol"; } @@ -181,7 +182,8 @@ public class RadiusGuacamoleProperties { /** * The tunneled protocol to use inside a RADIUS EAP-TTLS connection. */ - public static final StringGuacamoleProperty RADIUS_EAP_TTLS_INNER_PROTOCOL = new StringGuacamoleProperty() { + public static final RadiusAuthenticationProtocolProperty RADIUS_EAP_TTLS_INNER_PROTOCOL = + new RadiusAuthenticationProtocolProperty() { @Override public String getName() { return "radius-eap-ttls-inner-protocol"; }