diff --git a/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/RestrictionAuthenticationProvider.java b/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/RestrictionAuthenticationProvider.java index ec6236432..570aa9c9c 100644 --- a/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/RestrictionAuthenticationProvider.java +++ b/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/RestrictionAuthenticationProvider.java @@ -19,12 +19,19 @@ package org.apache.guacamole.auth.restrict; +import com.google.inject.Guice; +import com.google.inject.Injector; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.restrict.conf.ConfigurationService; import org.apache.guacamole.auth.restrict.user.RestrictedUserContext; import org.apache.guacamole.net.auth.AbstractAuthenticationProvider; import org.apache.guacamole.net.auth.AuthenticatedUser; import org.apache.guacamole.net.auth.Credentials; +import org.apache.guacamole.net.auth.User; import org.apache.guacamole.net.auth.UserContext; +import org.apache.guacamole.net.auth.permission.SystemPermission; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * AuthenticationProvider implementation which provides additional restrictions @@ -33,6 +40,32 @@ import org.apache.guacamole.net.auth.UserContext; */ public class RestrictionAuthenticationProvider extends AbstractAuthenticationProvider { + /** + * Logger for this class. + */ + private static final Logger LOGGER = LoggerFactory.getLogger(RestrictionAuthenticationProvider.class); + + /** + * Injector which will manage the object graph of this authentication + * provider. + */ + private final Injector injector; + + /** + * Create a new instance of the Restriction authentication provider, + * setting up the Guice injector for dependency management. + * + * @throws GuacamoleException + * If an error occurs configuring the Guice injector. + */ + public RestrictionAuthenticationProvider() throws GuacamoleException { + + // Set up Guice injector. + injector = Guice.createInjector( + new RestrictionAuthenticationProviderModule(this) + ); + } + @Override public String getIdentifier() { return "restrict"; @@ -43,11 +76,38 @@ public class RestrictionAuthenticationProvider extends AbstractAuthenticationPro AuthenticatedUser authenticatedUser, Credentials credentials) throws GuacamoleException { - String remoteAddress = credentials.getRemoteAddress(); + ConfigurationService confService = injector.getInstance(ConfigurationService.class); - // Verify identity of user - RestrictionVerificationService.verifyLoginRestrictions(context, - authenticatedUser.getEffectiveUserGroups(), remoteAddress); + String remoteAddress = credentials.getRemoteAddress(); + User currentUser = context.self(); + boolean isAdmin = currentUser + .getEffectivePermissions() + .getSystemPermissions() + .hasPermission(SystemPermission.Type.ADMINISTER); + boolean restrictAdmins = confService.getRestrictAdminAccounts(); + + // User is admin and restrictions do not apply, log warning. + if (isAdmin && !restrictAdmins) { + LOGGER.warn("Bypassing restrictions for administrator \"{}\"", + currentUser.getIdentifier()); + } + + // User is not an admin, or restrictions do apply to admins + else { + if (isAdmin) { + LOGGER.warn("User \"{}\" is an administrator, but system is " + + "configured to enforce login restrictions on " + + "administrators.", + currentUser.getIdentifier()); + } + else { + LOGGER.debug("User \"{}\" is not an administrator, enforcing" + + "login restrictions.", currentUser.getIdentifier()); + } + RestrictionVerificationService.verifyLoginRestrictions(context, + authenticatedUser.getEffectiveUserGroups(), remoteAddress); + + } // User has been verified, and authentication should be allowed to // continue diff --git a/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/RestrictionAuthenticationProviderModule.java b/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/RestrictionAuthenticationProviderModule.java new file mode 100644 index 000000000..c6f5bbd4b --- /dev/null +++ b/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/RestrictionAuthenticationProviderModule.java @@ -0,0 +1,76 @@ +/* + * 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.restrict; + +import com.google.inject.AbstractModule; +import org.apache.guacamole.auth.restrict.conf.ConfigurationService; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.environment.Environment; +import org.apache.guacamole.environment.LocalEnvironment; +import org.apache.guacamole.net.auth.AuthenticationProvider; + +/** + * Guice module which configures Restriction-specific injections. + */ +public class RestrictionAuthenticationProviderModule extends AbstractModule { + /** + * Guacamole server environment. + */ + private final Environment environment; + + /** + * A reference to the RestrictionAuthenticationProvider on behalf of which + * this module has configured injection. + */ + private final AuthenticationProvider authProvider; + + /** + * Creates a new Restriction authentication provider module which + * configures injection for the RestrictionAuthenticationProvider. + * + * @param authProvider + * The AuthenticationProvider for which injection is being configured. + * + * @throws GuacamoleException + * If an error occurs while retrieving the Guacamole server + * environment. + */ + public RestrictionAuthenticationProviderModule( + AuthenticationProvider authProvider) throws GuacamoleException { + + // Get local environment + this.environment = LocalEnvironment.getInstance(); + + // Store associated auth provider + this.authProvider = authProvider; + + } + + @Override + protected void configure() { + + // Bind core implementations of guacamole-ext classes + bind(AuthenticationProvider.class).toInstance(authProvider); + bind(Environment.class).toInstance(environment); + + // Bind Restriction-specific services + bind(ConfigurationService.class); + + } +} diff --git a/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/RestrictionVerificationService.java b/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/RestrictionVerificationService.java index ae209360f..d17cd5376 100644 --- a/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/RestrictionVerificationService.java +++ b/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/RestrictionVerificationService.java @@ -39,7 +39,6 @@ import org.apache.guacamole.language.TranslatableGuacamoleSecurityException; import org.apache.guacamole.net.auth.User; import org.apache.guacamole.net.auth.UserContext; import org.apache.guacamole.net.auth.UserGroup; -import org.apache.guacamole.net.auth.permission.SystemPermission; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -301,13 +300,6 @@ public class RestrictionVerificationService { // Get the current user User currentUser = context.self(); - // Admins always have access. - if (currentUser.getEffectivePermissions().getSystemPermissions().hasPermission(SystemPermission.Type.ADMINISTER)) { - LOGGER.warn("User \"{}\" has System Administration permissions; additional restrictions will be bypassed.", - currentUser.getIdentifier()); - return; - } - // Get user's attributes Map userAttributes = currentUser.getAttributes(); @@ -443,13 +435,6 @@ public class RestrictionVerificationService { // Retrieve the current User object associated with the UserContext User currentUser = context.self(); - // Admins always have access. - if (currentUser.getEffectivePermissions().getSystemPermissions().hasPermission(SystemPermission.Type.ADMINISTER)) { - LOGGER.warn("User \"{}\" has System Administration permissions; additional restrictions will be bypassed.", - currentUser.getIdentifier()); - return; - } - // Get user's attributes Map userAttributes = currentUser.getAttributes(); diff --git a/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/conf/ConfigurationService.java b/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/conf/ConfigurationService.java new file mode 100644 index 000000000..8778da56b --- /dev/null +++ b/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/conf/ConfigurationService.java @@ -0,0 +1,58 @@ +/* + * 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.restrict.conf; + +import com.google.inject.Inject; +import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.environment.Environment; + +/** + * A service for accessing the Guacamaole configuration in order to read + * properties from the guacamole.properties file. + */ +public class ConfigurationService { + + /** + * The environment of the Guacamole Server. + */ + @Inject + private Environment environment; + + /** + * Return true if login restrictions implemented by this extension should + * apply to system admin accounts in addition to non-administrative users, + * or false if administrative accounts should be exempt from those + * restrictions. This will return false by default, exempting system + * administrators from login restrictions imposed by this extension. + * + * @return + * true if login restrictions should apply to Guacamole system + * administrative accounts, otherwise false. + * + * @throws GuacamoleException + * If guacamole.properties cannot be parsed. + */ + public boolean getRestrictAdminAccounts() throws GuacamoleException { + return environment.getProperty( + RestrictionProperties.RESTRICT_ADMIN_ACCOUNTS, + false + ); + } + +} diff --git a/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/conf/RestrictionProperties.java b/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/conf/RestrictionProperties.java new file mode 100644 index 000000000..a3b28eaf2 --- /dev/null +++ b/extensions/guacamole-auth-restrict/src/main/java/org/apache/guacamole/auth/restrict/conf/RestrictionProperties.java @@ -0,0 +1,41 @@ +/* + * 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.restrict.conf; + +import org.apache.guacamole.properties.BooleanGuacamoleProperty; + +/** + * A class that implements the various properties that this module can + * leverage from guacamole.properties. + */ +public class RestrictionProperties { + + /** + * A property that allows for configuring whether or not Guacamole applies + * the restrictions to admin accounts. By default, login restrictions do + * NOT apply to admin accounts. + */ + public static final BooleanGuacamoleProperty RESTRICT_ADMIN_ACCOUNTS = new BooleanGuacamoleProperty() { + + @Override + public String getName() { return "restrict-admin-accounts"; } + + }; + +}