You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@guacamole.apache.org by GitBox <gi...@apache.org> on 2020/01/26 15:41:52 UTC

[GitHub] [guacamole-client] mike-jumper commented on a change in pull request #468: GUACAMOLE-938: Use same bind/connect process for all LDAP connections, including referrals.

mike-jumper commented on a change in pull request #468: GUACAMOLE-938: Use same bind/connect process for all LDAP connections, including referrals.
URL: https://github.com/apache/guacamole-client/pull/468#discussion_r371008709
 
 

 ##########
 File path: extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPConnectionService.java
 ##########
 @@ -104,151 +117,254 @@ private LdapNetworkConnection createLDAPConnection() throws GuacamoleException {
 
         }
 
+        return new LdapNetworkConnection(config);
+
     }
 
     /**
-     * Binds to the LDAP server using the provided user DN and password.
+     * Creates a new instance of LdapNetworkConnection, configured as required
+     * to use whichever encryption method, hostname, and port are requested
+     * within guacamole.properties. The returned LdapNetworkConnection is
+     * configured for use but is not yet connected nor bound to the LDAP
+     * server. It will not be bound until it a bind operation is explicitly
+     * requested, and will not connected until it is used in an LDAP operation
+     * (such as a bind).
      *
-     * @param userDN
-     *     The DN of the user to bind as, or null to bind anonymously.
+     * @return
+     *     A new LdapNetworkConnection instance which has already been
+     *     configured to use the encryption method, hostname, and port
+     *     requested within guacamole.properties.
      *
-     * @param password
-     *     The password to use when binding as the specified user, or null to
-     *     attempt to bind without a password.
+     * @throws GuacamoleException
+     *     If an error occurs while parsing guacamole.properties, or if the
+     *     requested encryption method is actually not implemented (a bug).
+     */
+    private LdapNetworkConnection createLDAPConnection()
+            throws GuacamoleException {
+        return createLDAPConnection(
+                confService.getServerHostname(),
+                confService.getServerPort(),
+                confService.getEncryptionMethod());
+    }
+
+    /**
+     * Creates a new instance of LdapNetworkConnection, configured as required
+     * to use whichever encryption method, hostname, and port are specified
+     * within the given LDAP URL. The returned LdapNetworkConnection is
+     * configured for use but is not yet connected nor bound to the LDAP
+     * server. It will not be bound until it a bind operation is explicitly
+     * requested, and will not connected until it is used in an LDAP operation
+     * (such as a bind).
+     *
+     * @param url
+     *     The LDAP URL containing the details which should be used to connect
+     *     to the LDAP server.
      *
      * @return
-     *     A bound LDAP connection, or null if the connection could not be
-     *     bound.
+     *     A new LdapNetworkConnection instance which has already been
+     *     configured to use the encryption method, hostname, and port
+     *     specified within the given LDAP URL.
      *
      * @throws GuacamoleException
-     *     If the configuration details relevant to binding to the LDAP server
-     *     cannot be read.
+     *     If the given URL is not a valid LDAP URL, or if the encryption
+     *     method indicated by the URL is known but not actually implemented (a
+     *     bug).
      */
-    public LdapNetworkConnection bindAs(Dn userDN, String password)
+    private LdapNetworkConnection createLDAPConnection(String url)
             throws GuacamoleException {
 
-        // Get ldapConnection and try to connect and bind.
-        LdapNetworkConnection ldapConnection = createLDAPConnection();
+        // Parse provided LDAP URL
+        LdapUrl ldapUrl;
         try {
+            ldapUrl = new LdapUrl(url);
+        }
+        catch (LdapException e) {
+            logger.debug("Cannot connect to LDAP URL \"{}\": URL is invalid.", url, e);
+            throw new GuacamoleServerException("Invalid LDAP URL.", e);
+        }
+
+        // Retrieve hostname from URL, bailing out if no hostname is present
+        String host = ldapUrl.getHost();
+        if (host == null || host.isEmpty()) {
+            logger.debug("Cannot connect to LDAP URL \"{}\": no hostname is present.", url);
+            throw new GuacamoleServerException("LDAP URL contains no hostname.");
+        }
+
+        // Parse encryption method from URL scheme
+        EncryptionMethod encryptionMethod = EncryptionMethod.NONE;
+        if (LdapUrl.LDAPS_SCHEME.equals(ldapUrl.getScheme()))
+            encryptionMethod = EncryptionMethod.SSL;
 
-            // Connect to LDAP server
-            ldapConnection.connect();
+        // If no post is specified within the URL, use the default port
+        // dictated by the encryption method
+        int port = ldapUrl.getPort();
+        if (port < 1)
+            port = encryptionMethod.DEFAULT_PORT;
+
+        return createLDAPConnection(host, port, encryptionMethod);
 
-            // Explicitly start TLS if requested
-            if (confService.getEncryptionMethod() == EncryptionMethod.STARTTLS)
-                ldapConnection.startTls();
 
 Review comment:
   As far as normal binds go, we are still using TLS when requested - it's just set up via the `LdapConnectionConfig` and thus automatically applied when the Apache Directory API does its internal `connect()`:
   
   https://github.com/apache/guacamole-client/blob/cb53b17afb30d5cbd1c4f744344dd2f32c6fe1b4/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPConnectionService.java#L107-L111
   
   My understanding of the previous iteration of this code was that TLS was not applied to referrals, as the code being removed here (and replaced with `setUseTls(true)`) is specific to the old version of `bindAs()`, which was not called for referral URLs.
   
   We could apply TLS for referrals, as well. It would be a simply matter of choosing that `EncryptionMethod` when delegating the creation of the LDAP connection for an LDAP referral:
   
   https://github.com/apache/guacamole-client/blob/cb53b17afb30d5cbd1c4f744344dd2f32c6fe1b4/extensions/guacamole-auth-ldap/src/main/java/org/apache/guacamole/auth/ldap/LDAPConnectionService.java#L193-L196
   
   I agree this makes sense (a deployment which requires STARTTLS for the main connection should generally be expected to also require it for `ldap://` connections encountered in referrals). I'll add this.

----------------------------------------------------------------
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.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services