You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@guacamole.apache.org by "mike-jumper (via GitHub)" <gi...@apache.org> on 2023/03/01 17:11:25 UTC

[GitHub] [guacamole-client] mike-jumper commented on a diff in pull request #797: GUACAMOLE-839: Add webapp SSO support for certificates / smart cards.

mike-jumper commented on code in PR #797:
URL: https://github.com/apache/guacamole-client/pull/797#discussion_r1122072623


##########
extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLClientAuthenticationResource.java:
##########
@@ -0,0 +1,414 @@
+/*
+ * 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.auth.ssl;
+
+import com.google.inject.Inject;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
+import java.security.Principal;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import javax.naming.InvalidNameException;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+import javax.ws.rs.GET;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.HeaderParam;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.UriBuilder;
+import org.apache.guacamole.GuacamoleClientException;
+import org.apache.guacamole.GuacamoleException;
+import org.apache.guacamole.GuacamoleResourceNotFoundException;
+import org.apache.guacamole.auth.ssl.conf.ConfigurationService;
+import org.apache.guacamole.auth.sso.NonceService;
+import org.apache.guacamole.auth.sso.SSOResource;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * REST API resource that allows the user to retrieve an opaque state value
+ * representing their identity as determined by SSL/TLS client authentication.
+ * The opaque value may represent a valid identity or an authentication
+ * failure, and must be resubmitted within a normal Guacamole authentication
+ * request to finalize the authentication process.
+ */
+public class SSLClientAuthenticationResource extends SSOResource {
+
+    /**
+     * The string value that the SSL termination service uses for its client
+     * verification header to represent that the client certificate has been
+     * verified.
+     */
+    private static final String CLIENT_VERIFIED_HEADER_SUCCESS_VALUE = "SUCCESS";
+
+    /**
+     * The string value that the SSL termination service uses for its client
+     * verification header to represent that the client certificate is absent.
+     */
+    private static final String CLIENT_VERIFIED_HEADER_NONE_VALUE = "NONE";
+
+    /**
+     * The string prefix that the SSL termination service uses for its client
+     * verification header to represent that the client certificate has failed
+     * validation. The error message describing the nature of the failure is
+     * provided by the SSL termination service after this prefix.
+     */
+    private static final String CLIENT_VERIFIED_HEADER_FAILED_PREFIX = "FAILED:";
+
+    /**
+     * Logger for this class.
+     */
+    private static final Logger logger = LoggerFactory.getLogger(SSLClientAuthenticationResource.class);
+
+    /**
+     * Service for retrieving configuration information.
+     */
+    @Inject
+    private ConfigurationService confService;
+
+    /**
+     * Session manager for generating and maintaining unique tokens to
+     * represent the authentication flow of a user who has only partially
+     * authenticated. Here, these tokens represent a user that has been
+     * validated by SSL termination and allow the Guacamole instance that
+     * doesn't require SSL/TLS authentication to retrieve the user's identity
+     * and complete the authentication process.
+     */
+    @Inject
+    private SSLAuthenticationSessionManager sessionManager;
+
+    /**
+     * Service for validating and generating unique nonce values. Here, these
+     * nonces are used specifically for generating unique domains.
+     */
+    @Inject
+    private NonceService subdomainNonceService;
+
+    /**
+     * Retrieves a single value from the HTTP header having the given name. If
+     * there are multiple HTTP headers present with this name, the first
+     * matching header in the request is used. If there are no such headers in
+     * the request, null is returned.
+     *
+     * @param headers
+     *     The HTTP headers present in the request.
+     *
+     * @param name
+     *     The name of the header to retrieve.
+     *
+     * @return
+     *     The first value of the HTTP header having the given name, or null if
+     *     there is no such header.
+     */
+    private String getHeader(HttpHeaders headers, String name) {
+
+        List<String> values = headers.getRequestHeader(name);
+        if (values.isEmpty())
+            return null;
+
+        return values.get(0);
+
+    }
+
+    /**
+     * Decodes the provided URL-encoded string as UTF-8, returning the result.
+     *
+     * @param value
+     *     The URL-encoded string to decode.
+     *
+     * @return
+     *     The decoded string.
+     *
+     * @throws GuacamoleException
+     *     If the provided value is not a value URL-encoded string.
+     */
+    private byte[] decode(String value) throws GuacamoleException {
+        try {
+            return URLDecoder.decode(value, StandardCharsets.UTF_8.name())
+                    .getBytes(StandardCharsets.UTF_8);
+        }
+        catch (IllegalArgumentException e) {
+            throw new GuacamoleClientException("Invalid URL-encoded value.", e);
+        }
+        catch (UnsupportedEncodingException e) {
+            // This should never happen, as UTF-8 is a standard charset that
+            // the JVM is required to support
+            throw new UnsupportedOperationException("Unexpected lack of UTF-8 support.", e);
+        }
+    }
+
+    /**
+     * Extracts a user's username from the provided LDAP DN. If specific

Review Comment:
   Fixed via rebase.



##########
extensions/guacamole-auth-sso/modules/guacamole-auth-sso-ssl/src/main/java/org/apache/guacamole/auth/ssl/SSLAuthenticationSessionManager.java:
##########
@@ -0,0 +1,60 @@
+/*
+ * 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.auth.ssl;
+
+import com.google.inject.Singleton;
+import org.apache.guacamole.auth.sso.AuthenticationSessionManager;
+
+/**
+ * Manager service that temporarily stores SSL/TLS authentication attempts
+ * while the authentication flow is underway.
+ */
+@Singleton
+public class SSLAuthenticationSessionManager
+        extends AuthenticationSessionManager<SSLAuthenticationSession> {
+
+    /**
+     * Returns the identity asserted by the external SSL termination service at
+     * the end of the authentication process represented by the authentication
+     * session with the given identifier. If there is no such authentication
+     * session, or no valid identity has been asserted for that session, null
+     * is returned.
+     *
+     * @param identifier
+     *     The unique string returned by the call to defer(). For convenience,
+     *     this value may safely be null.
+     *
+     * @return
+     *     The identity asserted by the external SSL termination service at the
+     *     end of the authentication process represented by the authentication
+     *     session the the given identifier, or null if there is no such

Review Comment:
   Fixed via rebase.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: dev-unsubscribe@guacamole.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org