From ca466f563910529b84072d6536e7a3a88a2bb8fe Mon Sep 17 00:00:00 2001
From: TdlQ <12106009+TdlQ@users.noreply.github.com>
Date: Tue, 16 Sep 2025 17:12:45 +0200
Subject: [PATCH 01/27] GUACAMOLE-2137: Change: take TokenFilter's modifier
into account to retrieve value
---
.../java/org/apache/guacamole/token/TokenFilter.java | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/guacamole-ext/src/main/java/org/apache/guacamole/token/TokenFilter.java b/guacamole-ext/src/main/java/org/apache/guacamole/token/TokenFilter.java
index 673e134d90..99eab585e0 100644
--- a/guacamole-ext/src/main/java/org/apache/guacamole/token/TokenFilter.java
+++ b/guacamole-ext/src/main/java/org/apache/guacamole/token/TokenFilter.java
@@ -129,8 +129,11 @@ public void setToken(String name, String value) {
* The value of the token with the given name, or null if no such
* token exists.
*/
- public String getToken(String name) {
- return tokenValues.get(name);
+ public String getToken(String name, String modifier) {
+ if (modifier != null && tokenValues.containsKey(name + ":" + modifier))
+ return tokenValues.get(name + ":" + modifier);
+ else
+ return tokenValues.get(name);
}
/**
@@ -226,7 +229,7 @@ private String filter(String input, boolean strict)
// Pull token value
String tokenName = tokenMatcher.group(TOKEN_NAME_GROUP);
- String tokenValue = getToken(tokenName);
+ String tokenValue = getToken(tokenName, modifier);
// If token is unknown, interpretation depends on whether
// strict mode is enabled
From 5acdfa5c775eeb268f9f8cd75547f16588fba167 Mon Sep 17 00:00:00 2001
From: TdlQ <12106009+TdlQ@users.noreply.github.com>
Date: Tue, 16 Sep 2025 17:16:59 +0200
Subject: [PATCH 02/27] GUACAMOLE-2137: Add: module guacamole-vault-hv
(Hashicorp Vault)
---
.../modules/guacamole-vault-dist/pom.xml | 7 +
.../src/main/assembly/dist.xml | 8 +
.../modules/guacamole-vault-hv/.ratignore | 0
.../modules/guacamole-vault-hv/pom.xml | 92 +++++
.../vault/hv/GuacamoleExceptionSupplier.java | 47 +++
.../vault/hv/HvAuthenticationProvider.java | 47 +++
.../hv/HvAuthenticationProviderModule.java | 81 +++++
.../vault/hv/conf/HvAttributeService.java | 155 ++++++++
.../vault/hv/conf/HvConfigurationService.java | 204 +++++++++++
.../guacamole/vault/hv/secret/HvClient.java | 270 ++++++++++++++
.../vault/hv/secret/HvClientFactory.java | 44 +++
.../vault/hv/secret/HvSecretService.java | 335 ++++++++++++++++++
.../vault/hv/secret/HvTimedSecretData.java | 33 ++
.../guacamole/vault/hv/user/HvConnection.java | 68 ++++
.../vault/hv/user/HvConnectionGroup.java | 107 ++++++
.../guacamole/vault/hv/user/HvDirectory.java | 90 +++++
.../vault/hv/user/HvDirectoryService.java | 172 +++++++++
.../guacamole/vault/hv/user/HvUser.java | 126 +++++++
.../vault/hv/user/HvUserFactory.java | 40 +++
.../src/main/resources/guac-manifest.json | 16 +
.../src/main/resources/translations/en.json | 23 ++
extensions/guacamole-vault/pom.xml | 1 +
22 files changed, 1966 insertions(+)
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/.ratignore
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/pom.xml
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/GuacamoleExceptionSupplier.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/HvAuthenticationProvider.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/HvAuthenticationProviderModule.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/conf/HvAttributeService.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/conf/HvConfigurationService.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/secret/HvClient.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/secret/HvClientFactory.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/secret/HvSecretService.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/secret/HvTimedSecretData.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/user/HvConnection.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/user/HvConnectionGroup.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/user/HvDirectory.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/user/HvDirectoryService.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/user/HvUser.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/user/HvUserFactory.java
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/resources/guac-manifest.json
create mode 100644 extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/resources/translations/en.json
diff --git a/extensions/guacamole-vault/modules/guacamole-vault-dist/pom.xml b/extensions/guacamole-vault/modules/guacamole-vault-dist/pom.xml
index 57a0449417..bc9f1dd9b6 100644
--- a/extensions/guacamole-vault/modules/guacamole-vault-dist/pom.xml
+++ b/extensions/guacamole-vault/modules/guacamole-vault-dist/pom.xml
@@ -49,6 +49,13 @@
${revision}
+
+
+ org.apache.guacamole
+ guacamole-vault-hv
+ 1.6.0
+
+
diff --git a/extensions/guacamole-vault/modules/guacamole-vault-dist/src/main/assembly/dist.xml b/extensions/guacamole-vault/modules/guacamole-vault-dist/src/main/assembly/dist.xml
index 6f41e52782..c974390d1a 100644
--- a/extensions/guacamole-vault/modules/guacamole-vault-dist/src/main/assembly/dist.xml
+++ b/extensions/guacamole-vault/modules/guacamole-vault-dist/src/main/assembly/dist.xml
@@ -41,6 +41,14 @@
+
+
+ hv
+
+ org.apache.guacamole:guacamole-vault-hv
+
+
+
diff --git a/extensions/guacamole-vault/modules/guacamole-vault-hv/.ratignore b/extensions/guacamole-vault/modules/guacamole-vault-hv/.ratignore
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/extensions/guacamole-vault/modules/guacamole-vault-hv/pom.xml b/extensions/guacamole-vault/modules/guacamole-vault-hv/pom.xml
new file mode 100644
index 0000000000..c2905d025d
--- /dev/null
+++ b/extensions/guacamole-vault/modules/guacamole-vault-hv/pom.xml
@@ -0,0 +1,92 @@
+
+
+
+
+ 4.0.0
+ org.apache.guacamole
+ guacamole-vault-hv
+ jar
+ 1.6.0
+ guacamole-vault-hv
+ http://guacamole.apache.org/
+
+
+ org.apache.guacamole
+ guacamole-vault
+ 1.6.0
+ ../../
+
+
+
+ 1.9.25
+
+
+
+
+
+
+ org.apache.guacamole
+ guacamole-ext
+ provided
+
+
+
+
+ org.apache.guacamole
+ guacamole-vault-base
+ 1.6.0
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.19.0
+
+
+
+
+ org.jetbrains.kotlin
+ kotlin-reflect
+ ${kotlin.version}
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib
+ ${kotlin.version}
+
+
+ org.jetbrains.kotlin
+ kotlin-stdlib-jdk8
+ ${kotlin.version}
+
+
+
+
+ org.bouncycastle
+ bc-fips
+ 2.1.0
+
+
+
+
+
diff --git a/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/GuacamoleExceptionSupplier.java b/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/GuacamoleExceptionSupplier.java
new file mode 100644
index 0000000000..cb4f1a4f62
--- /dev/null
+++ b/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/GuacamoleExceptionSupplier.java
@@ -0,0 +1,47 @@
+/*
+ * 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.vault.hv;
+
+import org.apache.guacamole.GuacamoleException;
+
+/**
+ * A class that is basically equivalent to the standard Supplier class in
+ * Java, except that the get() function can throw GuacamoleException, which
+ * is impossible with any of the standard Java lambda type classes, since
+ * none of them can handle checked exceptions
+ *
+ * @param
+ * The type of object which will be returned as a result of calling
+ * get().
+ */
+public interface GuacamoleExceptionSupplier {
+
+ /**
+ * Returns a value of the declared type.
+ *
+ * @return
+ * A value of the declared type.
+ *
+ * @throws GuacamoleException
+ * If an error occurs while attemping to calculate the return value.
+ */
+ public T get() throws GuacamoleException;
+
+}
\ No newline at end of file
diff --git a/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/HvAuthenticationProvider.java b/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/HvAuthenticationProvider.java
new file mode 100644
index 0000000000..08bbb2da95
--- /dev/null
+++ b/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/HvAuthenticationProvider.java
@@ -0,0 +1,47 @@
+/*
+ * 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.vault.hv;
+
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.vault.VaultAuthenticationProvider;
+
+/**
+ * VaultAuthenticationProvider implementation which reads secrets from
+ * Hashicorp Vault
+ */
+public class HvAuthenticationProvider extends VaultAuthenticationProvider {
+
+ /**
+ * Creates a new HvKeyVaultAuthenticationProvider which reads secrets
+ * from a configured Hashicorp Vault.
+ *
+ * @throws GuacamoleException
+ * If configuration details cannot be read from guacamole.properties.
+ */
+ public HvAuthenticationProvider() throws GuacamoleException {
+ super(new HvAuthenticationProviderModule());
+ }
+
+ @Override
+ public String getIdentifier() {
+ return "hashicorp-vault";
+ }
+
+}
diff --git a/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/HvAuthenticationProviderModule.java b/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/HvAuthenticationProviderModule.java
new file mode 100644
index 0000000000..289fcad697
--- /dev/null
+++ b/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/HvAuthenticationProviderModule.java
@@ -0,0 +1,81 @@
+/*
+ * 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.vault.hv;
+
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+import java.security.Security;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.vault.VaultAuthenticationProviderModule;
+import org.apache.guacamole.vault.conf.VaultAttributeService;
+import org.apache.guacamole.vault.conf.VaultConfigurationService;
+import org.apache.guacamole.vault.hv.conf.HvAttributeService;
+import org.apache.guacamole.vault.hv.conf.HvConfigurationService;
+import org.apache.guacamole.vault.hv.secret.HvClient;
+import org.apache.guacamole.vault.hv.secret.HvClientFactory;
+import org.apache.guacamole.vault.hv.secret.HvSecretService;
+import org.apache.guacamole.vault.hv.user.HvConnectionGroup;
+import org.apache.guacamole.vault.hv.user.HvDirectoryService;
+import org.apache.guacamole.vault.hv.user.HvUser;
+import org.apache.guacamole.vault.hv.user.HvUserFactory;
+import org.apache.guacamole.vault.secret.VaultSecretService;
+import org.apache.guacamole.vault.user.VaultDirectoryService;
+import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
+
+/**
+ * Guice module which configures injections specific to Hashicorp Vault
+ * support.
+ */
+public class HvAuthenticationProviderModule
+ extends VaultAuthenticationProviderModule {
+
+ /**
+ * Creates a new HvAuthenticationProviderModule which
+ * configures dependency injection for the Hashicorp Vault
+ * authentication provider and related services.
+ *
+ * @throws GuacamoleException
+ * If configuration details in guacamole.properties cannot be parsed.
+ */
+ public HvAuthenticationProviderModule() throws GuacamoleException {
+ Security.addProvider(new BouncyCastleFipsProvider());
+ }
+
+ @Override
+ protected void configureVault() {
+
+ // Bind services specific to Hashicorp Vault
+ bind(HvAttributeService.class);
+ bind(VaultAttributeService.class).to(HvAttributeService.class);
+ bind(VaultConfigurationService.class).to(HvConfigurationService.class);
+ bind(VaultSecretService.class).to(HvSecretService.class);
+ bind(VaultDirectoryService.class).to(HvDirectoryService.class);
+
+ // Bind factory for creating HV Clients
+ install(new FactoryModuleBuilder()
+ .implement(HvClient.class, HvClient.class)
+ .build(HvClientFactory.class));
+
+ // Bind factory for creating HvUsers
+ install(new FactoryModuleBuilder()
+ .implement(HvUser.class, HvUser.class)
+ .build(HvUserFactory.class));
+ }
+
+}
diff --git a/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/conf/HvAttributeService.java b/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/conf/HvAttributeService.java
new file mode 100644
index 0000000000..671653e3ec
--- /dev/null
+++ b/extensions/guacamole-vault/modules/guacamole-vault-hv/src/main/java/org/apache/guacamole/vault/hv/conf/HvAttributeService.java
@@ -0,0 +1,155 @@
+/*
+ * 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.vault.hv.conf;
+
+import com.google.inject.Singleton;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.form.BooleanField;
+import org.apache.guacamole.form.Form;
+import org.apache.guacamole.form.TextField;
+import org.apache.guacamole.language.TranslatableGuacamoleClientException;
+import org.apache.guacamole.vault.conf.VaultAttributeService;
+
+@Singleton
+public class HvAttributeService implements VaultAttributeService {
+
+ /**
+ * The name of the attribute which can contain a HV configuration blob
+ * associated with either a connection group or user.
+ */
+ public static final String HV_CONFIGURATION_ATTRIBUTE = "hv-config";
+
+ /**
+ * The HV configuration attribute contains sensitive information, so it
+ * should not be exposed through the directory. Instead, if a value is
+ * set on the attributes of an object, the following value will be exposed
+ * in its place, and correspondingly the underlying value will not be
+ * changed if this value is provided to an update call.
+ */
+ public static final String HV_ATTRIBUTE_PLACEHOLDER_VALUE = "**********";
+
+ /**
+ * All attributes related to configuring the HV vault on a
+ * per-connection-group or per-user basis.
+ */
+ public static final Form HV_CONFIGURATION_FORM = new Form(
+ "hv-config",
+ Arrays.asList(new TextField(HV_CONFIGURATION_ATTRIBUTE))
+ );
+
+ /**
+ * All HV-specific attributes for users, connections, or connection groups,
+ * organized by form.
+ */
+ public static final Collection