[Date Prev][Date Next] [Chronological] [Thread] [Top]

LDAP over SSL



hi

I have downloaded and built Spencer's REGEX, Cyrus SASL 1.5.27, Open SSL 0.9.6c and OpenLDAP 2.0.18 using MS VC5. I have Netscape/iPlanet 4.x directory server. I have verified non-SSL connection and authentication of valid user DN and password, but it is not clear to me how to do SSL authentication of valid user DN and password using OpenLDAP's SSL functions.

I have verified the LDAP server is OK by using Novell's SDK/SSL API compiled under MS VC6 (because the SDK libraries do not work for MS VC5) for a valid user DN and password.

It is not clear to me what the procedure is and corresponding functions are with OpenLDAP/OpenSSL/Cyrus SASL.

I have tried to use ldap_pvt_tls_set_option fuction to specify the LDAP server certificate's CA root certificate. But in all cases I tried the application just waits forever in ldap_start_tls_s function call. I have attached the code below which include the Novell SDL API code that works on the same LDAP server. There is no problem with non-SSL authentication after modifying the code below slightly.

I have tried to use the ldapsearch sample available with OpenLDAP but it is not clear to me what options to specify for SSL authentication. The behavior is the wait forever. I have also verified non-SSL search specifying the same valid user DN/password using ldapsearch sample successfully.

I have tried with DER and Base 64 encoded CA certificate files with same result.

Thanks if any one can provide sample code or let me know what to do.

Rao
-----------
#define OPENLDAP 1

#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <sys/timeb.h>
#include "ldap.h"
#ifndef NOVELLNETSCAPE
#include "ldap_pvt.h"
#endif

static char usage[] =
"\n Usage:   sslbind <host name> <port number> <login dn> <password>"
"\n\t<cert file> <file type> \n"
"  host name      = ldap server name or IP address\n"
"  port number    = port to use - 636 is ldap ssl default\n" 
"  login dn       = user name to login as\n"
"  password       = user password\n"
"  cert file      = trusted root certificate file\n"
"  file type      = DER=der encoded file, B64=b64 encoded file\n"
"\n Example: sslbind Acme.com 636 cn=admin,o=Acme secret myKey.der DER\n";

#ifdef OPENLDAP
// Function prototype does not appear in ldap_pvt.h
int ldap_pvt_tls_init_def_ctx( void );
#endif


void main(int argc, char *argv[])
{

    int  version, rc, ldapPort;
    char *ldapHost;
    char *loginDN;
    char *password;
    char *certFile;
    char *fileType;
#ifdef NOVELLNETSCAPE
    int   fileEncoding;
#endif

    LDAP           *ld;
    LDAPMessage    *resultBuf = NULL;
    LDAPMessage    *entry = NULL;
    char           *dn;
       

    if (argc != 7)
    {
        printf("%s", usage);
        exit(1);
    }

    ldapHost     = argv[1];
    ldapPort     = 636;//atoi(argv[2]);
    loginDN      = argv[3];
    password     = argv[4];
    certFile     = argv[5];
    fileType     = argv[6];


    /* 
     * Set LDAP version to 3. 
     */
    version = LDAP_VERSION3;
    ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version);

#if defined(NOVELLNETSCAPE)
    /* 
     * Validate the fileType argument
     */
    if (0 == stricmp(fileType, "DER"))
		fileEncoding = LDAPSSL_CERT_FILETYPE_DER;
    else if (0 == stricmp(fileType, "B64"))
		fileEncoding = LDAPSSL_CERT_FILETYPE_B64;
    else {
		printf("Invalid certificate file type.\n");
		printf("%s", usage);
		exit(1);
    }

    /* 
     * Initialize the ssl library.  The first parameter of 
     * ldapssl_client_init is a certificate file.  However, when used
     * the file must be a DER encoded file.  A the API, 
     * ldapssl_add_trusted_cert accepts both DER and B64 encoded files.
     *
     * ldapssl_client_init is an application level initialization not a 
     * thread level initilization and should be done once.
     */
    rc = ldapssl_client_init(   NULL,       /* DER encoded cert file  */ 
                                NULL );     /* reserved, use NULL */

    if (rc != LDAP_SUCCESS) {
        printf("ldapssl_client_init error: %d\n", rc);
        exit(1);
    }

    /* 
     * Add the trusted root certificate file.  Multiple trusted root 
     * certificates can be added with ldapssl_add_trusted_cert.  Applications
     * can use this functionality to specify groups of trusted servers.
     */   
    rc = ldapssl_add_trusted_cert(certFile, fileEncoding);
    if (rc != LDAP_SUCCESS)
    {
        printf("ldapssl_add_trusted_cert error: %d\n", rc);
        ldapssl_client_deinit();
        exit(1);
    }


    /* 
     * create a LDAP session handle that is enabled for ssl connection
     */
    ld = ldapssl_init(  ldapHost,       /* host name */
                        ldapPort,       /* port number */
                        1 );            /* 0- clear text, 1-enable for ssl */

    if (ld == NULL )
    {
        printf("ldapssl_init error\n" );
        ldapssl_client_deinit();
        exit(1);
    }

#else
#if defined(OPENLDAP)
	//rc = ldap_pvt_tls_init();
	rc = ldap_pvt_tls_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR, "c:\\TestLDAPSSL");
	rc = ldap_pvt_tls_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, certFile);
    if (rc != LDAP_SUCCESS ) {
        printf("ldap_pvt_tls_set_option error: %d, %s\n", rc, ldap_err2string( rc ));
		exit(1);
	}
	//rc = ldap_pvt_tls_init_def_ctx();
	ld = ldap_init(ldapHost, ldapPort);
    if (ld == NULL )
    {
        printf("ldap_init error\n" );
        exit(1);
    }
	rc = ldap_start_tls_s(ld, NULL, NULL);
    if (rc != LDAP_SUCCESS ) {
        printf("ldap_start_tls_s error: %d, %s\n", rc, ldap_err2string( rc ));
		exit(1);
	}
#endif
#endif
    rc = ldap_simple_bind_s( ld, loginDN, password);
   
    if (rc != LDAP_SUCCESS )
    {
        printf("ldap_simple_bind_s error: %d, %s\n", rc, ldap_err2string( rc ));
        ldap_unbind_s( ld );
#ifdef NOVELLNETSCAPE
        ldapssl_client_deinit();
#endif
        exit(1);
    }
    

    printf("SSL bind successful - performing search\n");
      

    /* 
     * do a simple search just to verify things worked
     */
    rc = ldap_search_s( ld, "" , LDAP_SCOPE_ONELEVEL, "objectClass=*",
                        NULL, 0, &resultBuf);

    if( rc == LDAP_SUCCESS)
    {
       entry = ldap_first_entry(ld, resultBuf);

       while (entry != NULL)
       {
          dn = ldap_get_dn(ld, entry);
          printf("\tObject: %s\n", dn);

          ldap_memfree(dn);

          entry = ldap_next_entry(ld, entry);
       }

       ldap_msgfree( resultBuf );
    }
    else
    {
       printf("ldap_search_s error: %d, %s\n", rc, ldap_err2string(rc));
    }

    ldap_unbind_s( ld );

#ifdef NOVELLNETSCAPE
    /* 
     * Uninitialize the LDAP ssl library
     */
    ldapssl_client_deinit();
#endif
}