From 5c800b1d896cbfa91b44a13a16852c70b6bbbe24 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 3 Aug 2016 15:16:12 -0700 Subject: [PATCH] GUACAMOLE-70: Allow access to be restricted to strictly the users in the database. --- .../jdbc/AuthenticationProviderService.java | 5 ++-- .../JDBCAuthenticationProviderService.java | 26 +++++++++++++++++-- .../guacamole/auth/jdbc/JDBCEnvironment.java | 14 ++++++++++ .../auth/mysql/MySQLEnvironment.java | 14 ++++++++++ .../auth/mysql/MySQLGuacamoleProperties.java | 12 +++++++++ .../postgresql/PostgreSQLEnvironment.java | 14 ++++++++++ .../PostgreSQLGuacamoleProperties.java | 13 ++++++++++ 7 files changed, 93 insertions(+), 5 deletions(-) diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/AuthenticationProviderService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/AuthenticationProviderService.java index 915c41722..398910232 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/AuthenticationProviderService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/AuthenticationProviderService.java @@ -60,8 +60,7 @@ public interface AuthenticationProviderService { /** * Returning a new UserContext instance for the given already-authenticated - * user. A new placeholder account will be created for any user that does - * not already exist within the database. + * user. * * @param authenticationProvider * The AuthenticationProvider on behalf of which the UserContext is @@ -72,7 +71,7 @@ public interface AuthenticationProviderService { * * @return * A new UserContext instance for the user identified by the given - * credentials. + * credentials, or null if no such user exists within the database. * * @throws GuacamoleException * If an error occurs during authentication, or if the given diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java index 20e2f0969..8f98c74cf 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCAuthenticationProviderService.java @@ -22,6 +22,7 @@ package org.apache.guacamole.auth.jdbc; import com.google.inject.Inject; import com.google.inject.Provider; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.sharing.user.SharedAuthenticatedUser; import org.apache.guacamole.auth.jdbc.user.ModeledUser; import org.apache.guacamole.auth.jdbc.user.ModeledUserContext; import org.apache.guacamole.auth.jdbc.user.UserService; @@ -41,6 +42,12 @@ import org.apache.guacamole.net.auth.credentials.GuacamoleInvalidCredentialsExce */ public class JDBCAuthenticationProviderService implements AuthenticationProviderService { + /** + * The environment of the Guacamole server. + */ + @Inject + private JDBCEnvironment environment; + /** * Service for accessing users. */ @@ -73,8 +80,23 @@ public class JDBCAuthenticationProviderService implements AuthenticationProvider // Retrieve user account for already-authenticated user ModeledUser user = userService.retrieveUser(authenticationProvider, authenticatedUser); - if (user == null) - return null; + if (user == null) { + + // Do not invalidate the authentication result of users who were + // authenticated via our own connection sharing links + if (authenticatedUser instanceof SharedAuthenticatedUser) + return null; + + // Simply return no data if a database user account is not required + if (!environment.isUserRequired()) + return null; + + // Otherwise, invalidate the authentication result, as database user + // accounts are absolutely required + throw new GuacamoleInvalidCredentialsException("Invalid login", + CredentialsInfo.USERNAME_PASSWORD); + + } // Link to user context ModeledUserContext context = userContextProvider.get(); diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCEnvironment.java index f14bc2573..7d014c4c8 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCEnvironment.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCEnvironment.java @@ -41,6 +41,20 @@ public abstract class JDBCEnvironment extends LocalEnvironment { super(); } + /** + * Returns whether a database user account is required for authentication to + * succeed, even if another authentication provider has already + * authenticated the user. + * + * @return + * true if database user accounts are required for absolutely all + * authentication attempts, false otherwise. + * + * @throws GuacamoleException + * If an error occurs while retrieving the property. + */ + public abstract boolean isUserRequired() throws GuacamoleException; + /** * Returns the maximum number of concurrent connections to allow overall. * As this limit applies globally (independent of which connection is in diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLEnvironment.java index 208bf44ec..27710de28 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLEnvironment.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLEnvironment.java @@ -48,6 +48,12 @@ public class MySQLEnvironment extends JDBCEnvironment { */ private static final int DEFAULT_PORT = 3306; + /** + * Whether a database user account is required by default for authentication + * to succeed. + */ + private static final boolean DEFAULT_USER_REQUIRED = false; + /** * The default value for the maximum number of connections to be * allowed to the Guacamole server overall. @@ -167,6 +173,14 @@ public class MySQLEnvironment extends JDBCEnvironment { } + @Override + public boolean isUserRequired() throws GuacamoleException { + return getProperty( + MySQLGuacamoleProperties.MYSQL_USER_REQUIRED, + DEFAULT_USER_REQUIRED + ); + } + @Override public int getAbsoluteMaxConnections() throws GuacamoleException { return getProperty(MySQLGuacamoleProperties.MYSQL_ABSOLUTE_MAX_CONNECTIONS, diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLGuacamoleProperties.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLGuacamoleProperties.java index 19da1c1fe..7397f7a41 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLGuacamoleProperties.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/java/org/apache/guacamole/auth/mysql/MySQLGuacamoleProperties.java @@ -90,6 +90,18 @@ public class MySQLGuacamoleProperties { }; + /** + * Whether a user account within the database is required for authentication + * to succeed, even if the user has been authenticated via another + * authentication provider. + */ + public static final BooleanGuacamoleProperty MYSQL_USER_REQUIRED = new BooleanGuacamoleProperty() { + + @Override + public String getName() { return "mysql-user-required"; } + + }; + /** * Whether or not multiple users accessing the same connection at the same * time should be disallowed. diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLEnvironment.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLEnvironment.java index b50fd79b3..fe4207ab0 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLEnvironment.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLEnvironment.java @@ -47,6 +47,12 @@ public class PostgreSQLEnvironment extends JDBCEnvironment { */ private static final int DEFAULT_PORT = 5432; + /** + * Whether a database user account is required by default for authentication + * to succeed. + */ + private static final boolean DEFAULT_USER_REQUIRED = false; + /** * The default value for the maximum number of connections to be * allowed to the Guacamole server overall. @@ -166,6 +172,14 @@ public class PostgreSQLEnvironment extends JDBCEnvironment { } + @Override + public boolean isUserRequired() throws GuacamoleException { + return getProperty( + PostgreSQLGuacamoleProperties.POSTGRESQL_USER_REQUIRED, + DEFAULT_USER_REQUIRED + ); + } + @Override public int getAbsoluteMaxConnections() throws GuacamoleException { return getProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_ABSOLUTE_MAX_CONNECTIONS, diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLGuacamoleProperties.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLGuacamoleProperties.java index 16b8b8de8..e5b516c84 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLGuacamoleProperties.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/java/org/apache/guacamole/auth/postgresql/PostgreSQLGuacamoleProperties.java @@ -95,6 +95,19 @@ public class PostgreSQLGuacamoleProperties { }; + /** + * Whether a user account within the database is required for authentication + * to succeed, even if the user has been authenticated via another + * authentication provider. + */ + public static final BooleanGuacamoleProperty + POSTGRESQL_USER_REQUIRED = new BooleanGuacamoleProperty() { + + @Override + public String getName() { return "postgresql-user-required"; } + + }; + /** * Whether or not multiple users accessing the same connection at the same * time should be disallowed.