On Mon, Sep 2, 2024 at 6:19 AM David Lomas <d...@pale-eds.co.uk.invalid> wrote:
> Hi Nick et al, > > It's me again :). We've got our interception of the guacamole connection > working to trigger our house-keeping (basically, setting up an app & > environment on the target machine). For reference, we're: > > - Providing a custom auth provider which uses our back-end to verify > credentials > - Providing our own AuthenticatedUser class which then uses the > 'decorate' method to generate a custom UserContext > - In our custom UserContext, we're overriding the following methods to > eventually get the DelegatingConnectionGroup 'connect()' method which lets > us get the tunnel id and connection id, and from that, the address of the > target machine > > Behind all that, we're using the JDBC balancing connection group feature > to actually go from authentication to a valid connection. But now we have a > problem if our housekeeping (at the 'connect()' level fails and we want the > balancing group to 'move on' to the next available connection. I can't work > out how we're supposed to signal this. The connect() method is supposed to > return a tunnel, which we get like this: > > public class CustomUserContext extends DelegatingUserContext { > > // initialisation, etc. > // . > // . > > @Override > public Directory<ConnectionGroup> getConnectionGroupDirectory() throws > GuacamoleException { > return new > DecoratingDirectory<ConnectionGroup>(super.getConnectionGroupDirectory()) { > @Override > protected ConnectionGroup decorate(ConnectionGroup > connectionGroup) throws GuacamoleException { > originalConnectionGroup = connectionGroup; > return new DelegatingConnectionGroup(connectionGroup) { > @Override > public GuacamoleTunnel connect(GuacamoleClientInformation > info, Map<String, String> tokens) throws GuacamoleException { > GuacamoleTunnel tunnel = super.connect(info, tokens); > > and it's only after this point that we can check if the 'housekeeping' was > successful (because only after this point can we get the remote endpoint > address). If that happens, I've tried throwing an exception and returning > null, but both just result in the front-end reporting "The Guacamole server > is denying access to this connection because you have exhausted the limit > for simultaneous connection use by an individual user. Please close one or > more connections and try again." > > Is it even possible to 'reject' the connection at this point? I couldn't > find in the source code where the underlying object actually makes the > connection and what it does in case of failure, and the GuacamoleTunnel > doesn't have a 'disconnect()' or similar method that I can see. Note the > user is correctly authenticated, so I don't want to abandon the whole > authentication flow, just this particular connection (as if it had not > responded at all, or was already in use by someone else). so that the > balancing group would try a different one. > > Sorry for the loooooong delay in getting back to you, David! There are a couple of ways you could reject the connection: * GuacamoleTunnel does have a "close()" method: https://github.com/apache/guacamole-client/blob/f95a218cc82eca8eee948b8e903cfef2b0da872a/guacamole-common/src/main/java/org/apache/guacamole/net/GuacamoleTunnel.java#L109-L115 * You also should be able to throw a GuacamoleException of some sort - something like GuacamoleSessionClosedException or GuacamoleUpstreamUnavailableException. There are a few possibilities. However, even throwing the Exception you'll likely want to use close() to clean up the tunnel and any associated resources. -Nick