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 */
|