From bcbac1fb57b4ed9fe8750cdc44895f1ac9d7e8ad Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 22 Jan 2019 15:49:16 -0800 Subject: [PATCH] GUACAMOLE-524: Ensure all guacamole-ext classes implementing connect() use the old connect() as their basis. Overriding the old connect() will not have the expected effect otherwise. --- .../net/auth/DelegatingConnection.java | 38 +++++++++++++++++- .../net/auth/DelegatingConnectionGroup.java | 39 ++++++++++++++++++- .../auth/simple/SimpleConnectionGroup.java | 13 +++++-- 3 files changed, 85 insertions(+), 5 deletions(-) diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnection.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnection.java index b80e8683a..95b6e9326 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnection.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnection.java @@ -19,6 +19,7 @@ package org.apache.guacamole.net.auth; +import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Map; @@ -39,6 +40,24 @@ public class DelegatingConnection implements Connection { */ private final Connection connection; + /** + * The tokens which should apply strictly to the next call to + * {@link #connect(org.apache.guacamole.protocol.GuacamoleClientInformation)}. + * This storage is intended as a temporary bridge allowing the old version + * of connect() to be overridden while still resulting in the same behavior + * as older versions of DelegatingConnection. This storage should be + * removed once support for the old, deprecated connect() is removed. + */ + private final ThreadLocal> currentTokens = + new ThreadLocal>() { + + @Override + protected Map initialValue() { + return Collections.emptyMap(); + } + + }; + /** * Wraps the given Connection such that all function calls against this * DelegatingConnection will be delegated to it. @@ -127,10 +146,27 @@ public class DelegatingConnection implements Connection { return connection.getSharingProfileIdentifiers(); } + @Override + @Deprecated + public GuacamoleTunnel connect(GuacamoleClientInformation info) + throws GuacamoleException { + return connection.connect(info, currentTokens.get()); + } + @Override public GuacamoleTunnel connect(GuacamoleClientInformation info, Map tokens) throws GuacamoleException { - return connection.connect(info, tokens); + + // Make received tokens available within the legacy connect() strictly + // in context of the current connect() call + try { + currentTokens.set(tokens); + return connect(info); + } + finally { + currentTokens.remove(); + } + } @Override diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnectionGroup.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnectionGroup.java index 1d958bdb2..5af6eb13e 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnectionGroup.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/DelegatingConnectionGroup.java @@ -19,6 +19,7 @@ package org.apache.guacamole.net.auth; +import java.util.Collections; import java.util.Map; import java.util.Set; import org.apache.guacamole.GuacamoleException; @@ -36,6 +37,25 @@ public class DelegatingConnectionGroup implements ConnectionGroup { */ private final ConnectionGroup connectionGroup; + /** + * The tokens which should apply strictly to the next call to + * {@link #connect(org.apache.guacamole.protocol.GuacamoleClientInformation)}. + * This storage is intended as a temporary bridge allowing the old version + * of connect() to be overridden while still resulting in the same behavior + * as older versions of DelegatingConnectionGroup. This storage + * should be removed once support for the old, deprecated connect() is + * removed. + */ + private final ThreadLocal> currentTokens = + new ThreadLocal>() { + + @Override + protected Map initialValue() { + return Collections.emptyMap(); + } + + }; + /** * Wraps the given ConnectionGroup such that all function calls against this * DelegatingConnectionGroup will be delegated to it. @@ -118,10 +138,27 @@ public class DelegatingConnectionGroup implements ConnectionGroup { connectionGroup.setAttributes(attributes); } + @Override + @Deprecated + public GuacamoleTunnel connect(GuacamoleClientInformation info) + throws GuacamoleException { + return connectionGroup.connect(info, currentTokens.get()); + } + @Override public GuacamoleTunnel connect(GuacamoleClientInformation info, Map tokens) throws GuacamoleException { - return connectionGroup.connect(info, tokens); + + // Make received tokens available within the legacy connect() strictly + // in context of the current connect() call + try { + currentTokens.set(tokens); + return connect(info); + } + finally { + currentTokens.remove(); + } + } @Override diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionGroup.java b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionGroup.java index a077eb312..b2f7de0ca 100644 --- a/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionGroup.java +++ b/guacamole-ext/src/main/java/org/apache/guacamole/net/auth/simple/SimpleConnectionGroup.java @@ -47,7 +47,7 @@ public class SimpleConnectionGroup extends AbstractConnectionGroup { * The identifiers of all connection groups in this group. */ private final Set connectionGroupIdentifiers; - + /** * Creates a new SimpleConnectionGroup having the given name and identifier * which will expose the given contents. @@ -109,9 +109,16 @@ public class SimpleConnectionGroup extends AbstractConnectionGroup { } @Override - public GuacamoleTunnel connect(GuacamoleClientInformation info, - Map tokens) throws GuacamoleException { + @Deprecated + public GuacamoleTunnel connect(GuacamoleClientInformation info) + throws GuacamoleException { throw new GuacamoleSecurityException("Permission denied."); } + @Override + public GuacamoleTunnel connect(GuacamoleClientInformation info, + Map tokens) throws GuacamoleException { + return connect(info); + } + }