mirror of
				https://github.com/gyurix1968/guacamole-client.git
				synced 2025-11-04 02:53:22 +00:00 
			
		
		
		
	GUACAMOLE-641: Merge expand extension API to allow properties to be retrieved from key vaults.
This commit is contained in:
		@@ -58,7 +58,7 @@ public class CASAuthenticationProviderModule extends AbstractModule {
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Get local environment
 | 
			
		||||
        this.environment = new LocalEnvironment();
 | 
			
		||||
        this.environment = LocalEnvironment.getInstance();
 | 
			
		||||
 | 
			
		||||
        // Store associated auth provider
 | 
			
		||||
        this.authProvider = authProvider;
 | 
			
		||||
 
 | 
			
		||||
@@ -58,7 +58,7 @@ public class DuoAuthenticationProviderModule extends AbstractModule {
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Get local environment
 | 
			
		||||
        this.environment = new LocalEnvironment();
 | 
			
		||||
        this.environment = LocalEnvironment.getInstance();
 | 
			
		||||
 | 
			
		||||
        // Store associated auth provider
 | 
			
		||||
        this.authProvider = authProvider;
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@ public class HTTPHeaderAuthenticationProviderModule extends AbstractModule {
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Get local environment
 | 
			
		||||
        this.environment = new LocalEnvironment();
 | 
			
		||||
        this.environment = LocalEnvironment.getInstance();
 | 
			
		||||
 | 
			
		||||
        // Store associated auth provider
 | 
			
		||||
        this.authProvider = authProvider;
 | 
			
		||||
 
 | 
			
		||||
@@ -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.jdbc;
 | 
			
		||||
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Singleton;
 | 
			
		||||
import com.google.inject.name.Named;
 | 
			
		||||
import java.sql.Connection;
 | 
			
		||||
import java.sql.SQLException;
 | 
			
		||||
import org.apache.guacamole.GuacamoleException;
 | 
			
		||||
import org.apache.ibatis.datasource.pooled.PooledDataSource;
 | 
			
		||||
import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Pooled DataSource implementation which dynamically retrieves the database
 | 
			
		||||
 * username and password from the Guacamole server environment each time a
 | 
			
		||||
 * new database connection is created.
 | 
			
		||||
 */
 | 
			
		||||
@Singleton
 | 
			
		||||
public class DynamicallyAuthenticatedDataSource extends PooledDataSource {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new DynamicallyAuthenticatedDataSource which dynamically
 | 
			
		||||
     * retrieves database credentials from the given JDBCEnvironment each time
 | 
			
		||||
     * a new database connection is needed.
 | 
			
		||||
     *
 | 
			
		||||
     * @param environment
 | 
			
		||||
     *     The JDBCEnvironment that should be used to retrieve database
 | 
			
		||||
     *     credentials.
 | 
			
		||||
     *
 | 
			
		||||
     * @param driverClassLoader
 | 
			
		||||
     * @param driver
 | 
			
		||||
     * @param url
 | 
			
		||||
     */
 | 
			
		||||
    @Inject
 | 
			
		||||
    public DynamicallyAuthenticatedDataSource(JDBCEnvironment environment,
 | 
			
		||||
            @Named(value="JDBC.driverClassLoader") ClassLoader driverClassLoader,
 | 
			
		||||
            @Named(value="JDBC.driver") String driver,
 | 
			
		||||
            @Named(value="JDBC.url") String url) {
 | 
			
		||||
 | 
			
		||||
        // Wrap unpooled DataSource, overriding the connection process such
 | 
			
		||||
        // that credentials are dynamically retrieved from the JDBCEnvironment
 | 
			
		||||
        super(new UnpooledDataSource(driverClassLoader, driver, url, null, null) {
 | 
			
		||||
 | 
			
		||||
            @Override
 | 
			
		||||
            public Connection getConnection() throws SQLException {
 | 
			
		||||
                try {
 | 
			
		||||
                    return super.getConnection(environment.getUsername(), environment.getPassword());
 | 
			
		||||
                }
 | 
			
		||||
                catch (GuacamoleException e) {
 | 
			
		||||
                    throw new SQLException("Retrieval of database credentials failed.", e);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -20,6 +20,7 @@
 | 
			
		||||
package org.apache.guacamole.auth.jdbc;
 | 
			
		||||
 | 
			
		||||
import com.google.inject.Scopes;
 | 
			
		||||
import javax.sql.DataSource;
 | 
			
		||||
import org.apache.guacamole.auth.jdbc.user.ModeledUserContext;
 | 
			
		||||
import org.apache.guacamole.auth.jdbc.connectiongroup.RootConnectionGroup;
 | 
			
		||||
import org.apache.guacamole.auth.jdbc.connectiongroup.ModeledConnectionGroup;
 | 
			
		||||
@@ -90,7 +91,6 @@ import org.apache.guacamole.auth.jdbc.usergroup.UserGroupMemberUserMapper;
 | 
			
		||||
import org.apache.guacamole.auth.jdbc.usergroup.UserGroupParentUserGroupMapper;
 | 
			
		||||
import org.apache.guacamole.auth.jdbc.usergroup.UserGroupService;
 | 
			
		||||
import org.mybatis.guice.MyBatisModule;
 | 
			
		||||
import org.mybatis.guice.datasource.builtin.PooledDataSourceProvider;
 | 
			
		||||
import org.apache.guacamole.auth.jdbc.user.UserParentUserGroupMapper;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -121,7 +121,7 @@ public class JDBCAuthenticationProviderModule extends MyBatisModule {
 | 
			
		||||
    protected void initialize() {
 | 
			
		||||
        
 | 
			
		||||
        // Datasource
 | 
			
		||||
        bindDataSourceProviderType(PooledDataSourceProvider.class);
 | 
			
		||||
        bind(DataSource.class).to(DynamicallyAuthenticatedDataSource.class);
 | 
			
		||||
        
 | 
			
		||||
        // Transaction factory
 | 
			
		||||
        bindTransactionFactoryType(JdbcTransactionFactory.class);
 | 
			
		||||
 
 | 
			
		||||
@@ -20,25 +20,23 @@
 | 
			
		||||
package org.apache.guacamole.auth.jdbc;
 | 
			
		||||
 | 
			
		||||
import org.apache.guacamole.GuacamoleException;
 | 
			
		||||
import org.apache.guacamole.environment.LocalEnvironment;
 | 
			
		||||
import org.apache.guacamole.auth.jdbc.security.PasswordPolicy;
 | 
			
		||||
import org.apache.guacamole.environment.DelegatingEnvironment;
 | 
			
		||||
import org.apache.guacamole.environment.LocalEnvironment;
 | 
			
		||||
import org.apache.ibatis.session.SqlSession;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A JDBC-specific implementation of Environment that defines generic properties
 | 
			
		||||
 * intended for use within JDBC based authentication providers.
 | 
			
		||||
 */
 | 
			
		||||
public abstract class JDBCEnvironment extends LocalEnvironment {
 | 
			
		||||
public abstract class JDBCEnvironment extends DelegatingEnvironment {
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a new JDBCEnvironment using an underlying LocalEnviroment to
 | 
			
		||||
     * read properties from the file system.
 | 
			
		||||
     * 
 | 
			
		||||
     * @throws GuacamoleException
 | 
			
		||||
     *     If an error occurs while setting up the underlying LocalEnvironment.
 | 
			
		||||
     */
 | 
			
		||||
    public JDBCEnvironment() throws GuacamoleException {
 | 
			
		||||
        super();
 | 
			
		||||
    public JDBCEnvironment() {
 | 
			
		||||
        super(LocalEnvironment.getInstance());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -168,4 +166,30 @@ public abstract class JDBCEnvironment extends LocalEnvironment {
 | 
			
		||||
     */
 | 
			
		||||
    public abstract boolean autoCreateAbsentAccounts() throws GuacamoleException;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the username that should be used when authenticating with the
 | 
			
		||||
     * database containing the Guacamole authentication tables.
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     *     The username for the database.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException
 | 
			
		||||
     *     If an error occurs while retrieving the property value, or if the
 | 
			
		||||
     *     value was not set, as this property is required.
 | 
			
		||||
     */
 | 
			
		||||
    public abstract String getUsername() throws GuacamoleException;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the password that should be used authenticating with the
 | 
			
		||||
     * database containing the Guacamole authentication tables.
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     *     The password for the database.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException
 | 
			
		||||
     *     If an error occurs while retrieving the property value, or if the
 | 
			
		||||
     *     value was not set, as this property is required.
 | 
			
		||||
     */
 | 
			
		||||
    public abstract String getPassword() throws GuacamoleException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -72,8 +72,6 @@ public class MySQLAuthenticationProviderModule implements Module {
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.host", environment.getMySQLHostname());
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.port", String.valueOf(environment.getMySQLPort()));
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.schema", environment.getMySQLDatabase());
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.username", environment.getMySQLUsername());
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.password", environment.getMySQLPassword());
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.autoCommit", "false");
 | 
			
		||||
        myBatisProperties.setProperty("mybatis.pooled.pingEnabled", "true");
 | 
			
		||||
        myBatisProperties.setProperty("mybatis.pooled.pingQuery", "SELECT 1");
 | 
			
		||||
 
 | 
			
		||||
@@ -241,34 +241,14 @@ public class MySQLEnvironment extends JDBCEnvironment {
 | 
			
		||||
    public String getMySQLDatabase() throws GuacamoleException {
 | 
			
		||||
        return getRequiredProperty(MySQLGuacamoleProperties.MYSQL_DATABASE);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the username that should be used when authenticating with the
 | 
			
		||||
     * MySQL database containing the Guacamole authentication tables.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return
 | 
			
		||||
     *     The username for the MySQL database.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException 
 | 
			
		||||
     *     If an error occurs while retrieving the property value, or if the
 | 
			
		||||
     *     value was not set, as this property is required.
 | 
			
		||||
     */
 | 
			
		||||
    public String getMySQLUsername() throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getUsername() throws GuacamoleException {
 | 
			
		||||
        return getRequiredProperty(MySQLGuacamoleProperties.MYSQL_USERNAME);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the password that should be used when authenticating with the
 | 
			
		||||
     * MySQL database containing the Guacamole authentication tables.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return
 | 
			
		||||
     *     The password for the MySQL database.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException 
 | 
			
		||||
     *     If an error occurs while retrieving the property value, or if the
 | 
			
		||||
     *     value was not set, as this property is required.
 | 
			
		||||
     */
 | 
			
		||||
    public String getMySQLPassword() throws GuacamoleException {
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getPassword() throws GuacamoleException {
 | 
			
		||||
        return getRequiredProperty(MySQLGuacamoleProperties.MYSQL_PASSWORD);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -64,8 +64,6 @@ public class PostgreSQLAuthenticationProviderModule implements Module {
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.host", environment.getPostgreSQLHostname());
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.port", String.valueOf(environment.getPostgreSQLPort()));
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.schema", environment.getPostgreSQLDatabase());
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.username", environment.getPostgreSQLUsername());
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.password", environment.getPostgreSQLPassword());
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.autoCommit", "false");
 | 
			
		||||
        myBatisProperties.setProperty("mybatis.pooled.pingEnabled", "true");
 | 
			
		||||
        myBatisProperties.setProperty("mybatis.pooled.pingQuery", "SELECT 1");
 | 
			
		||||
 
 | 
			
		||||
@@ -232,34 +232,14 @@ public class PostgreSQLEnvironment extends JDBCEnvironment {
 | 
			
		||||
    public String getPostgreSQLDatabase() throws GuacamoleException {
 | 
			
		||||
        return getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_DATABASE);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the username that should be used when authenticating with the
 | 
			
		||||
     * PostgreSQL database containing the Guacamole authentication tables.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return
 | 
			
		||||
     *     The username for the PostgreSQL database.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException 
 | 
			
		||||
     *     If an error occurs while retrieving the property value, or if the
 | 
			
		||||
     *     value was not set, as this property is required.
 | 
			
		||||
     */
 | 
			
		||||
    public String getPostgreSQLUsername() throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getUsername() throws GuacamoleException {
 | 
			
		||||
        return getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_USERNAME);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the password that should be used when authenticating with the
 | 
			
		||||
     * PostgreSQL database containing the Guacamole authentication tables.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return
 | 
			
		||||
     *     The password for the PostgreSQL database.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException 
 | 
			
		||||
     *     If an error occurs while retrieving the property value, or if the
 | 
			
		||||
     *     value was not set, as this property is required.
 | 
			
		||||
     */
 | 
			
		||||
    public String getPostgreSQLPassword() throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getPassword() throws GuacamoleException {
 | 
			
		||||
        return getRequiredProperty(PostgreSQLGuacamoleProperties.POSTGRESQL_PASSWORD);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
 
 | 
			
		||||
@@ -69,8 +69,6 @@ public class SQLServerAuthenticationProviderModule implements Module {
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.host", environment.getSQLServerHostname());
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.port", String.valueOf(environment.getSQLServerPort()));
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.schema", environment.getSQLServerDatabase());
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.username", environment.getSQLServerUsername());
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.password", environment.getSQLServerPassword());
 | 
			
		||||
        
 | 
			
		||||
        myBatisProperties.setProperty("JDBC.autoCommit", "false");
 | 
			
		||||
        myBatisProperties.setProperty("mybatis.pooled.pingEnabled", "true");
 | 
			
		||||
 
 | 
			
		||||
@@ -222,33 +222,13 @@ public class SQLServerEnvironment extends JDBCEnvironment {
 | 
			
		||||
        return getRequiredProperty(SQLServerGuacamoleProperties.SQLSERVER_DATABASE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the username that should be used when authenticating with the
 | 
			
		||||
     * SQLServer database containing the Guacamole authentication tables.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return
 | 
			
		||||
     *     The username for the SQLServer database.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException 
 | 
			
		||||
     *     If an error occurs while retrieving the property value, or if the
 | 
			
		||||
     *     value was not set, as this property is required.
 | 
			
		||||
     */
 | 
			
		||||
    public String getSQLServerUsername() throws GuacamoleException {
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getUsername() throws GuacamoleException {
 | 
			
		||||
        return getRequiredProperty(SQLServerGuacamoleProperties.SQLSERVER_USERNAME);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the password that should be used when authenticating with the
 | 
			
		||||
     * SQLServer database containing the Guacamole authentication tables.
 | 
			
		||||
     * 
 | 
			
		||||
     * @return
 | 
			
		||||
     *     The password for the SQLServer database.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException 
 | 
			
		||||
     *     If an error occurs while retrieving the property value, or if the
 | 
			
		||||
     *     value was not set, as this property is required.
 | 
			
		||||
     */
 | 
			
		||||
    public String getSQLServerPassword() throws GuacamoleException {
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getPassword() throws GuacamoleException {
 | 
			
		||||
        return getRequiredProperty(SQLServerGuacamoleProperties.SQLSERVER_PASSWORD);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ public class JSONAuthenticationProviderModule extends AbstractModule {
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Get local environment
 | 
			
		||||
        this.environment = new LocalEnvironment();
 | 
			
		||||
        this.environment = LocalEnvironment.getInstance();
 | 
			
		||||
 | 
			
		||||
        // Store associated auth provider
 | 
			
		||||
        this.authProvider = authProvider;
 | 
			
		||||
 
 | 
			
		||||
@@ -60,7 +60,7 @@ public class LDAPAuthenticationProviderModule extends AbstractModule {
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Get local environment
 | 
			
		||||
        this.environment = new LocalEnvironment();
 | 
			
		||||
        this.environment = LocalEnvironment.getInstance();
 | 
			
		||||
 | 
			
		||||
        // Store associated auth provider
 | 
			
		||||
        this.authProvider = authProvider;
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ public class OpenIDAuthenticationProviderModule extends AbstractModule {
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Get local environment
 | 
			
		||||
        this.environment = new LocalEnvironment();
 | 
			
		||||
        this.environment = LocalEnvironment.getInstance();
 | 
			
		||||
 | 
			
		||||
        // Store associated auth provider
 | 
			
		||||
        this.authProvider = authProvider;
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ public class QuickConnectAuthenticationProviderModule extends AbstractModule {
 | 
			
		||||
            AuthenticationProvider authProvider) throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Get local environment
 | 
			
		||||
        this.environment = new LocalEnvironment();
 | 
			
		||||
        this.environment = LocalEnvironment.getInstance();
 | 
			
		||||
 | 
			
		||||
        // Store associated auth provider
 | 
			
		||||
        this.authProvider = authProvider;
 | 
			
		||||
 
 | 
			
		||||
@@ -63,7 +63,7 @@ public class RadiusAuthenticationProviderModule extends AbstractModule {
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Get local environment
 | 
			
		||||
        this.environment = new LocalEnvironment();
 | 
			
		||||
        this.environment = LocalEnvironment.getInstance();
 | 
			
		||||
        
 | 
			
		||||
        // Check for MD4 requirement
 | 
			
		||||
        RadiusAuthenticationProtocol authProtocol = environment.getProperty(RadiusGuacamoleProperties.RADIUS_AUTH_PROTOCOL);
 | 
			
		||||
 
 | 
			
		||||
@@ -57,7 +57,7 @@ public class SAMLAuthenticationProviderModule extends AbstractModule {
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Get local environment
 | 
			
		||||
        this.environment = new LocalEnvironment();
 | 
			
		||||
        this.environment = LocalEnvironment.getInstance();
 | 
			
		||||
 | 
			
		||||
        // Store associated auth provider
 | 
			
		||||
        this.authProvider = authProvider;
 | 
			
		||||
 
 | 
			
		||||
@@ -59,7 +59,7 @@ public class TOTPAuthenticationProviderModule extends AbstractModule {
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Get local environment
 | 
			
		||||
        this.environment = new LocalEnvironment();
 | 
			
		||||
        this.environment = LocalEnvironment.getInstance();
 | 
			
		||||
 | 
			
		||||
        // Store associated auth provider
 | 
			
		||||
        this.authProvider = authProvider;
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,92 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.environment;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import org.apache.guacamole.GuacamoleException;
 | 
			
		||||
import org.apache.guacamole.net.auth.GuacamoleProxyConfiguration;
 | 
			
		||||
import org.apache.guacamole.properties.GuacamoleProperties;
 | 
			
		||||
import org.apache.guacamole.properties.GuacamoleProperty;
 | 
			
		||||
import org.apache.guacamole.protocols.ProtocolInfo;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Environment implementation which simply delegates all function calls to a
 | 
			
		||||
 * wrapped Environment instance.
 | 
			
		||||
 */
 | 
			
		||||
public class DelegatingEnvironment implements Environment {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The Environment instance that all function calls should be delegated to.
 | 
			
		||||
     */
 | 
			
		||||
    private final Environment environment;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new DelegatingEnvironment which delegates all function calls
 | 
			
		||||
     * to the given Environment.
 | 
			
		||||
     *
 | 
			
		||||
     * @param environment
 | 
			
		||||
     *     The Environment that all function calls should be delegated to.
 | 
			
		||||
     */
 | 
			
		||||
    public DelegatingEnvironment(Environment environment) {
 | 
			
		||||
        this.environment = environment;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public File getGuacamoleHome() {
 | 
			
		||||
        return environment.getGuacamoleHome();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Map<String, ProtocolInfo> getProtocols() {
 | 
			
		||||
        return environment.getProtocols();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public ProtocolInfo getProtocol(String name) {
 | 
			
		||||
        return environment.getProtocol(name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public <Type> Type getProperty(GuacamoleProperty<Type> property) throws GuacamoleException {
 | 
			
		||||
        return environment.getProperty(property);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public <Type> Type getProperty(GuacamoleProperty<Type> property, Type defaultValue) throws GuacamoleException {
 | 
			
		||||
        return environment.getProperty(property, defaultValue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public <Type> Type getRequiredProperty(GuacamoleProperty<Type> property) throws GuacamoleException {
 | 
			
		||||
        return environment.getRequiredProperty(property);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public GuacamoleProxyConfiguration getDefaultGuacamoleProxyConfiguration() throws GuacamoleException {
 | 
			
		||||
        return environment.getDefaultGuacamoleProxyConfiguration();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addGuacamoleProperties(GuacamoleProperties properties) throws GuacamoleException {
 | 
			
		||||
        environment.addGuacamoleProperties(properties);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -19,9 +19,11 @@
 | 
			
		||||
 | 
			
		||||
package org.apache.guacamole.environment;
 | 
			
		||||
 | 
			
		||||
import org.apache.guacamole.properties.GuacamoleProperties;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import org.apache.guacamole.GuacamoleException;
 | 
			
		||||
import org.apache.guacamole.GuacamoleUnsupportedException;
 | 
			
		||||
import org.apache.guacamole.net.auth.GuacamoleProxyConfiguration;
 | 
			
		||||
import org.apache.guacamole.properties.BooleanGuacamoleProperty;
 | 
			
		||||
import org.apache.guacamole.properties.GuacamoleProperty;
 | 
			
		||||
@@ -162,4 +164,24 @@ public interface Environment {
 | 
			
		||||
    public GuacamoleProxyConfiguration getDefaultGuacamoleProxyConfiguration()
 | 
			
		||||
            throws GuacamoleException;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Adds another possible source of Guacamole configuration properties to
 | 
			
		||||
     * this Environment. Properties not already defined by other sources of
 | 
			
		||||
     * Guacamole configuration properties will alternatively be read from the
 | 
			
		||||
     * given {@link GuacamoleProperties}.
 | 
			
		||||
     *
 | 
			
		||||
     * @param properties
 | 
			
		||||
     *     The GuacamoleProperties to add to this Environment.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException
 | 
			
		||||
     *     If the given GuacamoleProperties cannot be added, or if this
 | 
			
		||||
     *     Environment does not support this operation.
 | 
			
		||||
     */
 | 
			
		||||
    public default void addGuacamoleProperties(GuacamoleProperties properties)
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
        throw new GuacamoleUnsupportedException(String.format("%s does not "
 | 
			
		||||
                + "support dynamic definition of Guacamole properties.",
 | 
			
		||||
                getClass()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,12 +26,13 @@ import java.io.FilenameFilter;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
import java.util.concurrent.CopyOnWriteArrayList;
 | 
			
		||||
import org.apache.guacamole.GuacamoleException;
 | 
			
		||||
import org.apache.guacamole.GuacamoleServerException;
 | 
			
		||||
import org.apache.guacamole.net.auth.GuacamoleProxyConfiguration;
 | 
			
		||||
import org.apache.guacamole.properties.BooleanGuacamoleProperty;
 | 
			
		||||
import org.apache.guacamole.properties.GuacamoleProperties;
 | 
			
		||||
import org.apache.guacamole.properties.GuacamoleProperty;
 | 
			
		||||
import org.apache.guacamole.protocols.ProtocolInfo;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
@@ -40,7 +41,10 @@ import org.slf4j.LoggerFactory;
 | 
			
		||||
/**
 | 
			
		||||
 * The environment of the locally-running Guacamole instance, describing
 | 
			
		||||
 * available protocols, configuration parameters, and the GUACAMOLE_HOME
 | 
			
		||||
 * directory.
 | 
			
		||||
 * directory. Sources of configuration properties like guacamole.properties and
 | 
			
		||||
 * environment variables will be automatically added by the Guacamole web
 | 
			
		||||
 * application and may also be added by extensions using
 | 
			
		||||
 * {@link #addGuacamoleProperties(org.apache.guacamole.properties.GuacamoleProperties)}.
 | 
			
		||||
 */
 | 
			
		||||
public class LocalEnvironment implements Environment {
 | 
			
		||||
 | 
			
		||||
@@ -52,8 +56,13 @@ public class LocalEnvironment implements Environment {
 | 
			
		||||
    /**
 | 
			
		||||
     * Array of all known protocol names.
 | 
			
		||||
     */
 | 
			
		||||
    private static final String[] KNOWN_PROTOCOLS = new String[]{
 | 
			
		||||
        "vnc", "rdp", "ssh", "telnet", "kubernetes"};
 | 
			
		||||
    private static final String[] KNOWN_PROTOCOLS = new String[] {
 | 
			
		||||
        "kubernetes",
 | 
			
		||||
        "rdp",
 | 
			
		||||
        "ssh",
 | 
			
		||||
        "telnet",
 | 
			
		||||
        "vnc",
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The hostname to use when connecting to guacd if no hostname is provided
 | 
			
		||||
@@ -73,23 +82,6 @@ public class LocalEnvironment implements Environment {
 | 
			
		||||
     */
 | 
			
		||||
    private static final boolean DEFAULT_GUACD_SSL = false;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A property that determines whether environment variables are evaluated
 | 
			
		||||
     * to override properties specified in guacamole.properties.
 | 
			
		||||
     */
 | 
			
		||||
    private static final BooleanGuacamoleProperty ENABLE_ENVIRONMENT_PROPERTIES =
 | 
			
		||||
        new BooleanGuacamoleProperty() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public String getName() {
 | 
			
		||||
                return "enable-environment-properties";
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * All properties read from guacamole.properties.
 | 
			
		||||
     */
 | 
			
		||||
    private final Properties properties;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The location of GUACAMOLE_HOME, which may not truly exist.
 | 
			
		||||
     */
 | 
			
		||||
@@ -101,9 +93,13 @@ public class LocalEnvironment implements Environment {
 | 
			
		||||
    private final Map<String, ProtocolInfo> availableProtocols;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Flag indicating whether environment variables can override properties.
 | 
			
		||||
     * All GuacamoleProperties instances added via addGuacamoleProperties(), in
 | 
			
		||||
     * the order that they were added. This storage has been made static to
 | 
			
		||||
     * allow addGuacamoleProperties() to work as expected even if extensions
 | 
			
		||||
     * continue to use the deprecated constructor to create non-singleton
 | 
			
		||||
     * instances.
 | 
			
		||||
     */
 | 
			
		||||
    private final boolean environmentPropertiesEnabled;
 | 
			
		||||
    private static final List<GuacamoleProperties> availableProperties = new CopyOnWriteArrayList<>();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The Jackson parser for parsing JSON files.
 | 
			
		||||
@@ -111,56 +107,43 @@ public class LocalEnvironment implements Environment {
 | 
			
		||||
    private static final ObjectMapper mapper = new ObjectMapper();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new Environment, initializing that environment based on the
 | 
			
		||||
     * location of GUACAMOLE_HOME and the contents of guacamole.properties.
 | 
			
		||||
     * 
 | 
			
		||||
     * @throws GuacamoleException If an error occurs while determining the
 | 
			
		||||
     *                            environment of this Guacamole instance.
 | 
			
		||||
     * Singleton instance of this environment, to be returned by calls to
 | 
			
		||||
     * getInstance().
 | 
			
		||||
     */
 | 
			
		||||
    public LocalEnvironment() throws GuacamoleException {
 | 
			
		||||
    private static final LocalEnvironment instance = new LocalEnvironment();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns a singleton instance of LocalEnvironment which may be shared by
 | 
			
		||||
     * the Guacamole web application and all extensions.
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     *     A singleton instance of this class.
 | 
			
		||||
     */
 | 
			
		||||
    public static LocalEnvironment getInstance() {
 | 
			
		||||
        return instance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new LocalEnvironment, initializing that environment based on
 | 
			
		||||
     * the contents of GUACAMOLE_HOME. Sources of configuration properties like
 | 
			
		||||
     * guacamole.properties and environment variables will be automatically
 | 
			
		||||
     * added by the Guacamole web application and/or any installed extensions.
 | 
			
		||||
     *
 | 
			
		||||
     * @deprecated
 | 
			
		||||
     *     Extensions leveraging LocalEnvironment should instead use
 | 
			
		||||
     *     LocalEnvironment.getInstance() to obtain a singleton instance of the
 | 
			
		||||
     *     environment.
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public LocalEnvironment() {
 | 
			
		||||
 | 
			
		||||
        // Determine location of GUACAMOLE_HOME
 | 
			
		||||
        guacHome = findGuacamoleHome();
 | 
			
		||||
        logger.info("GUACAMOLE_HOME is \"{}\".", guacHome.getAbsolutePath());
 | 
			
		||||
 | 
			
		||||
        // Read properties
 | 
			
		||||
        properties = new Properties();
 | 
			
		||||
        try {
 | 
			
		||||
 | 
			
		||||
            InputStream stream = null;
 | 
			
		||||
 | 
			
		||||
            // If not a directory, load from classpath
 | 
			
		||||
            if (!guacHome.isDirectory())
 | 
			
		||||
                stream = LocalEnvironment.class.getResourceAsStream("/guacamole.properties");
 | 
			
		||||
 | 
			
		||||
            // Otherwise, try to load from file
 | 
			
		||||
            else {
 | 
			
		||||
                File propertiesFile = new File(guacHome, "guacamole.properties");
 | 
			
		||||
                if (propertiesFile.exists())
 | 
			
		||||
                    stream = new FileInputStream(propertiesFile);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Load properties from stream, if any, always closing stream when done
 | 
			
		||||
            if (stream != null) {
 | 
			
		||||
                try { properties.load(stream); }
 | 
			
		||||
                finally { stream.close(); }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Notify if we're proceeding without guacamole.properties
 | 
			
		||||
            else
 | 
			
		||||
                logger.info("No guacamole.properties file found within GUACAMOLE_HOME or the classpath. Using defaults.");
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
        catch (IOException e) {
 | 
			
		||||
            logger.warn("The guacamole.properties file within GUACAMOLE_HOME cannot be read: {}", e.getMessage());
 | 
			
		||||
            logger.debug("Error reading guacamole.properties.", e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Read all protocols
 | 
			
		||||
        availableProtocols = readProtocols();
 | 
			
		||||
 | 
			
		||||
        // Should environment variables override configuration properties?
 | 
			
		||||
        environmentPropertiesEnabled = environmentPropertiesEnabled(properties);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -265,7 +248,7 @@ public class LocalEnvironment implements Environment {
 | 
			
		||||
                logger.error("Unable to read contents of \"{}\".", protocol_directory.getAbsolutePath());
 | 
			
		||||
                files = new File[0];
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
 | 
			
		||||
            // Load each protocol from each file
 | 
			
		||||
            for (File file : files) {
 | 
			
		||||
 | 
			
		||||
@@ -319,69 +302,39 @@ public class LocalEnvironment implements Environment {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks for the presence of the {@link #ENABLE_ENVIRONMENT_PROPERTIES}
 | 
			
		||||
     * property in the given properties collection.
 | 
			
		||||
     *
 | 
			
		||||
     * @param properties
 | 
			
		||||
     *     The properties collection to check.
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     *     true if the property is present in the given properties collection
 | 
			
		||||
     *     and its parsed value is true
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException If the value specified for the property
 | 
			
		||||
     *                            cannot be successfully parsed as a Boolean
 | 
			
		||||
     *
 | 
			
		||||
     */
 | 
			
		||||
    private static boolean environmentPropertiesEnabled(Properties properties)
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        final Boolean enabled = ENABLE_ENVIRONMENT_PROPERTIES.parseValue(
 | 
			
		||||
                properties.getProperty(ENABLE_ENVIRONMENT_PROPERTIES.getName()));
 | 
			
		||||
 | 
			
		||||
        return enabled != null && enabled;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public File getGuacamoleHome() {
 | 
			
		||||
        return guacHome;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the string value for a property name.
 | 
			
		||||
     *
 | 
			
		||||
     * The value may come from either the OS environment (if property override
 | 
			
		||||
     * is enabled) or the Properties collection that was loaded from
 | 
			
		||||
     * guacamole.properties. When checking the environment for the named
 | 
			
		||||
     * property, the name is first transformed by converting all hyphens to
 | 
			
		||||
     * underscores and converting the string to upper case letter, in accordance
 | 
			
		||||
     * with common convention for environment strings.
 | 
			
		||||
     * Returns the string value of the property having the given name, trying
 | 
			
		||||
     * each source of properties added with addGuacamoleProperties() until a
 | 
			
		||||
     * value is found. If no such property is defined, null is returned.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name
 | 
			
		||||
     *     The name of the property value to retrieve.
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     *     The corresponding value for the property. If property override
 | 
			
		||||
     *     is enabled and the value is found in the OS environment, the value
 | 
			
		||||
     *     from the environment is returned. Otherwise, the value from
 | 
			
		||||
     *     guacamole.properties, if any, is returned.
 | 
			
		||||
     *     The value of the property having the given name, or null if no such
 | 
			
		||||
     *     property is defined.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException
 | 
			
		||||
     *     If an error occurs retrieving a property from a GuacamoleProperties
 | 
			
		||||
     *     implementation added via addGuacamoleProperties().
 | 
			
		||||
     */
 | 
			
		||||
    private String getPropertyValue(String name) {
 | 
			
		||||
    private String getPropertyValue(String name) throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Check for corresponding environment variable if overrides enabled
 | 
			
		||||
        if (environmentPropertiesEnabled) {
 | 
			
		||||
 | 
			
		||||
            // Transform the name according to common convention
 | 
			
		||||
            final String envName = name.replace('-', '_').toUpperCase();
 | 
			
		||||
            final String envValue = System.getenv(envName);
 | 
			
		||||
 | 
			
		||||
            if (envValue != null) {
 | 
			
		||||
                return envValue;
 | 
			
		||||
            }
 | 
			
		||||
        // Search all provided GuacamoleProperties implementations, in order
 | 
			
		||||
        for (GuacamoleProperties properties : availableProperties) {
 | 
			
		||||
            String value = properties.getProperty(name);
 | 
			
		||||
            if (value != null)
 | 
			
		||||
                return value;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return properties.getProperty(name);
 | 
			
		||||
        // No such property
 | 
			
		||||
        return null;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -436,4 +389,9 @@ public class LocalEnvironment implements Environment {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void addGuacamoleProperties(GuacamoleProperties properties) {
 | 
			
		||||
        availableProperties.add(properties);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -202,7 +202,7 @@ public class SimpleConnection extends AbstractConnection {
 | 
			
		||||
            throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Retrieve proxy configuration from environment
 | 
			
		||||
        Environment environment = new LocalEnvironment();
 | 
			
		||||
        Environment environment = LocalEnvironment.getInstance();
 | 
			
		||||
        GuacamoleProxyConfiguration proxyConfig = environment.getDefaultGuacamoleProxyConfiguration();
 | 
			
		||||
 | 
			
		||||
        // Get guacd connection parameters
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,85 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.properties;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.FileInputStream;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.io.InputStream;
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
import org.apache.guacamole.GuacamoleException;
 | 
			
		||||
import org.apache.guacamole.GuacamoleServerException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * GuacamoleProperties implementation which reads all properties from a
 | 
			
		||||
 * standard Java properties file.
 | 
			
		||||
 */
 | 
			
		||||
public class FileGuacamoleProperties extends PropertiesGuacamoleProperties {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Reads the given Java properties file, storing all property name/value
 | 
			
		||||
     * pairs in a new {@link Properties} object.
 | 
			
		||||
     *
 | 
			
		||||
     * @param propertiesFile
 | 
			
		||||
     *     The Java properties file to read.
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     *     A new Properties containing all property name/value pairs defined in
 | 
			
		||||
     *     the given file.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException
 | 
			
		||||
     *     If an error prevents reading the given Java properties file.
 | 
			
		||||
     */
 | 
			
		||||
    private static Properties read(File propertiesFile) throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Fail early if file simply does not exist
 | 
			
		||||
        if (!propertiesFile.exists())
 | 
			
		||||
            throw new GuacamoleServerException(String.format("\"%s\" does not "
 | 
			
		||||
                    + "exist.", propertiesFile));
 | 
			
		||||
 | 
			
		||||
        // Load properties from stream, if any, always closing stream when done
 | 
			
		||||
        Properties properties = new Properties();
 | 
			
		||||
        try (InputStream stream = new FileInputStream(propertiesFile)) {
 | 
			
		||||
            properties.load(stream);
 | 
			
		||||
        }
 | 
			
		||||
        catch (IOException e) {
 | 
			
		||||
            throw new GuacamoleServerException(String.format("\"%s\" cannot "
 | 
			
		||||
                    + "be read: %s", propertiesFile, e.getMessage()), e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return properties;
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new FileGuacamoleProperties which reads all properties from
 | 
			
		||||
     * the given standard Java properties file.
 | 
			
		||||
     *
 | 
			
		||||
     * @param propertiesFile
 | 
			
		||||
     *     The Java properties file to read.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException
 | 
			
		||||
     *     If an error prevents reading the given Java properties file.
 | 
			
		||||
     */
 | 
			
		||||
    public FileGuacamoleProperties(File propertiesFile) throws GuacamoleException {
 | 
			
		||||
        super(read(propertiesFile));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,49 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.properties;
 | 
			
		||||
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
import org.apache.guacamole.GuacamoleException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An arbitrary set of Guacamole configuration property name/value pairs. This
 | 
			
		||||
 * interface is similar in concept to {@link Properties} except that
 | 
			
		||||
 * implementations are not required to allow properties to be enumerated or
 | 
			
		||||
 * iterated. Properties may simply be retrieved by their names, if known.
 | 
			
		||||
 */
 | 
			
		||||
public interface GuacamoleProperties {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the value of the property having the given name, if defined. If
 | 
			
		||||
     * no such property exists, null is returned.
 | 
			
		||||
     *
 | 
			
		||||
     * @param name
 | 
			
		||||
     *     The name of the property to retrieve.
 | 
			
		||||
     *
 | 
			
		||||
     * @return
 | 
			
		||||
     *     The value of the given property, or null if no such property is
 | 
			
		||||
     *     defined.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException
 | 
			
		||||
     *     If an error prevents the given property from being read.
 | 
			
		||||
     */
 | 
			
		||||
    String getProperty(String name) throws GuacamoleException;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -0,0 +1,54 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.properties;
 | 
			
		||||
 | 
			
		||||
import java.util.Properties;
 | 
			
		||||
import org.apache.guacamole.GuacamoleException;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * GuacamoleProperties implementation which reads all properties from a
 | 
			
		||||
 * {@link Properties} object.
 | 
			
		||||
 */
 | 
			
		||||
public class PropertiesGuacamoleProperties implements GuacamoleProperties {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The Properties from which all property values should be read.
 | 
			
		||||
     */
 | 
			
		||||
    private final Properties properties;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new PropertiesGuacamoleProperties which wraps the given
 | 
			
		||||
     * {@link Properties}, providing access to the values of any properties
 | 
			
		||||
     * defined therein.
 | 
			
		||||
     *
 | 
			
		||||
     * @param properties
 | 
			
		||||
     *     The Properties that should be used as the source of all property
 | 
			
		||||
     *     values exposed by this instance of PropertiesGuacamoleProperties.
 | 
			
		||||
     */
 | 
			
		||||
    public PropertiesGuacamoleProperties(Properties properties) {
 | 
			
		||||
        this.properties = properties;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getProperty(String name) throws GuacamoleException {
 | 
			
		||||
        return properties.getProperty(name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -24,6 +24,7 @@ import com.google.inject.Guice;
 | 
			
		||||
import com.google.inject.Injector;
 | 
			
		||||
import com.google.inject.Stage;
 | 
			
		||||
import com.google.inject.servlet.GuiceServletContextListener;
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.concurrent.atomic.AtomicReference;
 | 
			
		||||
import javax.inject.Inject;
 | 
			
		||||
@@ -33,6 +34,8 @@ import org.apache.guacamole.environment.LocalEnvironment;
 | 
			
		||||
import org.apache.guacamole.extension.ExtensionModule;
 | 
			
		||||
import org.apache.guacamole.log.LogModule;
 | 
			
		||||
import org.apache.guacamole.net.auth.AuthenticationProvider;
 | 
			
		||||
import org.apache.guacamole.properties.BooleanGuacamoleProperty;
 | 
			
		||||
import org.apache.guacamole.properties.FileGuacamoleProperties;
 | 
			
		||||
import org.apache.guacamole.rest.RESTServiceModule;
 | 
			
		||||
import org.apache.guacamole.rest.auth.HashTokenSessionMap;
 | 
			
		||||
import org.apache.guacamole.rest.auth.TokenSessionMap;
 | 
			
		||||
@@ -86,6 +89,18 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener
 | 
			
		||||
     */
 | 
			
		||||
    private final Logger logger = LoggerFactory.getLogger(GuacamoleServletContextListener.class);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A property that determines whether environment variables are evaluated
 | 
			
		||||
     * to override properties specified in guacamole.properties.
 | 
			
		||||
     */
 | 
			
		||||
    private static final BooleanGuacamoleProperty ENABLE_ENVIRONMENT_PROPERTIES =
 | 
			
		||||
        new BooleanGuacamoleProperty() {
 | 
			
		||||
            @Override
 | 
			
		||||
            public String getName() {
 | 
			
		||||
                return "enable-environment-properties";
 | 
			
		||||
            }
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The Guacamole server environment.
 | 
			
		||||
     */
 | 
			
		||||
@@ -111,16 +126,38 @@ public class GuacamoleServletContextListener extends GuiceServletContextListener
 | 
			
		||||
    @Override
 | 
			
		||||
    public void contextInitialized(ServletContextEvent servletContextEvent) {
 | 
			
		||||
 | 
			
		||||
        environment = LocalEnvironment.getInstance();
 | 
			
		||||
 | 
			
		||||
        // Read configuration information from GUACAMOLE_HOME/guacamole.properties
 | 
			
		||||
        try {
 | 
			
		||||
            environment = new LocalEnvironment();
 | 
			
		||||
            sessionMap = new HashTokenSessionMap(environment);
 | 
			
		||||
            File guacProperties = new File(environment.getGuacamoleHome(), "guacamole.properties");
 | 
			
		||||
            environment.addGuacamoleProperties(new FileGuacamoleProperties(guacProperties));
 | 
			
		||||
            logger.info("Read configuration parameters from \"{}\".", guacProperties);
 | 
			
		||||
        }
 | 
			
		||||
        catch (GuacamoleException e) {
 | 
			
		||||
            logger.error("Unable to read guacamole.properties: {}", e.getMessage());
 | 
			
		||||
            logger.debug("Error reading guacamole.properties.", e);
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // For any values not defined in GUACAMOLE_HOME/guacamole.properties,
 | 
			
		||||
        // read from system environment if "enable-environment-properties" is
 | 
			
		||||
        // set to "true"
 | 
			
		||||
        try {
 | 
			
		||||
            if (environment.getProperty(ENABLE_ENVIRONMENT_PROPERTIES, false)) {
 | 
			
		||||
                environment.addGuacamoleProperties(new SystemEnvironmentGuacamoleProperties());
 | 
			
		||||
                logger.info("Additional configuration parameters may be read "
 | 
			
		||||
                        + "from environment variables.");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        catch (GuacamoleException e) {
 | 
			
		||||
            logger.error("Unable to configure support for environment properties: {}", e.getMessage());
 | 
			
		||||
            logger.debug("Error reading \"{}\" property from guacamole.properties.", ENABLE_ENVIRONMENT_PROPERTIES.getName(), e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Now that at least the main guacamole.properties source of
 | 
			
		||||
        // configuration information is available, initialize the session map
 | 
			
		||||
        sessionMap = new HashTokenSessionMap(environment);
 | 
			
		||||
 | 
			
		||||
        // NOTE: The superclass implementation of contextInitialized() is
 | 
			
		||||
        // expected to invoke getInjector(), hence the need to call AFTER
 | 
			
		||||
        // setting up the environment and session map
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,38 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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;
 | 
			
		||||
 | 
			
		||||
import org.apache.guacamole.properties.GuacamoleProperties;
 | 
			
		||||
import org.apache.guacamole.token.TokenName;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * GuacamoleProperties implementation which reads all properties from
 | 
			
		||||
 * environment variables. The name of the environment variable corresponding to
 | 
			
		||||
 * any particular property is determined using
 | 
			
		||||
 * {@link TokenName#canonicalize(java.lang.String)}.
 | 
			
		||||
 */
 | 
			
		||||
public class SystemEnvironmentGuacamoleProperties implements GuacamoleProperties {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getProperty(String name) {
 | 
			
		||||
        return System.getenv(TokenName.canonicalize(name));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -63,25 +63,13 @@ public class FileAuthenticationProvider extends SimpleAuthenticationProvider {
 | 
			
		||||
    /**
 | 
			
		||||
     * Guacamole server environment.
 | 
			
		||||
     */
 | 
			
		||||
    private final Environment environment;
 | 
			
		||||
    private final Environment environment = LocalEnvironment.getInstance();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The filename to use for the user mapping.
 | 
			
		||||
     */
 | 
			
		||||
    public static final String USER_MAPPING_FILENAME = "user-mapping.xml";
 | 
			
		||||
    
 | 
			
		||||
    /**
 | 
			
		||||
     * Creates a new FileAuthenticationProvider that authenticates users against
 | 
			
		||||
     * simple, monolithic XML file.
 | 
			
		||||
     *
 | 
			
		||||
     * @throws GuacamoleException
 | 
			
		||||
     *     If a required property is missing, or an error occurs while parsing
 | 
			
		||||
     *     a property.
 | 
			
		||||
     */
 | 
			
		||||
    public FileAuthenticationProvider() throws GuacamoleException {
 | 
			
		||||
        environment = new LocalEnvironment();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getIdentifier() {
 | 
			
		||||
        return "default";
 | 
			
		||||
 
 | 
			
		||||
@@ -171,7 +171,7 @@ public class SchemaResource {
 | 
			
		||||
    public Map<String, ProtocolInfo> getProtocols() throws GuacamoleException {
 | 
			
		||||
 | 
			
		||||
        // Get and return a map of all protocols.
 | 
			
		||||
        Environment env = new LocalEnvironment();
 | 
			
		||||
        Environment env = LocalEnvironment.getInstance();
 | 
			
		||||
        return env.getProtocols();
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user