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

Reply via email to