From 7be25a326bb9c2fc7279519d3e34e99351d73e1e Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Tue, 9 Apr 2019 10:31:29 -0400 Subject: [PATCH 01/10] GUACAMOLE-774: Add in MD4 support for MSCHAPv1/2. --- .../auth/radius/RadiusConnectionService.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 ec82a63ee..171e41566 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 @@ -25,6 +25,8 @@ import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.NoSuchAlgorithmException; +import java.security.Provider; +import java.security.Security; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleServerException; import org.slf4j.Logger; @@ -41,6 +43,8 @@ import net.jradius.packet.AccessRequest; import net.jradius.packet.attribute.AttributeList; import net.jradius.client.auth.EAPTLSAuthenticator; import net.jradius.client.auth.EAPTTLSAuthenticator; +import net.jradius.client.auth.MSCHAPv1Authenticator; +import net.jradius.client.auth.MSCHAPv2Authenticator; import net.jradius.client.auth.RadiusAuthenticator; import net.jradius.client.auth.PEAPAuthenticator; import net.jradius.packet.attribute.AttributeFactory; @@ -129,6 +133,18 @@ public class RadiusConnectionService { 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 || From 93f17f159261fba47604bd4fb9f88a9c8f9e8793 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Tue, 9 Apr 2019 15:33:31 -0400 Subject: [PATCH 02/10] GUACAMOLE-774: Implement new enum for RADIUS authentication protocol. --- .../auth/radius/RadiusConnectionService.java | 41 +++++++----- .../{ => conf}/ConfigurationService.java | 20 ++++-- .../conf/RadiusAuthenticationProtocol.java | 64 +++++++++++++++++++ .../RadiusAuthenticationProtocolProperty.java | 38 +++++++++++ .../{ => conf}/RadiusGuacamoleProperties.java | 8 ++- 5 files changed, 147 insertions(+), 24 deletions(-) rename extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/{ => conf}/ConfigurationService.java (93%) create mode 100644 extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/RadiusAuthenticationProtocol.java create mode 100644 extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/RadiusAuthenticationProtocolProperty.java rename extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/{ => conf}/RadiusGuacamoleProperties.java (94%) 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"; } From 891efa446d2913e4b6044bb4a6c2b0caaefe86a4 Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Tue, 9 Apr 2019 15:36:33 -0400 Subject: [PATCH 03/10] GUACAMOLE-774: Add license to new files. --- .../conf/RadiusAuthenticationProtocol.java | 20 ++++++++++++++++--- .../RadiusAuthenticationProtocolProperty.java | 20 ++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) 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 index 526be8020..51eb87c32 100644 --- 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 @@ -1,8 +1,22 @@ /* - * 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. + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ + package org.apache.guacamole.auth.radius.conf; /** 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 index 7a5eaa39a..cc8d8277a 100644 --- 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 @@ -1,8 +1,22 @@ /* - * 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. + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. */ + package org.apache.guacamole.auth.radius.conf; import org.apache.guacamole.GuacamoleServerException; From 73388e4fd2298ba12445fd7136fdd3665d722d3c Mon Sep 17 00:00:00 2001 From: Nick Couchman Date: Tue, 9 Apr 2019 15:42:00 -0400 Subject: [PATCH 04/10] GUACAMOLE-774: Fix include and syntax errors. --- .../auth/radius/conf/RadiusAuthenticationProtocol.java | 5 ++--- .../radius/conf/RadiusAuthenticationProtocolProperty.java | 3 ++- 2 files changed, 4 insertions(+), 4 deletions(-) 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 index 51eb87c32..d5a33fc98 100644 --- 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 @@ -56,7 +56,7 @@ public enum RadiusAuthenticationProtocol { * @param strValue * The string value of the protocol. */ - public RadiusAuthenticationProtocol(String strValue) { + RadiusAuthenticationProtocol(String strValue) { this.strValue = strValue; } @@ -65,8 +65,7 @@ public enum RadiusAuthenticationProtocol { return strValue; } - @Override - public static RadiusAuthenticationProtocol valueOf(String value) { + public static RadiusAuthenticationProtocol getEnum(String value) { for (RadiusAuthenticationProtocol v : values()) if(v.toString().equals(value)) 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 index cc8d8277a..6fbfc2198 100644 --- 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 @@ -19,6 +19,7 @@ package org.apache.guacamole.auth.radius.conf; +import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleServerException; /** @@ -37,7 +38,7 @@ public abstract class RadiusAuthenticationProtocolProperty // Attempt to parse the string value RadiusAuthenticationProtocol authProtocol = - RadiusAuthenticationProtocol.valueOf(value); + RadiusAuthenticationProtocol.getEnum(value); // Throw an exception if nothing matched. if (authProtocol == null) From 10e29288b03212fb45cfe5a88e29280bacc4b4ba Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Wed, 17 Apr 2019 16:36:06 -0400 Subject: [PATCH 05/10] GUACAMOLE-774: Clean up style and comments, improve readability. --- .../RadiusAuthenticationProviderModule.java | 1 + .../auth/radius/RadiusConnectionService.java | 46 +++++++++++++------ .../radius/conf/ConfigurationService.java | 3 ++ .../RadiusAuthenticationProtocolProperty.java | 1 + 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java index 37ecb79fd..24acd3539 100644 --- a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java @@ -21,6 +21,7 @@ package org.apache.guacamole.auth.radius; import com.google.inject.AbstractModule; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.radius.conf.ConfigurationService; import org.apache.guacamole.environment.Environment; import org.apache.guacamole.environment.LocalEnvironment; import org.apache.guacamole.net.auth.AuthenticationProvider; 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 96a529cc6..15d183545 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 @@ -45,8 +45,6 @@ import net.jradius.packet.AccessRequest; import net.jradius.packet.attribute.AttributeList; import net.jradius.client.auth.EAPTLSAuthenticator; import net.jradius.client.auth.EAPTTLSAuthenticator; -import net.jradius.client.auth.MSCHAPv1Authenticator; -import net.jradius.client.auth.MSCHAPv2Authenticator; import net.jradius.client.auth.RadiusAuthenticator; import net.jradius.client.auth.PEAPAuthenticator; import net.jradius.packet.attribute.AttributeFactory; @@ -71,11 +69,17 @@ public class RadiusConnectionService { /** + * Set up a new instance of this class, and check the provided + * authentication protocol. If the protocol requires MD4 support, + * this loads the required security providers. * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed or an invalid + * authentication protocol is provided. */ - public RadiusConnectionService() { + public RadiusConnectionService() throws GuacamoleException { - RadiusAuthenticationProtocol authProtocol = confService.getAuthenticationProtocol(); + RadiusAuthenticationProtocol authProtocol = confService.getRadiusAuthProtocol(); // Check for MS-CHAP and add MD4 support if (authProtocol == RadiusAuthenticationProtocol.MSCHAPv1 @@ -83,7 +87,8 @@ public class RadiusConnectionService { Security.addProvider(new Provider("MD4", 0.00, "MD4 for MSCHAPv1/2 RADIUS") { { - this.put("MessageDigest.MD4", org.bouncycastle.jce.provider.JDKMessageDigest.MD4.class.getName()); + this.put("MessageDigest.MD4", + org.bouncycastle.jce.provider.JDKMessageDigest.MD4.class.getName()); } }); @@ -142,8 +147,8 @@ public class RadiusConnectionService { * not configured when the client is set up for a tunneled * RADIUS connection. */ - private RadiusAuthenticator setupRadiusAuthenticator(RadiusClient radiusClient) - throws GuacamoleException { + private RadiusAuthenticator setupRadiusAuthenticator( + RadiusClient radiusClient) throws GuacamoleException { // If we don't have a radiusClient object, yet, don't go any further. if (radiusClient == null) { @@ -152,7 +157,9 @@ public class RadiusConnectionService { return null; } - RadiusAuthenticator radAuth = radiusClient.getAuthProtocol(confService.getRadiusAuthProtocol().toString()); + RadiusAuthenticator radAuth = radiusClient.getAuthProtocol( + confService.getRadiusAuthProtocol().toString()); + if (radAuth == null) throw new GuacamoleException("Could not get a valid RadiusAuthenticator for specified protocol: " + confService.getRadiusAuthProtocol()); @@ -184,9 +191,11 @@ public class RadiusConnectionService { // If we're using EAP-TTLS, we need to define tunneled protocol if (radAuth instanceof EAPTTLSAuthenticator) { - RadiusAuthenticationProtocol innerProtocol = confService.getRadiusEAPTTLSInnerProtocol(); + RadiusAuthenticationProtocol innerProtocol = + confService.getRadiusEAPTTLSInnerProtocol(); + if (innerProtocol == null) - throw new GuacamoleException("Trying to use EAP-TTLS, but no inner protocol specified."); + throw new GuacamoleException("Missing or invalid inner protocol for EAP-TTLS."); ((EAPTTLSAuthenticator)radAuth).setInnerProtocol(innerProtocol.toString()); } @@ -263,14 +272,21 @@ public class RadiusConnectionService { radAuth.setupRequest(radiusClient, radAcc); radAuth.processRequest(radAcc); - RadiusResponse reply = radiusClient.sendReceive(radAcc, confService.getRadiusMaxRetries()); + RadiusResponse reply = radiusClient.sendReceive(radAcc, + confService.getRadiusMaxRetries()); // We receive a Challenge not asking for user input, so silently process the challenge - while((reply instanceof AccessChallenge) && (reply.findAttribute(Attr_ReplyMessage.TYPE) == null)) { + while((reply instanceof AccessChallenge) + && (reply.findAttribute(Attr_ReplyMessage.TYPE) == null)) { + radAuth.processChallenge(radAcc, reply); - reply = radiusClient.sendReceive(radAcc, confService.getRadiusMaxRetries()); + reply = radiusClient.sendReceive(radAcc, + confService.getRadiusMaxRetries()); + } + return reply; + } catch (RadiusException e) { logger.error("Unable to complete authentication.", e.getMessage()); @@ -309,8 +325,8 @@ public class RadiusConnectionService { * @throws GuacamoleException * If an error is encountered trying to talk to the RADIUS server. */ - public RadiusPacket sendChallengeResponse(String username, String response, byte[] state) - throws GuacamoleException { + public RadiusPacket sendChallengeResponse(String username, String response, + byte[] state) throws GuacamoleException { if (username == null || username.isEmpty()) { logger.error("Challenge/response to RADIUS requires a username."); diff --git a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/ConfigurationService.java b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/ConfigurationService.java index 0cdf344f9..2809f7c76 100644 --- a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/ConfigurationService.java +++ b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/conf/ConfigurationService.java @@ -22,6 +22,7 @@ package org.apache.guacamole.auth.radius.conf; import com.google.inject.Inject; import java.io.File; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.GuacamoleServerException; import org.apache.guacamole.environment.Environment; /** @@ -323,6 +324,8 @@ public class ConfigurationService { if (authProtocol == RadiusAuthenticationProtocol.EAP_TTLS) throw new GuacamoleServerException("Invalid inner protocol specified for EAP-TTLS."); + return authProtocol; + } } 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 index 6fbfc2198..c92c0a3ed 100644 --- 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 @@ -21,6 +21,7 @@ package org.apache.guacamole.auth.radius.conf; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleServerException; +import org.apache.guacamole.properties.GuacamoleProperty; /** * A GuacamoleProperty whose value is a RadiusAuthenticationProtocol. From a97e1113c3521672efd54a9c373fec1a768bb0bc Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Wed, 17 Apr 2019 16:48:51 -0400 Subject: [PATCH 06/10] GUACAMOLE-774: Fix RadiusConnectionservice class initilization for use with Guice. --- .../auth/radius/RadiusConnectionService.java | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) 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 15d183545..5e1c55c2a 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 @@ -72,26 +72,27 @@ public class RadiusConnectionService { * Set up a new instance of this class, and check the provided * authentication protocol. If the protocol requires MD4 support, * this loads the required security providers. - * - * @throws GuacamoleException - * If guacamole.properties cannot be parsed or an invalid - * authentication protocol is provided. */ - public RadiusConnectionService() throws GuacamoleException { + public RadiusConnectionService() { - RadiusAuthenticationProtocol authProtocol = confService.getRadiusAuthProtocol(); + try { + RadiusAuthenticationProtocol authProtocol = confService.getRadiusAuthProtocol(); - // 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()); - } - }); - + // 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()); + } + }); + + } + } catch(GuacamoleException e) { + logger.error("Could not retrieve RADIUS authentication protocol: {}", e.getMessage()); + logger.debug("Failed to determine authentication protocol", e); } } From 931bb6f1f9c69578e54084ecc8805e3bb117484c Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Wed, 17 Apr 2019 17:51:33 -0400 Subject: [PATCH 07/10] GUACAMOLE-774: Remove RadiusConnectionService constructor. --- .../auth/radius/RadiusConnectionService.java | 32 ------------------- 1 file changed, 32 deletions(-) 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 5e1c55c2a..c8a21d6a1 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 @@ -25,8 +25,6 @@ import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.NoSuchAlgorithmException; -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; @@ -66,36 +64,6 @@ public class RadiusConnectionService { */ @Inject private ConfigurationService confService; - - - /** - * Set up a new instance of this class, and check the provided - * authentication protocol. If the protocol requires MD4 support, - * this loads the required security providers. - */ - public RadiusConnectionService() { - - try { - RadiusAuthenticationProtocol authProtocol = confService.getRadiusAuthProtocol(); - - // 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()); - } - }); - - } - } catch(GuacamoleException e) { - logger.error("Could not retrieve RADIUS authentication protocol: {}", e.getMessage()); - logger.debug("Failed to determine authentication protocol", e); - } - - } /** * Creates a new instance of RadiusClient, configured with parameters From e09d8e0e8767a5a601dfe876f0931c1ac38c9102 Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Wed, 17 Apr 2019 18:40:31 -0400 Subject: [PATCH 08/10] GUACAMOLE-774: Add MD4 checks to Guice module loading. --- .../RadiusAuthenticationProviderModule.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java index 24acd3539..842ce8b52 100644 --- a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java @@ -20,8 +20,12 @@ package org.apache.guacamole.auth.radius; import com.google.inject.AbstractModule; +import java.security.Provider; +import java.security.Security; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.auth.radius.conf.ConfigurationService; +import org.apache.guacamole.auth.radius.conf.RadiusAuthenticationProtocol; +import org.apache.guacamole.auth.radius.conf.RadiusGuacamoleProperties; import org.apache.guacamole.environment.Environment; import org.apache.guacamole.environment.LocalEnvironment; import org.apache.guacamole.net.auth.AuthenticationProvider; @@ -58,6 +62,24 @@ public class RadiusAuthenticationProviderModule extends AbstractModule { // Get local environment this.environment = new LocalEnvironment(); + + // Check for MD4 requirement + RadiusAuthenticationProtocol authProtocol = environment.getProperty(RadiusGuacamoleProperties.RADIUS_AUTH_PROTOCOL); + RadiusAuthenticationProtocol innerProtocol = environment.getProperty(RadiusGuacamoleProperties.RADIUS_EAP_TTLS_INNER_PROTOCOL); + if ((authProtocol != null + && (authProtocol == RadiusAuthenticationProtocol.MSCHAPv1 + || authProtocol == RadiusAuthenticationProtocol.MSCHAPv2)) + || (innerProtocol != null + && (innerProtocol == RadiusAuthenticationProtocol.MSCHAPv1 + || innerProtocol == RadiusAuthenticationProtocol.MSCHAPv2))) { + + Security.addProvider(new Provider("MD4", 0.00, "MD4 for MSCHAPv1/2 Support") { + { + this.put("MessageDigest.MD4", org.bouncycastle.jce.provider.JDKMessageDigest.MD4.class.getName()); + } + }); + + } // Store associated auth provider this.authProvider = authProvider; From c7b21b8812a4ed6b404c9d7917cef1d27b91231b Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Wed, 24 Apr 2019 21:30:23 -0400 Subject: [PATCH 09/10] GUACAMOLE-774: Fix documentation in RadiusAuthenticationProtocol enum. --- .../conf/RadiusAuthenticationProtocol.java | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) 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 index d5a33fc98..e64a69584 100644 --- 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 @@ -25,28 +25,46 @@ package org.apache.guacamole.auth.radius.conf; */ public enum RadiusAuthenticationProtocol { - // Password authentication protocol + /** + * Password Authentication Protocol (PAP) + */ PAP("pap"), - // Challenge-Handshake AUthentication Protocol + /** + * Challenge-Handshake Authentication Protocol (CHAP) + */ CHAP("chap"), - // Microsoft CHAP version 1 + /** + * Microsoft implementation of CHAP, Version 1 (MS-CHAPv1) + */ MSCHAPv1("mschapv1"), - // Microsoft CHAP version 2 + /** + * Microsoft implementation of CHAP, Version 2 (MS-CHAPv2) + */ MSCHAPv2("mschapv2"), - // Extensible authentication protocol with MD5 hashing. + /** + * Extensible Authentication Protocol (EAP) with MD5 Hashing (EAP-MD5) + */ EAP_MD5("eap-md5"), - // Extensible authentication protocol with TLS + /** + * Extensible Authentication Protocol (EAP) with TLS encryption (EAP-TLS). + */ EAP_TLS("eap-tls"), - // Extensible authentication protocol with Tunneled TLS + /** + * Extensible Authentication Protocol (EAP) with Tunneled TLS (EAP-TTLS). + */ EAP_TTLS("eap-ttls"); - // Store the string value used in the configuration file. + /** + * This variable stores the string value of the protocol, and is also + * used within the extension to pass to JRadius for configuring the + * library to talk to the RADIUS server. + */ private final String strValue; /** @@ -54,17 +72,40 @@ public enum RadiusAuthenticationProtocol { * given string value. * * @param strValue - * The string value of the protocol. + * The value of the protocol to store as a string, which will be used + * in specifying the protocol within the guacamole.properties file, and + * will also be used by the JRadius library for its configuration. */ RadiusAuthenticationProtocol(String strValue) { this.strValue = strValue; } + /** + * {@inheritDoc} + *

+ * This function returns the stored string values of the selected RADIUS + * protocol, which is used both in Guacamole configuration and also to pass + * on to the JRadius library for its configuration. + * + * @return + * The string value stored for the selected RADIUS protocol. + */ @Override public String toString() { return strValue; } + /** + * For a given String value, return the enum value that matches that string, + * or null if no matchi is found. + * + * @param value + * The string value to search for in the list of enums. + * + * @return + * The RadiusAuthenticationProtocol value that is identified by the + * provided String value. + */ public static RadiusAuthenticationProtocol getEnum(String value) { for (RadiusAuthenticationProtocol v : values()) From e5fab49d75c19df2a4a991f21d7d0cc65ac701cd Mon Sep 17 00:00:00 2001 From: Virtually Nick Date: Mon, 12 Aug 2019 20:13:37 -0400 Subject: [PATCH 10/10] GUACAMOLE-774: Remove unnecessary null checks. --- .../radius/RadiusAuthenticationProviderModule.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java index 842ce8b52..d34b0b344 100644 --- a/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java +++ b/extensions/guacamole-auth-radius/src/main/java/org/apache/guacamole/auth/radius/RadiusAuthenticationProviderModule.java @@ -66,12 +66,10 @@ public class RadiusAuthenticationProviderModule extends AbstractModule { // Check for MD4 requirement RadiusAuthenticationProtocol authProtocol = environment.getProperty(RadiusGuacamoleProperties.RADIUS_AUTH_PROTOCOL); RadiusAuthenticationProtocol innerProtocol = environment.getProperty(RadiusGuacamoleProperties.RADIUS_EAP_TTLS_INNER_PROTOCOL); - if ((authProtocol != null - && (authProtocol == RadiusAuthenticationProtocol.MSCHAPv1 - || authProtocol == RadiusAuthenticationProtocol.MSCHAPv2)) - || (innerProtocol != null - && (innerProtocol == RadiusAuthenticationProtocol.MSCHAPv1 - || innerProtocol == RadiusAuthenticationProtocol.MSCHAPv2))) { + if (authProtocol == RadiusAuthenticationProtocol.MSCHAPv1 + || authProtocol == RadiusAuthenticationProtocol.MSCHAPv2 + || innerProtocol == RadiusAuthenticationProtocol.MSCHAPv1 + || innerProtocol == RadiusAuthenticationProtocol.MSCHAPv2) { Security.addProvider(new Provider("MD4", 0.00, "MD4 for MSCHAPv1/2 Support") { {