GUACAMOLE-189: Allow per-connection guacd parameters for the JDBC auth.
Project: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/commit/152de87d Tree: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/tree/152de87d Diff: http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/diff/152de87d Branch: refs/heads/master Commit: 152de87dc21260c3a9f25c1a0e9eee78900a3cda Parents: 1c0ee41 Author: Michael Jumper <[email protected]> Authored: Sat Oct 22 20:19:18 2016 -0700 Committer: Michael Jumper <[email protected]> Committed: Thu May 4 21:32:23 2017 -0700 ---------------------------------------------------------------------- .../guacamole/auth/jdbc/JDBCEnvironment.java | 38 +++++ .../auth/jdbc/connection/ConnectionModel.java | 92 ++++++++++++ .../connection/GuacamoleProxyConfiguration.java | 132 +++++++++++++++++ .../auth/jdbc/connection/ModeledConnection.java | 140 ++++++++++++++++++- .../tunnel/AbstractGuacamoleTunnelService.java | 77 +++++----- .../src/main/resources/translations/en.json | 11 +- .../schema/upgrade/upgrade-pre-0.9.13.sql | 30 ++++ .../auth/jdbc/connection/ConnectionMapper.xml | 34 ++++- .../schema/upgrade/upgrade-pre-0.9.13.sql | 35 +++++ .../auth/jdbc/connection/ConnectionMapper.xml | 34 ++++- 10 files changed, 572 insertions(+), 51 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/152de87d/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/JDBCEnvironment.java ---------------------------------------------------------------------- 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 dfbf0e9..52aed03 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 @@ -20,6 +20,8 @@ package org.apache.guacamole.auth.jdbc; import org.apache.guacamole.GuacamoleException; +import org.apache.guacamole.auth.jdbc.connection.GuacamoleProxyConfiguration; +import org.apache.guacamole.environment.Environment; import org.apache.guacamole.environment.LocalEnvironment; import org.apache.guacamole.auth.jdbc.security.PasswordPolicy; @@ -30,6 +32,18 @@ import org.apache.guacamole.auth.jdbc.security.PasswordPolicy; public abstract class JDBCEnvironment extends LocalEnvironment { /** + * The hostname to use when connecting to guacd if no hostname is provided + * within guacamole.properties. + */ + private static final String DEFAULT_GUACD_HOSTNAME = "localhost"; + + /** + * The port to use when connecting to guacd if no port is provided within + * guacamole.properties. + */ + private static final int DEFAULT_GUACD_PORT = 4822; + + /** * Constructs a new JDBCEnvironment using an underlying LocalEnviroment to * read properties from the file system. * @@ -41,6 +55,30 @@ public abstract class JDBCEnvironment extends LocalEnvironment { } /** + * Returns the connection information which should be used, by default, to + * connect to guacd when establishing a remote desktop connection. + * + * @return + * The connection information which should be used, by default, to + * connect to guacd. + * + * @throws GuacamoleException + * If the properties describing the connection information for guacd + * cannot be parsed. + */ + public GuacamoleProxyConfiguration getDefaultGuacamoleProxyConfiguration() + throws GuacamoleException { + + // Parse guacd hostname/port/ssl properties + return new GuacamoleProxyConfiguration( + getProperty(Environment.GUACD_HOSTNAME, DEFAULT_GUACD_HOSTNAME), + getProperty(Environment.GUACD_PORT, DEFAULT_GUACD_PORT), + getProperty(Environment.GUACD_SSL, false) + ); + + } + + /** * Returns whether a database user account is required for authentication to * succeed, even if another authentication provider has already * authenticated the user. http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/152de87d/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionModel.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionModel.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionModel.java index ac10455..92346b7 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionModel.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ConnectionModel.java @@ -22,6 +22,7 @@ package org.apache.guacamole.auth.jdbc.connection; import java.util.HashSet; import java.util.Set; import org.apache.guacamole.auth.jdbc.base.ChildObjectModel; +import org.apache.guacamole.auth.jdbc.connection.GuacamoleProxyConfiguration.EncryptionMethod; /** * Object representation of a Guacamole connection, as represented in the @@ -60,6 +61,24 @@ public class ConnectionModel extends ChildObjectModel { private Set<String> sharingProfileIdentifiers = new HashSet<String>(); /** + * The hostname of the guacd instance to use, or null if the hostname of the + * default guacd instance should be used. + */ + private String proxyHostname; + + /** + * The port of the guacd instance to use, or null if the port of the default + * guacd instance should be used. + */ + private Integer proxyPort; + + /** + * The encryption method required by the desired guacd instance, or null if + * the encryption method of the default guacd instance should be used. + */ + private EncryptionMethod proxyEncryptionMethod; + + /** * Creates a new, empty connection. */ public ConnectionModel() { @@ -159,6 +178,79 @@ public class ConnectionModel extends ChildObjectModel { } /** + * Returns the hostname of the guacd instance to use. If the hostname of the + * default guacd instance should be used instead, null is returned. + * + * @return + * The hostname of the guacd instance to use, or null if the hostname + * of the default guacd instance should be used. + */ + public String getProxyHostname() { + return proxyHostname; + } + + /** + * Sets the hostname of the guacd instance to use. + * + * @param proxyHostname + * The hostname of the guacd instance to use, or null if the hostname + * of the default guacd instance should be used. + */ + public void setProxyHostname(String proxyHostname) { + this.proxyHostname = proxyHostname; + } + + /** + * Returns the port of the guacd instance to use. If the port of the default + * guacd instance should be used instead, null is returned. + * + * @return + * The port of the guacd instance to use, or null if the port of the + * default guacd instance should be used. + */ + public Integer getProxyPort() { + return proxyPort; + } + + /** + * Sets the port of the guacd instance to use. + * + * @param proxyPort + * The port of the guacd instance to use, or null if the port of the + * default guacd instance should be used. + */ + public void setProxyPort(Integer proxyPort) { + this.proxyPort = proxyPort; + } + + /** + * Returns the type of encryption required by the desired guacd instance. + * If the encryption method of the default guacd instance should be used + * instead, null is returned. + * + * @return + * The type of encryption required by the desired guacd instance, or + * null if the encryption method of the default guacd instance should + * be used. + */ + public EncryptionMethod getProxyEncryptionMethod() { + return proxyEncryptionMethod; + } + + /** + * Sets the type of encryption which should be used when connecting to + * guacd, if any. + * + * @param proxyEncryptionMethod + * The type of encryption required by the desired guacd instance, or + * null if the encryption method of the default guacd instance should + * be used. + */ + public void setProxyEncryptionMethod(EncryptionMethod proxyEncryptionMethod) { + this.proxyEncryptionMethod = proxyEncryptionMethod; + } + + /** * Returns the identifiers of all readable sharing profiles associated with * this connection. This is set only when the connection is queried, and has * no effect when a connection is inserted, updated, or deleted. http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/152de87d/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/GuacamoleProxyConfiguration.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/GuacamoleProxyConfiguration.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/GuacamoleProxyConfiguration.java new file mode 100644 index 0000000..28d02e8 --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/GuacamoleProxyConfiguration.java @@ -0,0 +1,132 @@ +/* + * 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.connection; + +/** + * Information which describes how the connection to guacd should be + * established. This includes the hostname and port which guacd is listening on, + * as well as the type of encryption required, if any. + * + * @author Michael Jumper + */ +public class GuacamoleProxyConfiguration { + + /** + * All possible types of encryption used by guacd. + */ + public enum EncryptionMethod { + + /** + * Unencrypted (plaintext). + */ + NONE, + + /** + * Encrypted with SSL or TLS. + */ + SSL + + } + + /** + * The hostname or address of the machine where guacd is running. + */ + private final String hostname; + + /** + * The port that guacd is listening on. + */ + private final int port; + + /** + * The type of encryption required by guacd. + */ + private final EncryptionMethod encryptionMethod; + + /** + * Creates a new GuacamoleProxyConfiguration having the given hostname, + * port, and encryption method. + * + * @param hostname + * The hostname or address of the machine where guacd is running. + * + * @param port + * The port that guacd is listening on. + * + * @param encryptionMethod + * The type of encryption required by the instance of guacd running at + * the given hostname and port. + */ + public GuacamoleProxyConfiguration(String hostname, int port, + EncryptionMethod encryptionMethod) { + this.hostname = hostname; + this.port = port; + this.encryptionMethod = encryptionMethod; + } + + /** + * Creates a new GuacamoleProxyConfiguration having the given hostname and + * port, with encryption method being restricted to either NONE or SSL. + * + * @param hostname + * The hostname or address of the machine where guacd is running. + * + * @param port + * The port that guacd is listening on. + * + * @param ssl + * true if guacd requires SSL/TLS encryption, false if communication + * with guacd should be unencrypted. + */ + public GuacamoleProxyConfiguration(String hostname, int port, boolean ssl) { + this(hostname, port, ssl ? EncryptionMethod.SSL : EncryptionMethod.NONE); + } + + /** + * Returns the hostname or address of the machine where guacd is running. + * + * @return + * The hostname or address of the machine where guacd is running. + */ + public String getHostname() { + return hostname; + } + + /** + * Returns the port that guacd is listening on. + * + * @return + * The port that guacd is listening on. + */ + public int getPort() { + return port; + } + + /** + * Returns the type of encryption required by guacd. + * + * @return + * The type of encryption required by guacd. + */ + public EncryptionMethod getEncryptionMethod() { + return encryptionMethod; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/152de87d/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java index cbfdb68..2de235c 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/connection/ModeledConnection.java @@ -32,9 +32,12 @@ import org.apache.guacamole.auth.jdbc.tunnel.GuacamoleTunnelService; import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.apache.guacamole.auth.jdbc.base.ModeledChildDirectoryObject; +import org.apache.guacamole.auth.jdbc.connection.GuacamoleProxyConfiguration.EncryptionMethod; +import org.apache.guacamole.form.EnumField; import org.apache.guacamole.form.Field; import org.apache.guacamole.form.Form; import org.apache.guacamole.form.NumericField; +import org.apache.guacamole.form.TextField; import org.apache.guacamole.net.GuacamoleTunnel; import org.apache.guacamole.net.auth.Connection; import org.apache.guacamole.net.auth.ConnectionRecord; @@ -56,6 +59,51 @@ public class ModeledConnection extends ModeledChildDirectoryObject<ConnectionMod private static final Logger logger = LoggerFactory.getLogger(ModeledConnection.class); /** + * The name of the attribute which overrides the hostname used to connect + * to guacd for this connection. + */ + public static final String GUACD_HOSTNAME_NAME = "guacd-hostname"; + + /** + * The name of the attribute which overrides the port used to connect to + * guacd for this connection. + */ + public static final String GUACD_PORT_NAME = "guacd-port"; + + /** + * The name of the attribute which overrides the encryption method used to + * connect to guacd for this connection. + */ + public static final String GUACD_ENCRYPTION_NAME = "guacd-encryption"; + + /** + * The value specified for the "guacd-encryption" attribute if encryption + * should not be used to connect to guacd. + */ + public static final String GUACD_ENCRYPTION_VALUE_NONE = "none"; + + /** + * The value specified for the "guacd-encryption" attribute if SSL/TLS + * encryption should be used to connect to guacd. + */ + public static final String GUACD_ENCRYPTION_VALUE_SSL = "ssl"; + + /** + * All attributes which describe the configuration of the guacd instance + * which will be used to connect to the remote desktop described by this + * connection. + */ + public static final Form GUACD_PARAMETERS = new Form("guacd", Arrays.<Field>asList( + new TextField(GUACD_HOSTNAME_NAME), + new NumericField(GUACD_PORT_NAME), + new EnumField(GUACD_ENCRYPTION_NAME, Arrays.asList( + "", + GUACD_ENCRYPTION_VALUE_NONE, + GUACD_ENCRYPTION_VALUE_SSL + )) + )); + + /** * The name of the attribute which controls the maximum number of * concurrent connections. */ @@ -81,7 +129,8 @@ public class ModeledConnection extends ModeledChildDirectoryObject<ConnectionMod * logical forms. */ public static final Collection<Form> ATTRIBUTES = Collections.unmodifiableCollection(Arrays.asList( - CONCURRENCY_LIMITS + CONCURRENCY_LIMITS, + GUACD_PARAMETERS )); /** @@ -186,6 +235,35 @@ public class ModeledConnection extends ModeledChildDirectoryObject<ConnectionMod // Set per-user connection limit attribute attributes.put(MAX_CONNECTIONS_PER_USER_NAME, NumericField.format(getModel().getMaxConnectionsPerUser())); + // Set guacd (proxy) hostname and port + attributes.put(GUACD_HOSTNAME_NAME, getModel().getProxyHostname()); + attributes.put(GUACD_PORT_NAME, NumericField.format(getModel().getProxyPort())); + + // Set guacd (proxy) encryption method + EncryptionMethod encryptionMethod = getModel().getProxyEncryptionMethod(); + if (encryptionMethod == null) + attributes.put(GUACD_ENCRYPTION_NAME, null); + + else { + switch (encryptionMethod) { + + // Unencrypted + case NONE: + attributes.put(GUACD_ENCRYPTION_NAME, GUACD_ENCRYPTION_VALUE_NONE); + break; + + // SSL / TLS encryption + case SSL: + attributes.put(GUACD_ENCRYPTION_NAME, GUACD_ENCRYPTION_VALUE_SSL); + break; + + // Unimplemented / unspecified + default: + attributes.put(GUACD_ENCRYPTION_NAME, null); + + } + } + return attributes; } @@ -206,6 +284,31 @@ public class ModeledConnection extends ModeledChildDirectoryObject<ConnectionMod logger.debug("Unable to parse numeric attribute.", e); } + // Set guacd hostname (no translation necessary) + getModel().setProxyHostname(attributes.get(GUACD_HOSTNAME_NAME)); + + // Translate guacd port + try { getModel().setProxyPort(NumericField.parse(attributes.get(GUACD_PORT_NAME))); } + catch (NumberFormatException e) { + logger.warn("Not setting guacd port: {}", e.getMessage()); + logger.debug("Unable to parse numeric attribute.", e); + } + + // Translate guacd encryption method + String encryptionMethod = attributes.get(GUACD_ENCRYPTION_NAME); + + // Unencrypted + if (GUACD_ENCRYPTION_VALUE_NONE.equals(encryptionMethod)) + getModel().setProxyEncryptionMethod(EncryptionMethod.NONE); + + // SSL / TLS + else if (GUACD_ENCRYPTION_VALUE_SSL.equals(encryptionMethod)) + getModel().setProxyEncryptionMethod(EncryptionMethod.SSL); + + // Unimplemented / unspecified + else + getModel().setProxyEncryptionMethod(null); + } /** @@ -257,4 +360,39 @@ public class ModeledConnection extends ModeledChildDirectoryObject<ConnectionMod } + /** + * Returns the connection information which should be used to connect to + * guacd when establishing a connection to the remote desktop described by + * this connection. If no such information is defined for this specific + * remote desktop connection, the default guacd connection information will + * be used instead, as defined by JDBCEnvironment. + * + * @return + * The connection information which should be used to connect to guacd + * when establishing a connection to the remote desktop described by + * this connection. + * + * @throws GuacamoleException + * If the connection information for guacd cannot be parsed. + */ + public GuacamoleProxyConfiguration getGuacamoleProxyConfiguration() + throws GuacamoleException { + + // Retrieve default proxy configuration from environment + GuacamoleProxyConfiguration defaultConfig = environment.getDefaultGuacamoleProxyConfiguration(); + + // Retrieve proxy configuration overrides from model + String hostname = getModel().getProxyHostname(); + Integer port = getModel().getProxyPort(); + EncryptionMethod encryptionMethod = getModel().getProxyEncryptionMethod(); + + // Produce new proxy configuration from model, using defaults where unspecified + return new GuacamoleProxyConfiguration( + hostname != null ? hostname : defaultConfig.getHostname(), + port != null ? port : defaultConfig.getPort(), + encryptionMethod != null ? encryptionMethod : defaultConfig.getEncryptionMethod() + ); + + } + } http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/152de87d/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java index 043029c..abdeaff 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/java/org/apache/guacamole/auth/jdbc/tunnel/AbstractGuacamoleTunnelService.java @@ -42,10 +42,10 @@ import org.apache.guacamole.GuacamoleException; import org.apache.guacamole.GuacamoleResourceConflictException; import org.apache.guacamole.GuacamoleResourceNotFoundException; import org.apache.guacamole.GuacamoleSecurityException; +import org.apache.guacamole.GuacamoleServerException; import org.apache.guacamole.GuacamoleUpstreamException; import org.apache.guacamole.auth.jdbc.JDBCEnvironment; import org.apache.guacamole.auth.jdbc.connection.ConnectionMapper; -import org.apache.guacamole.environment.Environment; import org.apache.guacamole.net.GuacamoleSocket; import org.apache.guacamole.net.GuacamoleTunnel; import org.apache.guacamole.net.auth.Connection; @@ -57,6 +57,7 @@ import org.apache.guacamole.token.StandardTokens; import org.apache.guacamole.token.TokenFilter; import org.mybatis.guice.transactional.Transactional; import org.apache.guacamole.auth.jdbc.connection.ConnectionParameterMapper; +import org.apache.guacamole.auth.jdbc.connection.GuacamoleProxyConfiguration; import org.apache.guacamole.auth.jdbc.sharing.connection.SharedConnectionDefinition; import org.apache.guacamole.auth.jdbc.sharingprofile.ModeledSharingProfile; import org.apache.guacamole.auth.jdbc.sharingprofile.SharingProfileParameterMapper; @@ -80,12 +81,6 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS private final Logger logger = LoggerFactory.getLogger(AbstractGuacamoleTunnelService.class); /** - * The environment of the Guacamole server. - */ - @Inject - private JDBCEnvironment environment; - - /** * Mapper for accessing connections. */ @Inject @@ -122,18 +117,6 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS private Provider<ActiveConnectionRecord> activeConnectionRecordProvider; /** - * The hostname to use when connecting to guacd if no hostname is provided - * within guacamole.properties. - */ - private static final String DEFAULT_GUACD_HOSTNAME = "localhost"; - - /** - * The port to use when connecting to guacd if no port is provided within - * guacamole.properties. - */ - private static final int DEFAULT_GUACD_PORT = 4822; - - /** * All active connections through the tunnel having a given UUID. */ private final Map<String, ActiveConnectionRecord> activeTunnels = @@ -333,6 +316,13 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS * Returns an unconfigured GuacamoleSocket that is already connected to * guacd as specified in guacamole.properties, using SSL if necessary. * + * @param proxyConfig + * The configuration information to use when connecting to guacd. + * + * @param socketClosedCallback + * The callback which should be invoked whenever the returned socket + * closes. + * * @return * An unconfigured GuacamoleSocket, already connected to guacd. * @@ -340,23 +330,33 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS * If an error occurs while connecting to guacd, or while parsing * guacd-related properties. */ - private GuacamoleSocket getUnconfiguredGuacamoleSocket(Runnable socketClosedCallback) - throws GuacamoleException { + private GuacamoleSocket getUnconfiguredGuacamoleSocket( + GuacamoleProxyConfiguration proxyConfig, + Runnable socketClosedCallback) throws GuacamoleException { + + // Select socket type depending on desired encryption + switch (proxyConfig.getEncryptionMethod()) { + + // Use SSL if requested + case SSL: + return new ManagedSSLGuacamoleSocket( + proxyConfig.getHostname(), + proxyConfig.getPort(), + socketClosedCallback + ); + + // Use straight TCP if unencrypted + case NONE: + return new ManagedInetGuacamoleSocket( + proxyConfig.getHostname(), + proxyConfig.getPort(), + socketClosedCallback + ); - // Use SSL if requested - if (environment.getProperty(Environment.GUACD_SSL, false)) - return new ManagedSSLGuacamoleSocket( - environment.getProperty(Environment.GUACD_HOSTNAME, DEFAULT_GUACD_HOSTNAME), - environment.getProperty(Environment.GUACD_PORT, DEFAULT_GUACD_PORT), - socketClosedCallback - ); - - // Otherwise, just use straight TCP - return new ManagedInetGuacamoleSocket( - environment.getProperty(Environment.GUACD_HOSTNAME, DEFAULT_GUACD_HOSTNAME), - environment.getProperty(Environment.GUACD_PORT, DEFAULT_GUACD_PORT), - socketClosedCallback - ); + } + + // Bail out if encryption method is unknown + throw new GuacamoleServerException("Unimplemented encryption method."); } @@ -472,10 +472,12 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS GuacamoleConfiguration config; + // Retrieve connection information associated with given connection record + ModeledConnection connection = activeConnection.getConnection(); + // Pull configuration directly from the connection if we are not // joining an active connection if (activeConnection.isPrimaryConnection()) { - ModeledConnection connection = activeConnection.getConnection(); activeConnections.put(connection.getIdentifier(), activeConnection); activeConnectionGroups.put(connection.getParentIdentifier(), activeConnection); config = getGuacamoleConfiguration(activeConnection.getUser(), connection); @@ -499,7 +501,8 @@ public abstract class AbstractGuacamoleTunnelService implements GuacamoleTunnelS // Obtain socket which will automatically run the cleanup task ConfiguredGuacamoleSocket socket = new ConfiguredGuacamoleSocket( - getUnconfiguredGuacamoleSocket(cleanupTask), config, info); + getUnconfiguredGuacamoleSocket(connection.getGuacamoleProxyConfiguration(), + cleanupTask), config, info); // Assign and return new tunnel if (interceptErrors) http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/152de87d/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json index 78728c3..f182aac 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-base/src/main/resources/translations/en.json @@ -20,7 +20,16 @@ "FIELD_HEADER_MAX_CONNECTIONS" : "Maximum number of connections:", "FIELD_HEADER_MAX_CONNECTIONS_PER_USER" : "Maximum number of connections per user:", - "SECTION_HEADER_CONCURRENCY" : "Concurrency Limits" + "FIELD_HEADER_GUACD_HOSTNAME" : "Hostname:", + "FIELD_HEADER_GUACD_ENCRYPTION" : "Encryption:", + "FIELD_HEADER_GUACD_PORT" : "Port:", + + "FIELD_OPTION_GUACD_ENCRYPTION_EMPTY" : "", + "FIELD_OPTION_GUACD_ENCRYPTION_NONE" : "None (unencrypted)", + "FIELD_OPTION_GUACD_ENCRYPTION_SSL" : "SSL / TLS", + + "SECTION_HEADER_CONCURRENCY" : "Concurrency Limits", + "SECTION_HEADER_GUACD" : "Guacamole Proxy Parameters (guacd)" }, http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/152de87d/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.13.sql ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.13.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.13.sql new file mode 100644 index 0000000..bb37c6c --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/schema/upgrade/upgrade-pre-0.9.13.sql @@ -0,0 +1,30 @@ +-- +-- 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. +-- + +-- +-- Add guacd per-connection override columns +-- + +ALTER TABLE guacamole_connection ADD COLUMN proxy_port INT(11); +ALTER TABLE guacamole_connection ADD COLUMN proxy_hostname VARCHAR(512); + +ALTER TABLE guacamole_connection ADD COLUMN proxy_encryption_method ENUM( + 'NONE', + 'SSL' +); http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/152de87d/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml index 0fd0265..e4b5294 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-mysql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml @@ -33,6 +33,10 @@ <result column="protocol" property="protocol" jdbcType="VARCHAR"/> <result column="max_connections" property="maxConnections" jdbcType="INTEGER"/> <result column="max_connections_per_user" property="maxConnectionsPerUser" jdbcType="INTEGER"/> + <result column="proxy_hostname" property="proxyHostname" jdbcType="VARCHAR"/> + <result column="proxy_port" property="proxyPort" jdbcType="INTEGER"/> + <result column="proxy_encryption_method" property="proxyEncryptionMethod" jdbcType="VARCHAR" + javaType="org.apache.guacamole.auth.jdbc.connection.GuacamoleProxyConfiguration$EncryptionMethod"/> <!-- Associated sharing profiles --> <collection property="sharingProfileIdentifiers" resultSet="sharingProfiles" ofType="java.lang.String" @@ -88,7 +92,10 @@ parent_id, protocol, max_connections, - max_connections_per_user + max_connections_per_user, + proxy_hostname, + proxy_port, + proxy_encryption_method FROM guacamole_connection WHERE connection_id IN <foreach collection="identifiers" item="identifier" @@ -116,7 +123,10 @@ parent_id, protocol, max_connections, - max_connections_per_user + max_connections_per_user, + proxy_hostname, + proxy_port, + proxy_encryption_method FROM guacamole_connection JOIN guacamole_connection_permission ON guacamole_connection_permission.connection_id = guacamole_connection.connection_id WHERE guacamole_connection.connection_id IN @@ -149,7 +159,10 @@ parent_id, protocol, max_connections, - max_connections_per_user + max_connections_per_user, + proxy_hostname, + proxy_port, + proxy_encryption_method FROM guacamole_connection WHERE <if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=VARCHAR}</if> @@ -173,14 +186,20 @@ parent_id, protocol, max_connections, - max_connections_per_user + max_connections_per_user, + proxy_hostname, + proxy_port, + proxy_encryption_method ) VALUES ( #{object.name,jdbcType=VARCHAR}, #{object.parentIdentifier,jdbcType=VARCHAR}, #{object.protocol,jdbcType=VARCHAR}, #{object.maxConnections,jdbcType=INTEGER}, - #{object.maxConnectionsPerUser,jdbcType=INTEGER} + #{object.maxConnectionsPerUser,jdbcType=INTEGER}, + #{object.proxyHostname,jdbcType=VARCHAR}, + #{object.proxyPort,jdbcType=INTEGER}, + #{object.proxyEncryptionMethod,jdbcType=VARCHAR} ) </insert> @@ -192,7 +211,10 @@ parent_id = #{object.parentIdentifier,jdbcType=VARCHAR}, protocol = #{object.protocol,jdbcType=VARCHAR}, max_connections = #{object.maxConnections,jdbcType=INTEGER}, - max_connections_per_user = #{object.maxConnectionsPerUser,jdbcType=INTEGER} + max_connections_per_user = #{object.maxConnectionsPerUser,jdbcType=INTEGER}, + proxy_hostname = #{object.proxyHostname,jdbcType=VARCHAR}, + proxy_port = #{object.proxyPort,jdbcType=INTEGER}, + proxy_encryption_method = #{object.proxyEncryptionMethod,jdbcType=VARCHAR} WHERE connection_id = #{object.objectID,jdbcType=INTEGER} </update> http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/152de87d/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.13.sql ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.13.sql b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.13.sql new file mode 100644 index 0000000..015ec9a --- /dev/null +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/schema/upgrade/upgrade-pre-0.9.13.sql @@ -0,0 +1,35 @@ +-- +-- 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. +-- + +-- +-- Add new guacd encryption method type +-- + +CREATE TYPE guacamole_proxy_encryption_method AS ENUM( + 'NONE', + 'SSL' +); + +-- +-- Add guacd per-connection override columns +-- + +ALTER TABLE guacamole_connection ADD COLUMN proxy_port integer; +ALTER TABLE guacamole_connection ADD COLUMN proxy_hostname varchar(512); +ALTER TABLE guacamole_connection ADD COLUMN proxy_encryption_method guacamole_proxy_encryption_method; http://git-wip-us.apache.org/repos/asf/incubator-guacamole-client/blob/152de87d/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml ---------------------------------------------------------------------- diff --git a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml index 5fe9de4..aedd86b 100644 --- a/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml +++ b/extensions/guacamole-auth-jdbc/modules/guacamole-auth-jdbc-postgresql/src/main/resources/org/apache/guacamole/auth/jdbc/connection/ConnectionMapper.xml @@ -33,6 +33,10 @@ <result column="protocol" property="protocol" jdbcType="VARCHAR"/> <result column="max_connections" property="maxConnections" jdbcType="INTEGER"/> <result column="max_connections_per_user" property="maxConnectionsPerUser" jdbcType="INTEGER"/> + <result column="proxy_hostname" property="proxyHostname" jdbcType="VARCHAR"/> + <result column="proxy_port" property="proxyPort" jdbcType="INTEGER"/> + <result column="proxy_encryption_method" property="proxyEncryptionMethod" jdbcType="VARCHAR" + javaType="org.apache.guacamole.auth.jdbc.connection.GuacamoleProxyConfiguration$EncryptionMethod"/> <!-- Associated sharing profiles --> <collection property="sharingProfileIdentifiers" resultSet="sharingProfiles" ofType="java.lang.String" @@ -88,7 +92,10 @@ parent_id, protocol, max_connections, - max_connections_per_user + max_connections_per_user, + proxy_hostname, + proxy_port, + proxy_encryption_method FROM guacamole_connection WHERE connection_id IN <foreach collection="identifiers" item="identifier" @@ -116,7 +123,10 @@ parent_id, protocol, max_connections, - max_connections_per_user + max_connections_per_user, + proxy_hostname, + proxy_port, + proxy_encryption_method FROM guacamole_connection JOIN guacamole_connection_permission ON guacamole_connection_permission.connection_id = guacamole_connection.connection_id WHERE guacamole_connection.connection_id IN @@ -149,7 +159,10 @@ parent_id, protocol, max_connections, - max_connections_per_user + max_connections_per_user, + proxy_hostname, + proxy_port, + proxy_encryption_method FROM guacamole_connection WHERE <if test="parentIdentifier != null">parent_id = #{parentIdentifier,jdbcType=INTEGER}::integer</if> @@ -173,14 +186,20 @@ parent_id, protocol, max_connections, - max_connections_per_user + max_connections_per_user, + proxy_hostname, + proxy_port, + proxy_encryption_method ) VALUES ( #{object.name,jdbcType=VARCHAR}, #{object.parentIdentifier,jdbcType=INTEGER}::integer, #{object.protocol,jdbcType=VARCHAR}, #{object.maxConnections,jdbcType=INTEGER}, - #{object.maxConnectionsPerUser,jdbcType=INTEGER} + #{object.maxConnectionsPerUser,jdbcType=INTEGER}, + #{object.proxyHostname,jdbcType=VARCHAR}, + #{object.proxyPort,jdbcType=INTEGER}, + #{object.proxyEncryptionMethod,jdbcType=VARCHAR}::guacamole_proxy_encryption_method ) </insert> @@ -192,7 +211,10 @@ parent_id = #{object.parentIdentifier,jdbcType=INTEGER}::integer, protocol = #{object.protocol,jdbcType=VARCHAR}, max_connections = #{object.maxConnections,jdbcType=INTEGER}, - max_connections_per_user = #{object.maxConnectionsPerUser,jdbcType=INTEGER} + max_connections_per_user = #{object.maxConnectionsPerUser,jdbcType=INTEGER}, + proxy_hostname = #{object.proxyHostname,jdbcType=VARCHAR}, + proxy_port = #{object.proxyPort,jdbcType=INTEGER}, + proxy_encryption_method = #{object.proxyEncryptionMethod,jdbcType=VARCHAR}::guacamole_proxy_encryption_method WHERE connection_id = #{object.objectID,jdbcType=INTEGER}::integer </update>
