directory-api mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Emmanuel Lécharny <elecha...@gmail.com>
Subject Re: SASL/EXTERNAL binding
Date Thu, 16 Nov 2017 20:35:58 GMT


Le 16/11/2017 à 18:35, Frank Crow a écrit :
> About four years ago, I started on a project using OpenLDAP and Apache LDAP
> API for ldap client applications.   Due to requirements we moved away from
> using stored passwords and configured for client-side certificates
> (SASL/EXTERNAL).   That is when I discovered that the Apache LDAP API did
> not support SASL/EXTERNAL and that there was an outstanding bug
> (DIRAPI-105) against that feature.

It's not a bug, but a missing feature( although it's wrongly qualified
as 'bug' ;-)
>
> We undid the SASL/EXTERNAL requirement and failed our requirements with a
> promise to implement when available.   Now I'm off of that project and onto
> a new one.   Again, we have similar requirements.   And still, after all
> these years DIRAPI-105 keeps getting kicked down the road.

Indeed :/
>
> So, after that ticket being open for nearly 7 years, I'm just wondering if
> I should give up hope?  It's been quite a long road from the Mxx releases
> into the RC1 and RC2 and now 1.0.0 and still not supported.   I'm really
> wanting to implement this authentication mechanism (actually, I am anyway)
> and I'd really like to use the Apache LDAP API but I'm stuck with simple
> binds if I do.
Implementing EXTERNAL in the LDAP API should be quite simple : it should
be as simple as extending the AbstractSaslRequest class, and to pass teh
EXTERNAL machanism as a String, plus an optional authzID parameter (whch
is a part of teh AbstractSaslRequest class). Adding the EXTERNAL value
in the SupportedSaslMechanisms class would help :

public final class SupportedSaslMechanisms
{
    /** CRAM-MD5 mechanism */
    public static final String CRAM_MD5 = "CRAM-MD5";
 ...
    /** The EXTERNAL mechanism */
    public static final String EXTERNAL = "EXTERNAL";
...

and

package org.apache.directory.ldap.client.api;


import
org.apache.directory.api.ldap.model.constants.SupportedSaslMechanisms;


/**
 * Holds the data required to complete the EXTERNAL SASL operation
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory
Project</a>
 */
public class SaslExternalRequest extends AbstractSaslRequest
{
    /**
     * Creates a new instance of SaslExternalRequest.
     */
    public SaslExternalRequest()
    {
        super( SupportedSaslMechanisms.EXTERNAL );
    }

   
    /**
     * Creates a new instance of SaslExternalRequest.
     */
    public SaslExternalRequest( String authzId )
    {
        super( SupportedSaslMechanisms.EXTERNAL );
        this.authorizationId = authzId;
    }
}


Last, not least, adding the appropriate function in
LdapNetworkConnection is needed :




    /**
     * Bind to the server using a SaslExternalRequest object.
     *
     * @param request The SaslExternalRequest POJO containing all the
needed parameters
     * @return A LdapResponse containing the result
     * @throws LdapException if some error occurred
     */
    public BindResponse bind( SaslExternalRequest request ) throws
LdapException
    {
        if ( request == null )
        {
            String msg = "Cannot process a null request";
            LOG.debug( msg );
            throw new IllegalArgumentException( msg );
        }

        BindFuture bindFuture = bindAsync( request );

        // Get the result from the future
        try
        {
            // Read the response, waiting for it if not available
immediately
            // Get the response, blocking
            BindResponse bindResponse = bindFuture.get( timeout,
TimeUnit.MILLISECONDS );

            if ( bindResponse == null )
            {
                // We didn't received anything : this is an error
                LOG.error( "Bind failed : timeout occurred" );
                throw new LdapException( TIME_OUT_ERROR );
            }

            if ( bindResponse.getLdapResult().getResultCode() ==
ResultCodeEnum.SUCCESS )
            {
                authenticated.set( true );

                // Everything is fine, return the response
                LOG.debug( "Bind successful : {}", bindResponse );
            }
            else
            {
                // We have had an error
                LOG.debug( "Bind failed : {}", bindResponse );
            }

            return bindResponse;
        }
        catch ( Exception ie )
        {
            // Catch all other exceptions
            LOG.error( NO_RESPONSE_ERROR, ie );

            throw new LdapException( NO_RESPONSE_ERROR, ie );
        }
    }


That should be enough to get it working. Now, it requires some test.

Would you like to give it a little run ? If you validate that this code
works, I can easily inject it into the API and cut a release.

>
> I'm talking about projects which are pretty big US Navy programs of record
> where this feature would be very valuable.   But I'm just thinking that I
> need to move on with life.   Maybe look at Oracle Unified Directory or
> something else.
>
> Any ideas on that?

I gave you what I have from the top of my head. I also insist on teh
fact that it's Open Source, and anyone can contribute code, especially
when there is some itch that one want to scratch. That being said, the
code base is quite big, and I can understand it's intimidating.

Regarding this specific feature, teh real problem for us was to get it
tested. But if you don't mind doing this part of the job, we probably
can move forward !

thanks !

-- 
Emmanuel Lecharny

Symas.com
directory.apache.org


Mime
View raw message