apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From minf...@apache.org
Subject svn commit: r124662 - /apr/apr-util/trunk/CHANGES /apr/apr-util/trunk/include/apr_ldap_init.h /apr/apr-util/trunk/include/apr_ldap_option.h /apr/apr-util/trunk/ldap/apr_ldap_init.c /apr/apr-util/trunk/ldap/apr_ldap_option.c
Date Sat, 08 Jan 2005 17:18:47 GMT
Author: minfrin
Date: Sat Jan  8 09:18:45 2005
New Revision: 124662

URL: http://svn.apache.org/viewcvs?view=rev&rev=124662
Log:
LDAP: Move all certificate initialisation, and the creation of SSL
and TLS connections into the apr_ldap_set_option() API. Add support
for client certificates.

Modified:
   apr/apr-util/trunk/CHANGES
   apr/apr-util/trunk/include/apr_ldap_init.h
   apr/apr-util/trunk/include/apr_ldap_option.h
   apr/apr-util/trunk/ldap/apr_ldap_init.c
   apr/apr-util/trunk/ldap/apr_ldap_option.c

Modified: apr/apr-util/trunk/CHANGES
Url: http://svn.apache.org/viewcvs/apr/apr-util/trunk/CHANGES?view=diff&rev=124662&p1=apr/apr-util/trunk/CHANGES&r1=124661&p2=apr/apr-util/trunk/CHANGES&r2=124662
==============================================================================
--- apr/apr-util/trunk/CHANGES	(original)
+++ apr/apr-util/trunk/CHANGES	Sat Jan  8 09:18:45 2005
@@ -1,5 +1,9 @@
 Changes with APR-util 1.1.0
 
+  *) LDAP: Move all certificate initialisation, and the creation of SSL
+     and TLS connections into the apr_ldap_set_option() API. Add support
+     for client certificates. [Graham Leggett]
+ 
   *) Emit the run-time link path option in apu-config after installation
      if the user is linking with libtool.  [Justin Erenkrantz]
 

Modified: apr/apr-util/trunk/include/apr_ldap_init.h
Url: http://svn.apache.org/viewcvs/apr/apr-util/trunk/include/apr_ldap_init.h?view=diff&rev=124662&p1=apr/apr-util/trunk/include/apr_ldap_init.h&r1=124661&p2=apr/apr-util/trunk/include/apr_ldap_init.h&r2=124662
==============================================================================
--- apr/apr-util/trunk/include/apr_ldap_init.h	(original)
+++ apr/apr-util/trunk/include/apr_ldap_init.h	Sat Jan  8 09:18:45 2005
@@ -28,6 +28,14 @@
 #define APR_LDAP_CA_TYPE_DER      1
 #define APR_LDAP_CA_TYPE_BASE64   2
 #define APR_LDAP_CA_TYPE_CERT7_DB 3
+#define APR_LDAP_CA_TYPE_SECMOD 4
+#define APR_LDAP_CERT_TYPE_UNKNOWN 5
+#define APR_LDAP_CERT_TYPE_DER 6
+#define APR_LDAP_CERT_TYPE_BASE64 7
+#define APR_LDAP_CERT_TYPE_KEY3_DB 8
+#define APR_LDAP_KEY_TYPE_UNKNOWN 9
+#define APR_LDAP_KEY_TYPE_DER 10
+#define APR_LDAP_KEY_TYPE_BASE64 11
 
 APU_DECLARE(int) apr_ldap_ssl_init(apr_pool_t *pool,
                                    const char *cert_auth_file,

Modified: apr/apr-util/trunk/include/apr_ldap_option.h
Url: http://svn.apache.org/viewcvs/apr/apr-util/trunk/include/apr_ldap_option.h?view=diff&rev=124662&p1=apr/apr-util/trunk/include/apr_ldap_option.h&r1=124661&p2=apr/apr-util/trunk/include/apr_ldap_option.h&r2=124662
==============================================================================
--- apr/apr-util/trunk/include/apr_ldap_option.h	(original)
+++ apr/apr-util/trunk/include/apr_ldap_option.h	Sat Jan  8 09:18:45 2005
@@ -33,39 +33,112 @@
 /*
  * The following defines handle the different TLS certificate
  * options available. If these options are missing, APR will try and
- * emulate support for this using the derecated ldap_start_tls_s()
+ * emulate support for this using the deprecated ldap_start_tls_s()
  * function.
  */
-#ifdef LDAP_OPT_X_TLS_NEVER
-#define APR_LDAP_OPT_TLS_NEVER LDAP_OPT_X_TLS_NEVER
-#else
-#define APR_LDAP_OPT_TLS_NEVER 0
-#endif
+#define APR_LDAP_OPT_TLS 0x6fff
+#define APR_LDAP_OPT_TLS_CERT 0x6ffe
 
-#ifdef LDAP_OPT_X_TLS_HARD
-#define APR_LDAP_OPT_TLS_HARD LDAP_OPT_X_TLS_HARD
-#else
-#define APR_LDAP_OPT_TLS_HARD 1
-#endif
-
-#ifdef LDAP_OPT_X_TLS_DEMAND
-#define APR_LDAP_OPT_TLS_DEMAND LDAP_OPT_X_TLS_DEMAND
-#else
-#define APR_LDAP_OPT_TLS_DEMAND 2
-#endif
+/**
+ * Structures for the apr_set_option() cases
+ */
 
-#ifdef LDAP_OPT_X_TLS_ALLOW
-#define APR_LDAP_OPT_TLS_ALLOW LDAP_OPT_X_TLS_ALLOW
-#else
-#define APR_LDAP_OPT_TLS_ALLOW 3
-#endif
+/**
+ * APR_LDAP_OPT_TLS_CERT
+ *
+ * This structure includes possible options to set certificates on
+ * system initialisation. Different SDKs have different certificate
+ * requirements, and to achieve this multiple certificates must be
+ * specified at once.
+ *
+ * Netscape:
+ * Needs the CA cert database (cert7.db), the client cert database (key3.db)
+ * and the security module file (secmod.db) set at the system initialisation
+ * time. Three types are supported: APR_LDAP_CERT7_DB, APR_LDAP_KEY3_DB and
+ * APR_LDAP_SECMOD.
+ *
+ * To specify a client cert connection, a certificate nickname needs to be
+ * provided with a type of APR_LDAP_CERT.
+ * int ldapssl_enable_clientauth( LDAP *ld, char *keynickname,
+ * char *keypasswd, char *certnickname );
+ * keynickname is currently not used, and should be set to ""
+ *
+ * Novell:
+ * Needs CA certificates and client certificates set at system initialisation
+ * time. Three types are supported: APR_LDAP_CA*, APR_LDAP_CERT* and
+ * APR_LDAP_KEY*.
+ *
+ * Certificates cannot be specified per connection.
+ *
+ * The functions used are:
+ * ldapssl_add_trusted_cert(serverTrustedRoot, serverTrustedRootEncoding);
+ * Clients certs and keys are set at system initialisation time with
+ * int ldapssl_set_client_cert (
+ *  void   *cert,
+ *  int     type
+ *  void   *password); 
+ * type can be LDAPSSL_CERT_FILETYPE_B64 or LDAPSSL_CERT_FILETYPE_DER
+ *  ldapssl_set_client_private_key(clientPrivateKey,
+ *                                 clientPrivateKeyEncoding,
+ *                                 clientPrivateKeyPassword);
+ *
+ * OpenSSL:
+ * Needs one or more CA certificates to be set at system initialisation time
+ * with a type of APR_LDAP_CA*.
+ *
+ * May have one or more client certificates set per connection with a type of
+ * APR_LDAP_CERT*, and keys with APR_LDAP_KEY*.
+ */
+#define APR_LDAP_CA_TYPE_UNKNOWN  0
+#define APR_LDAP_CA_TYPE_DER      1
+#define APR_LDAP_CA_TYPE_BASE64   2
+#define APR_LDAP_CA_TYPE_CERT7_DB 3
+#define APR_LDAP_CA_TYPE_SECMOD 4
+#define APR_LDAP_CERT_TYPE_UNKNOWN 5
+#define APR_LDAP_CERT_TYPE_DER 6
+#define APR_LDAP_CERT_TYPE_BASE64 7
+#define APR_LDAP_CERT_TYPE_KEY3_DB 8
+#define APR_LDAP_KEY_TYPE_UNKNOWN 9
+#define APR_LDAP_KEY_TYPE_DER 10
+#define APR_LDAP_KEY_TYPE_BASE64 11
 
-#ifdef LDAP_OPT_X_TLS_TRY
-#define APR_LDAP_OPT_TLS_TRY LDAP_OPT_X_TLS_TRY
-#else
-#define APR_LDAP_OPT_TLS_TRY 4
-#endif
+typedef struct apr_ldap_opt_tls_cert_t apr_ldap_opt_tls_cert_t;
+struct apr_ldap_opt_tls_cert_t {
+    int type;
+    const char *path;
+    const char *password;
+    apr_ldap_opt_tls_cert_t *next;
+};
 
+/**
+ * APR_LDAP_OPT_TLS
+ *
+ * This sets the SSL level on the LDAP handle.
+ *
+ * Netscape/Mozilla:
+ * Supports SSL, but not STARTTLS
+ * SSL is enabled by calling ldapssl_install_routines().
+ *
+ * Novell:
+ * Supports SSL and STARTTLS.
+ * SSL is enabled by calling ldapssl_install_routines(). Note that calling
+ * other ldap functions before ldapssl_install_routines() may cause this
+ * function to fail.
+ * STARTTLS is enabled by calling ldapssl_start_tls_s() after calling
+ * ldapssl_install_routines() (check this).
+ *
+ * OpenLDAP:
+ * Supports SSL and apparently supports STARTTLS
+ * Currently it is not clear whether OpenLDAP can support SSL, apparently it
+ * can.
+ * Support for STARTTLS is also unconfirmed - ldap_start_tls_s() has been
+ * deprecated, but no replacement method or function has been defined. Even the
+ * OpenLDAP source code is uncommented and yields no clues...
+ */
+#define APR_LDAP_NONE 0
+#define APR_LDAP_SSL 1
+#define APR_LDAP_STARTTLS 2
+#define APR_LDAP_STOPTLS 3
 
 /**
  * APR LDAP get option function

Modified: apr/apr-util/trunk/ldap/apr_ldap_init.c
Url: http://svn.apache.org/viewcvs/apr/apr-util/trunk/ldap/apr_ldap_init.c?view=diff&rev=124662&p1=apr/apr-util/trunk/ldap/apr_ldap_init.c&r1=124661&p2=apr/apr-util/trunk/ldap/apr_ldap_init.c&r2=124662
==============================================================================
--- apr/apr-util/trunk/ldap/apr_ldap_init.c	(original)
+++ apr/apr-util/trunk/ldap/apr_ldap_init.c	Sat Jan  8 09:18:45 2005
@@ -33,9 +33,15 @@
 /**
  * APR LDAP SSL Initialise function
  *
- * This function sets up any SSL certificate parameters as
- * required by the application. It should be called once on
- * system initialisation.
+ * This function initialises SSL on the underlying LDAP toolkit
+ * if this is necessary.
+ *
+ * If a CA certificate is provided, this is set, however the setting
+ * of certificates via this method has been deprecated and will be removed in
+ * APR v2.0.
+ *
+ * The apr_ldap_set_option() function with the APR_LDAP_OPT_TLS_CERT option
+ * should be used instead to set certificates.
  *
  * If SSL support is not available on this platform, or a problem
  * was encountered while trying to set the certificate, the function
@@ -47,209 +53,40 @@
                                    int cert_file_type,
                                    apr_ldap_err_t **result_err) {
 
-    apr_ldap_err_t *result;
-
-    if (cert_auth_file) {
-        return apr_ldap_ssl_add_cert(pool,
-                                     cert_auth_file,
-                                     cert_file_type,
-                                     result_err);
-    }
-    else {
-        result = (apr_ldap_err_t *)apr_pcalloc(pool, sizeof(apr_ldap_err_t));
-        *result_err = result;
-#if APR_HAS_LDAP_SSL /* compiled with ssl support */
-
-        /* Novell needs special initialisation */
-#if APR_HAS_NOVELL_LDAPSDK
-#if APR_HAS_LDAPSSL_CLIENT_INIT
-        result->rc = ldapssl_client_init(NULL, NULL);
-
-        if (LDAP_SUCCESS == result->rc) {
-            return APR_SUCCESS;
-        }
-        else {
-            result->msg = ldap_err2string(result-> rc);
-            result->reason = apr_pstrdup (pool, "LDAP: Could not "
-                                                "initialize SSL");
-            return APR_EGENERAL;
-        }
-#else
-        result->reason = "LDAP: ldapssl_client_init() function not "
-                         "supported by this Novell SDK. SSL not "
-                         "initialised";
-        result->rc = -1;
-#endif
-#endif
-
-#endif
-    }
-
-    /* if no cert_auth_file was passed, we assume SSL support
-     * is possible, as we have not been specifically told otherwise.
-     */
-    return APR_SUCCESS;
-
-} 
-
-
-/**
- * APR LDAP SSL add client certificate function.
- *
- * This function sets up an optional client certificate to be used
- * when connecting to the remote LDAP server.
- * If SSL support is not available on this platform, or a problem
- * was encountered while trying to set the certificate, the function
- * will return APR_EGENERAL. Further LDAP specific error information
- * can be found in result_err.
- */
-APU_DECLARE(int) apr_ldap_ssl_add_cert(apr_pool_t *pool,
-                                       const char *cert_auth_file,
-                                       int cert_file_type,
-                                       apr_ldap_err_t **result_err) {
-
     apr_ldap_err_t *result = (apr_ldap_err_t *)apr_pcalloc(pool, sizeof(apr_ldap_err_t));
     *result_err = result;
 
-    if (cert_auth_file) {
 #if APR_HAS_LDAP_SSL /* compiled with ssl support */
 
-        /* Netscape SDK */
-#if APR_HAS_NETSCAPE_LDAPSDK
-#if APR_HAS_LDAP_SSL_CLIENT_INIT
-        /* Netscape sdk only supports a cert7.db file 
-         */
-        if (cert_file_type == APR_LDAP_CA_TYPE_CERT7_DB) {
-            result->rc = ldapssl_client_init(cert_auth_file, NULL);
-        }
-        else {
-            result->reason = "LDAP: Invalid certificate type: "
-                             "CERT7_DB type required";
-            result->rc = -1;
-        }
-#else
-        result->reason = "LDAP: ldapssl_client_init() function not "
-                         "supported by this Netscape SDK. Certificate "
-                         "authority file not set";
-        result->rc = -1;
-#endif
-#endif
-
-        /* Novell SDK */
+    /* Novell */
 #if APR_HAS_NOVELL_LDAPSDK
-#if APR_HAS_LDAPSSL_CLIENT_INIT && APR_HAS_LDAPSSL_ADD_TRUSTED_CERT && APR_HAS_LDAPSSL_CLIENT_DEINIT
-        /* Novell SDK supports DER or BASE64 files
-         */
-        if (cert_file_type == APR_LDAP_CA_TYPE_DER  ||
-            cert_file_type == APR_LDAP_CA_TYPE_BASE64 ) {
-
-            result->rc = ldapssl_client_init(NULL, NULL);
-            if (LDAP_SUCCESS == result->rc) {
-                if (cert_file_type == APR_LDAP_CA_TYPE_BASE64) {
-                    result->rc = ldapssl_add_trusted_cert((void*)cert_auth_file, 
-                                              LDAPSSL_CERT_FILETYPE_B64);
-                }
-                else {
-                    result->rc = ldapssl_add_trusted_cert((void*)cert_auth_file, 
-                                              LDAPSSL_CERT_FILETYPE_DER);
-                }
-
-                if (LDAP_SUCCESS != result->rc) {
-                    ldapssl_client_deinit();
-                    result->reason = apr_psprintf(pool, 
-                                                  "LDAP: Invalid certificate "
-                                                  "or path: Could not add "
-                                                  "trusted cert %s", 
-                                                  cert_auth_file);
-                }
-            }
-        }
-        else {
-            result->reason = "LDAP: Invalid certificate type: "
-                             "DER or BASE64 type required";
-            result->rc = -1;
-        }
-#else
-        result->reason = "LDAP: ldapssl_client_init(), "
-                         "ldapssl_add_trusted_cert() or "
-                         "ldapssl_client_deinit() functions not supported "
-                         "by this Novell SDK. Certificate authority file "
-                         "not set";
-        result->rc = -1;
-#endif
+    ldapssl_client_init(NULL, NULL);
 #endif
 
-        /* openldap SDK */
-#if APR_HAS_OPENLDAP_LDAPSDK
-#ifdef LDAP_OPT_X_TLS_CACERTFILE
-        /* OpenLDAP SDK supports BASE64 files
-         */
-        if (cert_file_type == APR_LDAP_CA_TYPE_BASE64) {
-            result->rc = ldap_set_option(NULL,
-                                         LDAP_OPT_X_TLS_CACERTFILE,
-                                         cert_auth_file);
-        }
-        else {
-            result->reason = "LDAP: Invalid certificate type: "
-                             "BASE64 type required";
-            result->rc = -1;
-        }
-#else
-        result->reason = "LDAP: LDAP_OPT_X_TLS_CACERTFILE not "
-                         "defined by this OpenLDAP SDK. Certificate "
-                         "authority file not set";
-        result->rc = -1;
-#endif
-#endif
-
-        /* microsoft SDK */
-#if APR_HAS_MICROSOFT_LDAPSDK
-        /* Microsoft SDK use the registry certificate store - always
-         * assume support is always available
-         */
-        result->rc = LDAP_SUCCESS;
-#endif
-
-        /* Sun SDK */
-#if APR_HAS_SOLARIS_LDAPSDK
-        result->reason = "LDAP: Attempt to set certificate store failed. "
-                         "APR does not yet know how to set a certificate "
-                         "store on the Sun toolkit";
-        result->rc = -1;
-#endif
-
-        /* SDK not recognised */
-#if APR_HAS_OTHER_LDAPSDK
-        /* unknown toolkit type, assume no support available */
-        result->reason = "LDAP: Attempt to set certificate store failed. "
-                         "Toolkit type not recognised by APR as supporting "
-                         "SSL";
-        result->rc = -1;
-#endif
+    /* if a certificate was specified, set it */
+    if (cert_auth_file) {
+        apr_ldap_opt_tls_cert_t *cert = (apr_ldap_opt_tls_cert_t *)apr_palloc(pool, sizeof(apr_ldap_opt_tls_cert_t));
+        cert->type = cert_file_type;
+        cert->path = cert_auth_file;
+        return apr_ldap_set_option(pool, NULL, APR_LDAP_OPT_TLS, (void *)cert, result_err);
+    }
 
 #else  /* not compiled with SSL Support */
-
+    if (cert_auth_file) {
         result->reason = "LDAP: Attempt to set certificate store failed. "
                          "Not built with SSL support";
         result->rc = -1;
-
+    }
 #endif /* APR_HAS_LDAP_SSL */
 
-        if (result->rc != -1) {
-            result->msg = ldap_err2string(result-> rc);
-        }
-
-        if (LDAP_SUCCESS == result->rc) {
-            return APR_SUCCESS;
-        }
-        else {
-            return APR_EGENERAL;
-        }
+    if (result->rc != -1) {
+        result->msg = ldap_err2string(result-> rc);
+    }
+
+    if (LDAP_SUCCESS != result->rc) {
+        return APR_EGENERAL;
     }
 
-    /* if no cert_auth_file was passed, we assume SSL support
-     * is possible, as we have not been specifically told otherwise.
-     */
     return APR_SUCCESS;
 
 } 
@@ -293,11 +130,9 @@
  * toolkit supports it, the following values are accepted for
  * secure:
  *
- * APR_LDAP_OPT_TLS_NEVER: No encryption
- * APR_LDAP_OPT_TLS_HARD: SSL encryption (ldaps://)
- * APR_LDAP_OPT_TLS_DEMAND: Force STARTTLS on ldap://
- * APR_LDAP_OPT_TLS_ALLOW: Allow STARTTLS on ldap://
- * APR_LDAP_OPT_TLS_TRY: Optionally try STARTLS on ldap://
+ * APR_LDAP_NONE: No encryption
+ * APR_LDAP_SSL: SSL encryption (ldaps://)
+ * APR_LDAP_STARTTLS: Force STARTTLS on ldap://
  */
 APU_DECLARE(int) apr_ldap_init(apr_pool_t *pool,
                                LDAP **ldap,
@@ -309,124 +144,13 @@
     apr_ldap_err_t *result = (apr_ldap_err_t *)apr_pcalloc(pool, sizeof(apr_ldap_err_t));
     *result_err = result;
 
-    /* clear connection requested */
-    if (!secure) {
-        *ldap = ldap_init((char *)hostname, portno);
+    *ldap = ldap_init((char *)hostname, portno);
+    if (*ldap != NULL) {
+        return apr_ldap_set_option(pool, *ldap, APR_LDAP_OPT_TLS, &secure, result_err);
     }
-    else { /* ssl connnection requested */
-#if APR_HAS_LDAP_SSL
-
-        /* netscape toolkit */
-#if APR_HAS_NETSCAPE_LDAPSDK
-#if APR_HAS_LDAPSSL_INIT
-        *ldap = ldapssl_init(hostname, portno, 1);
-#else
-        result->reason = "LDAP: SSL not yet supported by APR on "
-                         "this version of the Netscape toolkit";
-        return APR_ENOTIMPL;
-#endif
-#endif
-
-        /* novell toolkit */
-#if APR_HAS_NOVELL_LDAPSDK
-        if (secure == APR_LDAP_OPT_TLS_HARD) {
-            *ldap = ldapssl_init(hostname, portno, 1);
-        }
-        else {
-            *ldap = ldapssl_init(hostname, portno, 0);
-            result->rc = ldapssl_start_tls(*ldap);
-            if (LDAP_SUCCESS != result->rc) {
-                ldap_unbind_s(*ldap);
-                result->reason = "LDAP: ldapssl_start_tls failed, "
-                                 "could not set security mode for "
-                                 "apr_ldap_init()";
-                result->msg = ldap_err2string(result->rc);
-                *ldap = NULL;
-                return APR_EGENERAL;
-            }
-        }
-#endif
-
-        /* openldap toolkit */
-#if APR_HAS_OPENLDAP_LDAPSDK
-#ifdef LDAP_OPT_X_TLS
-        *ldap = ldap_init(hostname, portno);
-        if (NULL != *ldap) {
-            int SSLmode = secure;
-            result->rc = ldap_set_option(*ldap, LDAP_OPT_X_TLS, &SSLmode);
-            if (LDAP_SUCCESS != result->rc) {
-                ldap_unbind_s(*ldap);
-                result->reason = "LDAP: ldap_set_option failed, "
-                                 "could not set security mode for "
-                                 "apr_ldap_init()";
-                result->msg = ldap_err2string(result->rc);
-                *ldap = NULL;
-                return APR_EGENERAL;
-            }
-        }
-#else
-        result->reason = "LDAP: SSL/TLS not yet supported by APR on this "
-                         "version of the OpenLDAP toolkit";
-        return APR_ENOTIMPL;
-#endif
-#endif
-
-        /* microsoft toolkit */
-#if APR_HAS_MICROSOFT_LDAPSDK
-        if (APR_LDAP_OPT_TLS_HARD == secure) {
-            *ldap = ldap_sslinit((char *)hostname, portno, 1);
-        }
-        else {
-            if (APR_LDAP_OPT_TLS_DEMAND == secure) {
-                *ldap = ldap_init(hostname, portno);
-                if (NULL != *ldap) {
-                    result->rc = ldap_start_tls_s(*ldap, NULL, NULL, NULL, NULL);
-                    if (LDAP_SUCCESS != result->rc) {
-                        ldap_unbind_s(*ldap);
-                        result->reason = "LDAP: ldap_start_tls_s() failed, "
-                                         "could not set STARTTLS mode for "
-                                         "apr_ldap_init()";
-                        result->msg = ldap_err2string(result->rc);
-                        *ldap = NULL;
-                        return APR_EGENERAL;
-                    }
-                }
-            }
-            else {
-                result->reason = "LDAP: APR_LDAP_OPT_TLS_ALLOW and "
-                                 "APR_LDAP_OPT_TLS_TRY are not supported "
-                                 "by APR on this version of the Microsoft "
-                                 "toolkit. Use APR_LDAP_OPT_TLS_DEMAND "
-                                 "instead to enable STARTTLS";
-                return APR_ENOTIMPL;
-            }
-        }
-#endif
-
-        /* sun toolkit */
-#if APR_HAS_SOLARIS_LDAPSDK
-        result->reason = "LDAP: SSL not yet supported by APR on "
-                         "this version of the Sun toolkit";
-        return APR_ENOTIMPL;
-#endif
-
-        /* unknown toolkit - return not implemented */
-#if APR_HAS_OTHER_LDAPSDK
-        return APR_ENOTIMPL;
-#endif
-
-#endif /* APR_HAS_LDAP_SSL */
-    }
-
-    /* if the attempt returned a NULL object, return an error 
-     * from the os as per the LDAP C SDK.
-     */
-    if (NULL == *ldap) {
+    else {
         return apr_get_os_error();
     }
-    
-    /* otherwise we were successful */
-    return APR_SUCCESS;
 
 }
 

Modified: apr/apr-util/trunk/ldap/apr_ldap_option.c
Url: http://svn.apache.org/viewcvs/apr/apr-util/trunk/ldap/apr_ldap_option.c?view=diff&rev=124662&p1=apr/apr-util/trunk/ldap/apr_ldap_option.c&r1=124661&p2=apr/apr-util/trunk/ldap/apr_ldap_option.c&r2=124662
==============================================================================
--- apr/apr-util/trunk/ldap/apr_ldap_option.c	(original)
+++ apr/apr-util/trunk/ldap/apr_ldap_option.c	Sat Jan  8 09:18:45 2005
@@ -87,18 +87,460 @@
         return APR_ENOMEM;
     }
 
-    /* set the option specified using the native LDAP function */
-    result->rc = ldap_set_option(ldap, option, (void *)invalue);
+    switch (option) {
+        case APR_LDAP_OPT_TLS_CERT: {
+            option_set_cert(pool, ldap, invalue, result);
+            break;
+        }
+        case APR_LDAP_OPT_TLS: {
+            option_set_tls(pool, ldap, invalue, result);
+            break;
+        }
+        default: {
+
+            /* set the option specified using the native LDAP function */
+            result->rc = ldap_set_option(ldap, option, (void *)invalue);
+
+            /* handle the error case */
+            if (LDAP_SUCCESS != result->rc) {
+                result->msg = ldap_err2string(result->rc);
+                result->reason = "LDAP: Could not set an option";
+            }
+
+        }
+    }
 
     /* handle the error case */
     if (LDAP_SUCCESS != result->rc) {
-        result->msg = ldap_err2string(result-> rc);
-        result->reason = apr_pstrdup (pool, "LDAP: Could not get an option");
         return APR_EGENERAL;
     }
 
     return APR_SUCCESS;
 
 }
+
+/**
+ * Handle APR_LDAP_OPT_TLS
+ *
+ * This function sets the type of TLS to be applied to this connection.
+ * The options are:
+ * APR_LDAP_NONE: no encryption
+ * APR_LDAP_SSL: SSL encryption (ldaps://)
+ * APR_LDAP_STARTTLS: STARTTLS encryption
+ * APR_LDAP_STOPTLS: Stop existing TLS connecttion
+ */
+int option_set_tls(apr_pool_t *pool,
+            LDAP *ldap,
+            const void *invalue,
+            apr_ldap_err_t *result) {
+
+    int tls = * (const int *)invalue;
+
+#if APR_HAS_LDAP_SSL /* compiled with ssl support */
+
+    /* Netscape SDK */
+#if APR_HAS_NETSCAPE_LDAPSDK
+    if (APR_LDAP_SSL == tls) {
+        result->rc = ldapssl_install_routines(ldap);
+        if (result->rc == LDAP_SUCCESS) {
+            result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, LDAP_OPT_ON);
+        }
+        if (result->rc != LDAP_SUCCESS) {
+            result->msg = ldap_err2string(result->rc);
+            result->reason = "LDAP: Could not switch SSL on for this "
+                             "connection.";
+        }
+    }
+    else if (APR_LDAP_STARTTLS == tls) {
+        result->reason = "LDAP: STARTTLS is not supported by the "
+                         "Netscape/Mozilla SDK";
+        result->rc = -1;
+    }
+    else if (APR_LDAP_STOPTLS == tls) {
+        result->reason = "LDAP: STOPTLS is not supported by the "
+                         "Netscape/Mozilla SDK";
+        result->rc = -1;
+    }
+#endif
+
+    /* Novell SDK */
+#if APR_HAS_NOVELL_SDK
+    /* ldapssl_install_routines(ldap)
+     * Behavior is unpredictable when other LDAP functions are called
+     * between the ldap_init function and the ldapssl_install_routines
+     * function.
+     * 
+     * STARTTLS is supported by the ldap_start_tls_s() method
+     */
+    if (APR_LDAP_SSL == tls) {
+        result->rc = ldapssl_install_routines(ldap);
+        if (result->rc != LDAP_SUCCESS) {
+            result->msg = ldap_err2string(result->rc);
+            result->reason = "LDAP: Could not switch SSL on for this "
+                             "connection.";
+        }
+    }
+    else if (APR_LDAP_STARTTLS == tls) {
+        result->rc = ldapssl_start_tls(ldap);
+        if (result->rc != LDAP_SUCCESS) {
+            result->msg = ldap_err2string(result->rc);
+            result->reason = "LDAP: Could not start TLS on this connection";
+        }
+    }
+    else if (APR_LDAP_STOPTLS == tls) {
+        result->rc = ldapssl_stop_tls(ldap);
+        if (result->rc != LDAP_SUCCESS) {
+            result->msg = ldap_err2string(result->rc);
+            result->reason = "LDAP: Could not stop TLS on this connection";
+        }
+    }
+#endif
+
+    /* OpenLDAP SDK */
+#if APR_HAS_OPENLDAP_LDAPSDK
+#ifdef LDAP_OPT_X_TLS
+    if (APR_LDAP_SSL == tls) {
+        int SSLmode = LDAP_OPT_X_TLS_HARD;
+        result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS, &SSLmode);
+        if (LDAP_SUCCESS != result->rc) {
+            result->reason = "LDAP: ldap_set_option failed. "
+                             "Could not set LDAP_OPT_X_TLS to "
+                             "LDAP_OPT_X_TLS_HARD";
+            result->msg = ldap_err2string(result->rc);
+        }   
+    }
+    else if (APR_LDAP_STARTTLS == tls) {
+        result->rc = ldap_start_tls_s(ldap, NULL, NULL);
+        if (LDAP_SUCCESS != result->rc) {
+            result->reason = "LDAP: ldap_start_tls_s() failed";
+            result->msg = ldap_err2string(result->rc);
+        }
+    }
+    else if (APR_LDAP_STOPTLS == tls) {
+        result->reason = "LDAP: STOPTLS is not supported by the "
+                         "OpenLDAP SDK";
+        result->rc = -1;
+    }
+#else
+    result->reason = "LDAP: SSL/TLS not yet supported by APR on this "
+                     "version of the OpenLDAP toolkit";
+    result->rc = -1;
+#endif
+#endif
+
+    /* Solaris SDK */
+#if APR_HAS_SOLARIS_LDAPSDK
+    if (APR_LDAP_NONE != tls) {
+        result->reason = "LDAP: SSL/TLS is currently not supported by "
+                         "APR on the Solaris SDK";
+        result->rc = -1;
+    }
+#endif
+
+    /* Microsoft SDK */
+#if APR_HAS_MICROSOFT_LDAPSDK
+    if (APR_LDAP_NONE == tls) {
+        mode = 0;
+        result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, &mode);
+        if (LDAP_SUCCESS != result->rc) {
+            result->reason = "LDAP: an attempt to set LDAP_OPT_SSL off "
+                             "failed.";
+            result->msg = ldap_err2string(result->rc);
+        }
+    }
+    else if (APR_LDAP_SSL == tls) {
+        mode = 1;
+        result->rc = ldap_set_option(ldap, LDAP_OPT_SSL, &mode);
+        if (LDAP_SUCCESS != result->rc) {
+            result->reason = "LDAP: an attempt to set LDAP_OPT_SSL on "
+                             "failed.";
+            result->msg = ldap_err2string(result->rc);
+        }
+    }
+    else if (APR_LDAP_STARTTLS == tls) {
+        result->rc = ldap_start_tls_s(ldap, NULL, NULL, NULL, NULL);
+        if (LDAP_SUCCESS != result->rc) {
+            result->reason = "LDAP: ldap_start_tls_s() failed";
+            result->msg = ldap_err2string(result->rc);
+        }
+    }
+    else if (APR_LDAP_STOPTLS == tls) {
+        result->rc = ldap_stop_tls_s(ldap);
+        if (LDAP_SUCCESS != result->rc) {
+            result->reason = "LDAP: ldap_stop_tls_s() failed";
+            result->msg = ldap_err2string(result->rc);
+        }
+    }
+#endif
+
+#if APR_HAS_OTHER_LDAPSDK
+    if (APR_LDAP_NONE != tls) {
+        result->reason = "LDAP: SSL/TLS is currently not supported by "
+                         "APR on this LDAP SDK";
+        result->rc = -1;
+    }
+#endif
+
+#endif /* APR_HAS_LDAP_SSL */
+
+}
+
+/**
+ * Handle APR_LDAP_OPT_TLS_CACERTFILE
+ *
+ * This function sets the CA certificate for further SSL/TLS connections.
+ *
+ * The file provided are in different formats depending on the toolkit used:
+ *
+ * Netscape: cert7.db file
+ * Novell: PEM or DER
+ * OpenLDAP: PEM (others supported?)
+ * Microsoft: unknown
+ * Solaris: unknown
+ */
+int option_set_cert(apr_pool_t *pool,
+             LDAP *ldap,
+             const void *invalue,
+             apr_ldap_err_t *result) {
+
+    apr_ldap_opt_tls_cert_t *cert = (apr_ldap_opt_tls_cert_t *)invalue;
+
+#if APR_HAS_LDAP_SSL
+
+#if APR_HAS_NETSCAPE_LDAPSDK
+#if APR_HAS_LDAP_SSL_CLIENT_INIT
+    const char *secmod = NULL;
+    const char *key3db = NULL;
+    const char *cert7db = NULL;
+
+    /* set up cert7.db, key3.db and secmod parameters */
+    while (cert) {
+        switch (cert->type) {
+            case APR_LDAP_CA_TYPE_CERT7_DB: {
+                cert7db = cert->path;
+                break;
+            }
+            case APR_LDAP_CA_TYPE_SECMOD: {
+                secmod = cert->path;
+                break;
+            }
+            case APR_LDAP_CERT_TYPE_KEY3_DB: {
+                key3db = cert->path;
+                break;
+            }
+            default: {
+                result->rc = -1;
+                result->reason = "LDAP: The Netscape/Mozilla LDAP SDK only "
+                                 "understands the CERT7, KEY3 and SECMOD "
+                                 "file types.";
+            }
+        }
+        if (result->rc != LDAP_SUCCESS) {
+            break;
+        }
+        cert = cert->next;
+    }
+
+    /* actually set the certificate parameters */
+    if (result->rc == LDAP_SUCCESS) {
+        if (secmod) {
+            result->rc = ldapssl_advclientauth_init(cert7db, NULL,
+                                                    key3db ? 1 : 0, key3db, NULL,
+                                                    1, secmod, LDAPSSL_AUTH_CNCHECK);
+            if (result->rc != LDAP_SUCCESS) {
+                result->reason = "LDAP: ldapssl_advclientauth_init() failed.";
+                result->msg = ldap_err2string(result->rc);
+            }
+        }
+        else if (key3db) {
+            result->rc = ldapssl_clientauth_init(cert7db, NULL,
+                                                    1, key3db, NULL);
+            if (result->rc != LDAP_SUCCESS) {
+                result->reason = "LDAP: ldapssl_clientauth_init() failed.";
+                result->msg = ldap_err2string(result->rc);
+            }
+        }
+        else {
+            result->rc = ldapssl_client_init(cert7db, NULL);
+            if (result->rc != LDAP_SUCCESS) {
+                result->reason = "LDAP: ldapssl_client_init() failed.";
+                result->msg = ldap_err2string(result->rc);
+            }
+        }
+    }
+#else
+    result->reason = "LDAP: ldapssl_client_init() function not "
+                     "supported by this Netscape SDK. Certificate "
+                     "authority file not set";
+    result->rc = -1;
+#endif
+#endif
+
+    /* Novell SDK */
+#if APR_HAS_NOVELL_LDAPSDK
+#if APR_HAS_LDAPSSL_CLIENT_INIT && APR_HAS_LDAPSSL_ADD_TRUSTED_CERT && APR_HAS_LDAPSSL_CLIENT_DEINIT
+    /* The Novell library cannot support per connection certificates. Error
+     * out if the ldap handle is provided.
+     */
+    if (ldap) {
+        result->rc = -1;
+        result->reason = "LDAP: The Novell LDAP SDK cannot support the setting "
+                         "of certificates or keys on a per connection basis.";
+    }
+    /* Novell's library needs to be inititalised first */
+    else {
+        result->rc = ldapssl_client_init(NULL, NULL);
+        if (LDAP_SUCCESS != result->rc) {
+            result->msg = ldap_err2string(result-> rc);
+            result->reason = apr_pstrdup (pool, "LDAP: Could not "
+                                                "initialize SSL");
+        }
+    }
+    /* set one or more certificates */
+    while (LDAP_SUCCESS == result->rc && cert) {
+        /* Novell SDK supports DER or BASE64 files. */
+        switch (cert->type) {
+            case APR_LDAP_CA_TYPE_DER: {
+                result->rc = ldapssl_add_trusted_cert((void *)cert->path,
+                                      LDAPSSL_CERT_FILETYPE_DER);
+                result->msg = ldap_err2string(result->rc);
+                break;
+            }
+            case APR_LDAP_CA_TYPE_BASE64: {
+                result->rc = ldapssl_add_trusted_cert((void *)cert->path,
+                                      LDAPSSL_CERT_FILETYPE_B64);
+                result->msg = ldap_err2string(result->rc);
+                break;
+            }
+            case APR_LDAP_CERT_TYPE_DER: {
+                result->rc = ldapssl_set_client_cert((void *)cert->path,
+                                      LDAPSSL_CERT_FILETYPE_DER,
+                                      cert->password);
+                result->msg = ldap_err2string(result->rc);
+                break;
+            }
+            case APR_LDAP_CERT_TYPE_BASE64: {
+                result->rc = ldapssl_set_client_cert((void *)cert->path,
+                                      LDAPSSL_CERT_FILETYPE_B64,
+                                      cert->password);
+                result->msg = ldap_err2string(result->rc);
+                break;
+            }
+            case APR_LDAP_KEY_TYPE_DER: {
+                result->rc = ldapssl_set_client_private_key((void *)cert->path,
+                                      LDAPSSL_CERT_FILETYPE_DER,
+                                      cert->password);
+                result->msg = ldap_err2string(result->rc);
+                break;
+            }
+            case APR_LDAP_KEY_TYPE_BASE64: {
+                result->rc = ldapssl_set_client_private_key((void *)cert->path,
+                                      LDAPSSL_CERT_FILETYPE_B64,
+                                      cert->password);
+                result->msg = ldap_err2string(result->rc);
+                break;
+            }
+            default: {
+                result->rc = -1;
+                result->reason = "LDAP: The Novell LDAP SDK only understands the "
+                                 "DER and PEM (BASE64) file types.";
+            }
+        }
+        if (LDAP_SUCCESS != result->rc) {
+            break;
+        }
+        cert = cert->next;
+    }
+#else
+    result->reason = "LDAP: ldapssl_client_init(), "
+                     "ldapssl_add_trusted_cert() or "
+                     "ldapssl_client_deinit() functions not supported "
+                     "by this Novell SDK. Certificate authority file "
+                     "not set";
+    result->rc = -1;
+#endif
+#endif
+
+    /* openldap SDK */
+#if APR_HAS_OPENLDAP_LDAPSDK
+#ifdef LDAP_OPT_X_TLS_CACERTFILE
+    /* set one or more certificates */
+    /* FIXME: make it support setting directories as well as files */
+    while (cert) {
+        /* OpenLDAP SDK supports BASE64 files. */
+        switch (cert->type) {
+            case APR_LDAP_CA_TYPE_BASE64: {
+                result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_CACERTFILE,
+                                             (void *)cert->path);
+                result->msg = ldap_err2string(result->rc);
+                break;
+            }
+            case APR_LDAP_CERT_TYPE_BASE64: {
+                result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_CERTFILE,
+                                             (void *)cert->path);
+                result->msg = ldap_err2string(result->rc);
+                break;
+            }
+            case APR_LDAP_KEY_TYPE_BASE64: {
+                result->rc = ldap_set_option(ldap, LDAP_OPT_X_TLS_KEYFILE,
+                                             (void *)cert->path);
+                result->msg = ldap_err2string(result->rc);
+                break;
+            }
+            default: {
+                result->rc = -1;
+                result->reason = "LDAP: The OpenLDAP SDK only understands the "
+                                 "PEM (BASE64) file type.";
+            }
+        }
+        if (LDAP_SUCCESS != result->rc) {
+            break;
+        }
+        cert = cert->next;
+    }
+#else
+    result->reason = "LDAP: LDAP_OPT_X_TLS_CACERTFILE not "
+                     "defined by this OpenLDAP SDK. Certificate "
+                     "authority file not set";
+    result->rc = -1;
+#endif
+#endif
+
+    /* microsoft SDK */
+#if APR_HAS_MICROSOFT_LDAPSDK
+    /* Microsoft SDK use the registry certificate store - error out here
+     * with a message explaining this.
+     */
+    result->reason = "LDAP: CA certificates cannot be set using this method, "
+                     "as they are stored in the registry instead."
+    result->rc = -1;
+#endif
+
+    /* Sun SDK */
+#if APR_HAS_SOLARIS_LDAPSDK
+    result->reason = "LDAP: Attempt to set certificate store failed. "
+                     "APR does not yet know how to set a certificate "
+                     "store on the Sun toolkit";
+    result->rc = -1;
+#endif
+
+    /* SDK not recognised */
+#if APR_HAS_OTHER_LDAPSDK
+        result->reason = "LDAP: LDAP_OPT_X_TLS_CACERTFILE not "
+                         "defined by this LDAP SDK. Certificate " 
+                         "authority file not set";
+        result->rc = -1;
+#endif
+
+#else  /* not compiled with SSL Support */
+    result->reason = "LDAP: Attempt to set certificate(s) failed. "
+                     "Not built with SSL support";
+    result->rc = -1;
+#endif /* APR_HAS_LDAP_SSL */
+
+    return result->rc;
+
+}
+
 
 #endif /* APR_HAS_LDAP */

Mime
View raw message