From 29b56ff3cf98f5d027189896a3638fb0009b1846 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Wed, 23 Apr 2025 11:28:09 -0700 Subject: [PATCH] GUACAMOLE-839: Ensure plus signs in received encoded certificates are not decoded as spaces. The Apache HTTPD implementation of URL escaping does not encode plus signs, which Java's URLDecoder will decode as spaces. To avoid mangling received certificates, we need to ensure any plus signs within received certificates are preserved even if not encoded. --- .../auth/ssl/SSLClientAuthenticationResource.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLClientAuthenticationResource.java b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLClientAuthenticationResource.java index 443795001..e9a798466 100644 --- a/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLClientAuthenticationResource.java +++ b/extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLClientAuthenticationResource.java @@ -142,6 +142,12 @@ public class SSLClientAuthenticationResource extends SSOResource { /** * Decodes the provided URL-encoded string as UTF-8, returning the result. + *

+ * NOTE: The escape() function of the Apache HTTPD server is known to not + * encode plus signs, which can appear in the base64-encoded certificates + * typically received here. To avoid mangling such certificates, this + * function specifically avoids decoding plus signs as spaces (as would + * otherwise happen if URLDecoder is used directly). * * @param value * The URL-encoded string to decode. @@ -153,6 +159,13 @@ public class SSLClientAuthenticationResource extends SSOResource { * If the provided value is not a valid URL-encoded string. */ private byte[] decode(String value) throws GuacamoleException { + + // Ensure all plus signs are decoded literally rather than as spaces + // (the Apache HTTPD implementation of URL escaping that applies to + // request headers does not encode plus signs, whereas the Nginx + // implementation does) + value = value.replace("+", "%2B"); + try { return URLDecoder.decode(value, StandardCharsets.UTF_8.name()) .getBytes(StandardCharsets.UTF_8);