mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-07 13:41:21 +00:00
GUACAMOLE-641: Allow vault implementations to automatically provide tokens based on connection parameters (without YAML mapping).
This commit is contained in:
@@ -26,10 +26,14 @@ import com.microsoft.azure.keyvault.KeyVaultClient;
|
|||||||
import com.microsoft.azure.keyvault.authentication.KeyVaultCredentials;
|
import com.microsoft.azure.keyvault.authentication.KeyVaultCredentials;
|
||||||
import com.microsoft.azure.keyvault.models.SecretBundle;
|
import com.microsoft.azure.keyvault.models.SecretBundle;
|
||||||
import com.microsoft.rest.ServiceCallback;
|
import com.microsoft.rest.ServiceCallback;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
|
import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
||||||
import org.apache.guacamole.vault.azure.conf.AzureKeyVaultAuthenticationException;
|
import org.apache.guacamole.vault.azure.conf.AzureKeyVaultAuthenticationException;
|
||||||
import org.apache.guacamole.vault.azure.conf.AzureKeyVaultConfigurationService;
|
import org.apache.guacamole.vault.azure.conf.AzureKeyVaultConfigurationService;
|
||||||
import org.apache.guacamole.vault.secret.CachedVaultSecretService;
|
import org.apache.guacamole.vault.secret.CachedVaultSecretService;
|
||||||
@@ -118,4 +122,10 @@ public class AzureKeyVaultSecretService extends CachedVaultSecretService {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Future<String>> getTokens(GuacamoleConfiguration config)
|
||||||
|
throws GuacamoleException {
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -19,8 +19,10 @@
|
|||||||
|
|
||||||
package org.apache.guacamole.vault.secret;
|
package org.apache.guacamole.vault.secret;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
|
import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic service for retrieving the value of a secret stored in a vault.
|
* Generic service for retrieving the value of a secret stored in a vault.
|
||||||
@@ -69,4 +71,29 @@ public interface VaultSecretService {
|
|||||||
*/
|
*/
|
||||||
Future<String> getValue(String name) throws GuacamoleException;
|
Future<String> getValue(String name) throws GuacamoleException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a map of token names to corresponding Futures which eventually
|
||||||
|
* complete with the value of that token, where each token is dynamically
|
||||||
|
* defined based on connection parameters. If a vault implementation allows
|
||||||
|
* for predictable secrets based on the parameters of a connection, this
|
||||||
|
* function should be implemented to provide automatic tokens for those
|
||||||
|
* secrets and remove the need for manual mapping via YAML.
|
||||||
|
*
|
||||||
|
* @param config
|
||||||
|
* The configuration of the Guacamole connection for which tokens are
|
||||||
|
* being generated. This configuration may be empty or partial,
|
||||||
|
* depending on the underlying implementation.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* A map of token names to their corresponding future values, where
|
||||||
|
* each token and value may be dynamically determined based on the
|
||||||
|
* connection configuration.
|
||||||
|
*
|
||||||
|
* @throws GuacamoleException
|
||||||
|
* If an error occurs producing the tokens and values required for the
|
||||||
|
* given configuration.
|
||||||
|
*/
|
||||||
|
Map<String, Future<String>> getTokens(GuacamoleConfiguration config)
|
||||||
|
throws GuacamoleException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -32,6 +32,7 @@ import org.apache.guacamole.net.auth.Connection;
|
|||||||
import org.apache.guacamole.net.auth.ConnectionGroup;
|
import org.apache.guacamole.net.auth.ConnectionGroup;
|
||||||
import org.apache.guacamole.net.auth.TokenInjectingUserContext;
|
import org.apache.guacamole.net.auth.TokenInjectingUserContext;
|
||||||
import org.apache.guacamole.net.auth.UserContext;
|
import org.apache.guacamole.net.auth.UserContext;
|
||||||
|
import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
||||||
import org.apache.guacamole.token.GuacamoleTokenUndefinedException;
|
import org.apache.guacamole.token.GuacamoleTokenUndefinedException;
|
||||||
import org.apache.guacamole.token.TokenFilter;
|
import org.apache.guacamole.token.TokenFilter;
|
||||||
import org.apache.guacamole.vault.conf.VaultConfigurationService;
|
import org.apache.guacamole.vault.conf.VaultConfigurationService;
|
||||||
@@ -188,6 +189,10 @@ public class VaultUserContext extends TokenInjectingUserContext {
|
|||||||
* may contain its own tokens, which will be substituted using values
|
* may contain its own tokens, which will be substituted using values
|
||||||
* from the given filter.
|
* from the given filter.
|
||||||
*
|
*
|
||||||
|
* @param config
|
||||||
|
* The GuacamoleConfiguration of the connection for which tokens are
|
||||||
|
* being retrieved, if available. This may be null.
|
||||||
|
*
|
||||||
* @param filter
|
* @param filter
|
||||||
* The filter to use to substitute values for tokens in the names of
|
* The filter to use to substitute values for tokens in the names of
|
||||||
* secrets to be retrieved from the vault.
|
* secrets to be retrieved from the vault.
|
||||||
@@ -202,7 +207,8 @@ public class VaultUserContext extends TokenInjectingUserContext {
|
|||||||
* vault due to an error.
|
* vault due to an error.
|
||||||
*/
|
*/
|
||||||
private Map<String, Future<String>> getTokens(Map<String, String> tokenMapping,
|
private Map<String, Future<String>> getTokens(Map<String, String> tokenMapping,
|
||||||
TokenFilter filter) throws GuacamoleException {
|
GuacamoleConfiguration config, TokenFilter filter)
|
||||||
|
throws GuacamoleException {
|
||||||
|
|
||||||
// Populate map with pending secret retrieval operations corresponding
|
// Populate map with pending secret retrieval operations corresponding
|
||||||
// to each mapped token
|
// to each mapped token
|
||||||
@@ -230,6 +236,9 @@ public class VaultUserContext extends TokenInjectingUserContext {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Additionally include any dynamic, parameter-based tokens
|
||||||
|
pendingTokens.putAll(secretService.getTokens(config));
|
||||||
|
|
||||||
return pendingTokens;
|
return pendingTokens;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -304,28 +313,28 @@ public class VaultUserContext extends TokenInjectingUserContext {
|
|||||||
|
|
||||||
// Substitute tokens producing secret names, retrieving and storing
|
// Substitute tokens producing secret names, retrieving and storing
|
||||||
// those secrets as parameter tokens
|
// those secrets as parameter tokens
|
||||||
return resolve(getTokens(confService.getTokenMapping(), filter));
|
return resolve(getTokens(confService.getTokenMapping(), null, filter));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the connection parameters associated with the
|
* Retrieves the GuacamoleConfiguration of the given Connection. If
|
||||||
* GuacamoleConfiguration of the given Connection. If possible, privileged
|
* possible, privileged access to the configuration is obtained first. Note
|
||||||
* access to those parameters is obtained first. Note that the underlying
|
* that the underlying extension is not required to allow privileged
|
||||||
* extension is not required to allow privileged access, nor is it
|
* access, nor is it required to expose the underlying configuration at
|
||||||
* required to expose the underlying connection parameters at all.
|
* all.
|
||||||
*
|
*
|
||||||
* @param connection
|
* @param connection
|
||||||
* The connection to retrieve parameters from.
|
* The connection to retrieve the configuration from.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* A Map of all connection parameters exposed by the underlying
|
* The GuacamoleConfiguration associated with the given connection,
|
||||||
* extension for the given connection, which may be empty.
|
* which may be partial or empty.
|
||||||
*
|
*
|
||||||
* @throws GuacamoleException
|
* @throws GuacamoleException
|
||||||
* If an error prevents privileged retrieval of parameters.
|
* If an error prevents privileged retrieval of the configuration.
|
||||||
*/
|
*/
|
||||||
private Map<String, String> getConnectionParameters(Connection connection)
|
private GuacamoleConfiguration getConnectionConfiguration(Connection connection)
|
||||||
throws GuacamoleException {
|
throws GuacamoleException {
|
||||||
|
|
||||||
String identifier = connection.getIdentifier();
|
String identifier = connection.getIdentifier();
|
||||||
@@ -335,11 +344,11 @@ public class VaultUserContext extends TokenInjectingUserContext {
|
|||||||
// actually be privileged)
|
// actually be privileged)
|
||||||
Connection privilegedConnection = getPrivileged().getConnectionDirectory().get(identifier);
|
Connection privilegedConnection = getPrivileged().getConnectionDirectory().get(identifier);
|
||||||
if (privilegedConnection != null)
|
if (privilegedConnection != null)
|
||||||
return privilegedConnection.getConfiguration().getParameters();
|
return privilegedConnection.getConfiguration();
|
||||||
|
|
||||||
// Fall back to unprivileged access if not implemented/allowed by
|
// Fall back to unprivileged access if not implemented/allowed by
|
||||||
// extension
|
// extension
|
||||||
return connection.getConfiguration().getParameters();
|
return connection.getConfiguration();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,7 +369,8 @@ public class VaultUserContext extends TokenInjectingUserContext {
|
|||||||
// Add hostname and username tokens if available (implementations are
|
// Add hostname and username tokens if available (implementations are
|
||||||
// not required to expose connection configuration details)
|
// not required to expose connection configuration details)
|
||||||
|
|
||||||
Map<String, String> parameters = getConnectionParameters(connection);
|
GuacamoleConfiguration config = getConnectionConfiguration(connection);
|
||||||
|
Map<String, String> parameters = config.getParameters();
|
||||||
|
|
||||||
String hostname = parameters.get("hostname");
|
String hostname = parameters.get("hostname");
|
||||||
if (hostname != null && !hostname.isEmpty())
|
if (hostname != null && !hostname.isEmpty())
|
||||||
@@ -382,7 +392,7 @@ public class VaultUserContext extends TokenInjectingUserContext {
|
|||||||
|
|
||||||
// Substitute tokens producing secret names, retrieving and storing
|
// Substitute tokens producing secret names, retrieving and storing
|
||||||
// those secrets as parameter tokens
|
// those secrets as parameter tokens
|
||||||
return resolve(getTokens(confService.getTokenMapping(), filter));
|
return resolve(getTokens(confService.getTokenMapping(), config, filter));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -23,9 +23,12 @@ import com.google.inject.Inject;
|
|||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
import org.apache.guacamole.GuacamoleException;
|
import org.apache.guacamole.GuacamoleException;
|
||||||
|
import org.apache.guacamole.protocol.GuacamoleConfiguration;
|
||||||
import org.apache.guacamole.vault.secret.VaultSecretService;
|
import org.apache.guacamole.vault.secret.VaultSecretService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -59,4 +62,11 @@ public class KsmSecretService implements VaultSecretService {
|
|||||||
return ksm.getSecret(name);
|
return ksm.getSecret(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Future<String>> getTokens(GuacamoleConfiguration config)
|
||||||
|
throws GuacamoleException {
|
||||||
|
// STUB
|
||||||
|
return Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user