diff options
author | cvsadm <cvsadm> | 2005-01-21 00:44:34 +0000 |
---|---|---|
committer | cvsadm <cvsadm> | 2005-01-21 00:44:34 +0000 |
commit | b2093e3016027d6b5cf06b3f91f30769bfc099e2 (patch) | |
tree | cf58939393a9032182c4fbc4441164a9456e82f8 /ldap/servers/slapd/ssl.c | |
download | ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.gz ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.tar.xz ds-b2093e3016027d6b5cf06b3f91f30769bfc099e2.zip |
Moving NSCP Directory Server from DirectoryBranch to TRUNK, initial drop. (foxworth)ldapserver7x
Diffstat (limited to 'ldap/servers/slapd/ssl.c')
-rw-r--r-- | ldap/servers/slapd/ssl.c | 1499 |
1 files changed, 1499 insertions, 0 deletions
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c new file mode 100644 index 00000000..49eea76a --- /dev/null +++ b/ldap/servers/slapd/ssl.c @@ -0,0 +1,1499 @@ +/** BEGIN COPYRIGHT BLOCK + * Copyright 2001 Sun Microsystems, Inc. + * Portions copyright 1999, 2001-2003 Netscape Communications Corporation. + * All rights reserved. + * END COPYRIGHT BLOCK **/ +/* SSL-related stuff for slapd */ + +#if defined(NET_SSL) + +#if defined( _WINDOWS ) +#include <windows.h> +#include <winsock.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "proto-ntutil.h" +#include <string.h> +#include <stdlib.h> +#include <direct.h> +#include <io.h> +#endif + +#ifdef LINUX +#include <sys/param.h> +#endif + +#include <ssl.h> +#include <nss.h> +#include <key.h> +#include <sslproto.h> +#include "secmod.h" +#include <string.h> +#include <errno.h> + +#include "slap.h" + +#include "svrcore.h" +#include "fe.h" +#include <ldap_ssl.h> /* ldapssl_client_init */ +#include "certdb.h" + +/* For IRIX... */ +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + +extern char* slapd_SSL3ciphers; +extern symbol_t supported_ciphers[]; + +/* dongle_file_name is set in slapd_nss_init when we set the path for the + key, cert, and secmod files - the dongle file must be in the same directory + and use the same naming scheme +*/ +static char* dongle_file_name = NULL; + +static int _security_library_initialized = 0; +static int _ssl_listener_initialized = 0; + +/* Our name for the internal token, must match PKCS-11 config data below */ +static char *internalTokenName = "Internal (Software) Token"; + +static int stimeout; +static char *ciphers = NULL; +static char * configDN = "cn=encryption,cn=config"; + +/* Copied from libadmin/libadmin.h public/nsapi.h */ +#define SERVER_KEY_NAME "Server-Key" +#define MAGNUS_ERROR_LEN 1024 +#define LOG_WARN 0 +#define LOG_FAILURE 3 +#define FILE_PATHSEP '/' + +/* ----------------------- Multiple cipher support ------------------------ */ + + +#ifdef NET_SSL + +static char **cipher_names = NULL; +typedef struct { + char *version; + char *name; + int num; +} cipherstruct; + + +static cipherstruct _conf_ciphers[] = { + {"SSL3","rc4", SSL_EN_RC4_128_WITH_MD5}, + {"SSL3","rc4export", SSL_EN_RC4_128_EXPORT40_WITH_MD5}, + {"SSL3","rc2", SSL_EN_RC2_128_CBC_WITH_MD5}, + {"SSL3","rc2export", SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5}, + /*{"idea", SSL_EN_IDEA_128_CBC_WITH_MD5}, */ + {"SSL3","des", SSL_EN_DES_64_CBC_WITH_MD5}, + {"SSL3","desede3", SSL_EN_DES_192_EDE3_CBC_WITH_MD5}, + {"SSL3","rsa_rc4_128_md5", SSL_RSA_WITH_RC4_128_MD5}, + {"SSL3","rsa_3des_sha", SSL_RSA_WITH_3DES_EDE_CBC_SHA}, + {"SSL3","rsa_des_sha", SSL_RSA_WITH_DES_CBC_SHA}, + {"SSL3","rsa_fips_3des_sha", SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA}, + {"SSL3","rsa_fips_des_sha", SSL_RSA_FIPS_WITH_DES_CBC_SHA}, + {"SSL3","rsa_rc4_40_md5", SSL_RSA_EXPORT_WITH_RC4_40_MD5}, + {"SSL3","rsa_rc2_40_md5", SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5}, + {"SSL3","rsa_null_md5", SSL_RSA_WITH_NULL_MD5}, + {"TLS","tls_rsa_export1024_with_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA}, + {"TLS","tls_rsa_export1024_with_des_cbc_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA}, + {"SSL3","fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA}, + {"SSL3","fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA}, + {"SSL3","fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA}, + + + /*{"SSL3","dhe_dss_40_sha", SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA}, */ + {"SSL3","dhe_dss_des_sha", SSL_DHE_DSS_WITH_DES_CBC_SHA}, + {"SSL3","dhe_dss_3des_sha", SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA}, + /*{"SSL3","dhe_rsa_40_sha", SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA}, */ + {"SSL3","dhe_rsa_des_sha", SSL_DHE_RSA_WITH_DES_CBC_SHA}, + {"SSL3","dhe_rsa_3des_sha", SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA}, + + {"TLS","tls_rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA}, + {"TLS","tls_dhe_dss_aes_128_sha", TLS_DHE_DSS_WITH_AES_128_CBC_SHA}, + {"TLS","tls_dhe_rsa_aes_128_sha", TLS_DHE_RSA_WITH_AES_128_CBC_SHA}, + + {"TLS","tls_rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA}, + {"TLS","tls_dhe_dss_aes_256_sha", TLS_DHE_DSS_WITH_AES_256_CBC_SHA}, + {"TLS","tls_dhe_rsa_aes_256_sha", TLS_DHE_RSA_WITH_AES_256_CBC_SHA}, + /*{"TLS","tls_dhe_dss_1024_des_sha", TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA}, */ + {"TLS","tls_dhe_dss_1024_rc4_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA}, + {"TLS","tls_dhe_dss_rc4_128_sha", TLS_DHE_DSS_WITH_RC4_128_SHA}, + {NULL, NULL, 0} +}; + +char ** getSupportedCiphers() +{ + SSLCipherSuiteInfo info; + char *sep = "::"; + int number_of_ciphers = sizeof (_conf_ciphers) /sizeof(cipherstruct); + int i; + if (cipher_names == NULL ) { + cipher_names = (char **) slapi_ch_calloc ((number_of_ciphers +1 ) , sizeof(char *)); + for (i = 0 ; _conf_ciphers[i].name != NULL; i++ ) { + SSL_GetCipherSuiteInfo((PRUint16)_conf_ciphers[i].num,&info,sizeof(info)); + cipher_names[i] = PR_smprintf("%s%s%s%s%s%s%s%s%d\0",_conf_ciphers[i].version,sep,_conf_ciphers[i].name,sep,info.symCipherName,sep,info.macAlgorithmName,sep,info.symKeyBits); + } + cipher_names[i] = NULL; + } + return cipher_names; +} +void +_conf_setallciphers(int active) +{ + int x; + + /* MLM - change: Because null_md5 is NOT encrypted at all, force + * them to activate it by name. */ + for(x = 0; _conf_ciphers[x].name; x++) { + if(active && !strcmp(_conf_ciphers[x].name, "rsa_null_md5")) { + continue; + } +#ifdef NET_SSL + SSL_CipherPrefSetDefault(_conf_ciphers[x].num, active ? PR_TRUE : PR_FALSE); +#endif + } +} + +char * +_conf_setciphers(char *ciphers) +{ + char *t, err[MAGNUS_ERROR_LEN]; + int x, active; + char *raw = ciphers; + + /* Default is to activate all of them */ + if(!ciphers || ciphers[0] == '\0') { + _conf_setallciphers(1); + return NULL; + } +/* Enable all the ciphers by default and the following while loop would disable the user disabled ones This is needed becuase we added a new set of ciphers in the table . Right now there is no support for this from the console */ + _conf_setallciphers(1); + + t = ciphers; + while(t) { + while((*ciphers) && (isspace(*ciphers))) ++ciphers; + + switch(*ciphers++) { + case '+': + active = 1; break; + case '-': + active = 0; break; + default: + sprintf(err, "invalid ciphers <%s>: format is " + "+cipher1,-cipher2...", raw); + return slapi_ch_strdup(err); + } + if( (t = strchr(ciphers, ',')) ) + *t++ = '\0'; + + if(!strcasecmp(ciphers, "all")) + _conf_setallciphers(active); + else { + for(x = 0; _conf_ciphers[x].name; x++) { + if(!strcasecmp(ciphers, _conf_ciphers[x].name)) { + SSL_CipherPrefSetDefault(_conf_ciphers[x].num, active ? PR_TRUE : PR_FALSE); + break; + } + } + if(!_conf_ciphers[x].name) { + sprintf(err, "unknown cipher %s", ciphers); + return slapi_ch_strdup(err); + } + } + if(t) + ciphers = t; + } + return NULL; +} + +/* SSL Policy stuff */ + +/* + * Policy table + */ +static struct policy +{ + long ciphersuite; + int exportPolicy; +} policy_table[] = { + { SSL_EN_RC4_128_WITH_MD5, SSL_NOT_ALLOWED }, + { SSL_EN_RC4_128_EXPORT40_WITH_MD5, SSL_ALLOWED }, + { SSL_EN_RC2_128_CBC_WITH_MD5, SSL_NOT_ALLOWED }, + { SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5, SSL_ALLOWED }, + { SSL_EN_IDEA_128_CBC_WITH_MD5, SSL_NOT_ALLOWED }, + { SSL_EN_DES_64_CBC_WITH_MD5, SSL_NOT_ALLOWED }, + { SSL_EN_DES_192_EDE3_CBC_WITH_MD5, SSL_NOT_ALLOWED }, + + /* SSL v3 Cipher Suites */ + { SSL_RSA_WITH_NULL_MD5, SSL_ALLOWED }, +#if 0 + { SSL_RSA_WITH_NULL_SHA, SSL_ALLOWED }, +#endif + { SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_ALLOWED }, + { SSL_RSA_WITH_RC4_128_MD5, SSL_RESTRICTED }, +#if 0 + { SSL_RSA_WITH_RC4_128_SHA, SSL_NOT_ALLOWED }, +#endif + { SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, SSL_ALLOWED }, + +#if 0 + { SSL_RSA_WITH_IDEA_CBC_SHA, SSL_NOT_ALLOWED }, + { SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_ALLOWED }, +#endif + + { SSL_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED }, + { SSL_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RESTRICTED }, + +#if 0 + { SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_ALLOWED }, + { SSL_DH_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED }, + { SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED }, + { SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_ALLOWED }, + { SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED }, + { SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED }, + + { SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_ALLOWED }, + { SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED }, + { SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED }, + { SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_ALLOWED }, + { SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED }, + { SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED }, + + { SSL_DH_ANON_EXPORT_WITH_RC4_40_MD5, SSL_ALLOWED }, + { SSL_DH_ANON_WITH_RC4_128_MD5, SSL_NOT_ALLOWED }, + { SSL_DH_ANON_EXPORT_WITH_DES40_CBC_SHA, SSL_ALLOWED }, + { SSL_DH_ANON_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED }, + { SSL_DH_ANON_WITH_3DES_EDE_CBC_SHA, SSL_NOT_ALLOWED }, +#endif + + { SSL_FORTEZZA_DMS_WITH_NULL_SHA, SSL_NOT_ALLOWED }, + { SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, SSL_NOT_ALLOWED }, + { SSL_FORTEZZA_DMS_WITH_RC4_128_SHA, SSL_NOT_ALLOWED }, + + { SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA, SSL_RESTRICTED }, + { SSL_RSA_FIPS_WITH_DES_CBC_SHA, SSL_NOT_ALLOWED }, +}; + + +/* + * SSLPLCY_Install + * + * Call the SSL_CipherPolicySet function for each ciphersuite. + */ +PRStatus +SSLPLCY_Install(void) +{ + + SECStatus s = 0; + + +#ifdef NS_DOMESTIC + + s = NSS_SetDomesticPolicy(); + +#else + s = NSS_SetExportPolicy(); + +#endif + + + return s?PR_FAILURE:PR_SUCCESS; + +} + + +#endif /* NET_SSL */ + +static void +slapd_SSL_report(int degree, char *fmt, va_list args) +{ + char buf[2048]; + vsprintf( buf, fmt, args ); + LDAPDebug( LDAP_DEBUG_ANY, "SSL %s: %s\n", + (degree == LOG_FAILURE) ? "failure" : "alert", + buf, 0 ); +} + +void +slapd_SSL_error(char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + slapd_SSL_report(LOG_FAILURE, fmt, args); + exit(1); +} + +void +slapd_SSL_warn(char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + slapd_SSL_report(LOG_WARN, fmt, args); + va_end(args); +} + + +static void +server_free_alias_dir(char *s) +{ + void *mem = s; + + slapi_ch_free(&mem); +} + + +/** + * Get a particular entry + */ +static Slapi_Entry * +getConfigEntry( const char *dn, Slapi_Entry **e2 ) { + Slapi_DN sdn; + + slapi_sdn_init_dn_byref( &sdn, dn ); + slapi_search_internal_get_entry( &sdn, NULL, e2, + plugin_get_default_component_id()); + slapi_sdn_done( &sdn ); + return *e2; +} + +/** + * Free an entry + */ +static void +freeConfigEntry( Slapi_Entry ** e ) { + if ( (e != NULL) && (*e != NULL) ) { + slapi_entry_free( *e ); + *e = NULL; + } +} + +/** + * Get a list of child DNs + */ +static char ** +getChildren( char *dn ) { + Slapi_PBlock *new_pb = NULL; + Slapi_Entry **e; + int search_result = 1; + int nEntries = 0; + char **list = NULL; + + new_pb = slapi_search_internal ( dn, LDAP_SCOPE_ONELEVEL, + "(objectclass=nsEncryptionModule)", + NULL, NULL, 0); + + slapi_pblock_get( new_pb, SLAPI_NENTRIES, &nEntries); + if ( nEntries > 0 ) { + slapi_pblock_get( new_pb, SLAPI_PLUGIN_INTOP_RESULT, &search_result); + slapi_pblock_get( new_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &e); + if ( e != NULL ) { + int i; + list = (char **)slapi_ch_malloc( sizeof(*list) * (nEntries + 1)); + for ( i = 0; e[i] != NULL; i++ ) { + list[i] = slapi_ch_strdup(slapi_entry_get_dn(e[i])); + } + list[nEntries] = NULL; + } + } + slapi_free_search_results_internal(new_pb); + slapi_pblock_destroy(new_pb ); + return list; +} + +/** + * Free a list of child DNs + */ +static void +freeChildren( char **list ) { + if ( list != NULL ) { + int i; + for ( i = 0; list[i] != NULL; i++ ) { + slapi_ch_free( (void **)(&list[i]) ); + } + slapi_ch_free( (void **)(&list) ); + } +} + + +/* + * slapd_nss_init() is always called from main(), even if we do not + * plan to listen on a secure port. If config_available is 0, the + * config. entries from dse.ldif are NOT available (used only when + * running in referral mode). + * As of DS6.1, the init_ssl flag passed is ignored. + */ +int +slapd_nss_init(int init_ssl, int config_available) +{ + SECStatus secStatus; + PRErrorCode errorCode; + char *keyfn = NULL; + char *certfn = NULL; + char *val = NULL; + char certPref[1024]; + char keyPref[1024]; + char path[1024]; + int rv = 0; + int len = 0; + PRUint32 nssFlags = 0; + Slapi_Entry *ec = NULL; + char *instancedir; + + if (config_available) { + getConfigEntry( configDN, &ec ); + } + + if ( ec != NULL ) { + certfn = slapi_entry_attr_get_charptr( ec, "nscertfile" ); + keyfn = slapi_entry_attr_get_charptr( ec, "nskeyfile" ); + slapi_entry_free (ec); + ec = NULL; + } + + instancedir = config_get_instancedir(); + strcpy(path, instancedir); + slapi_ch_free_string(&instancedir); + + /* make sure path does not end in the path separator character */ + len = strlen(path); + if (path[len-1] == '/' || path[len-1] == '\\') { + path[len-1] = '\0'; + } + + /* get the server root from the path */ + val = strrchr(path, '/'); + if (!val) { + val = strrchr(path, '\\'); + } + val++; + + if(keyfn && certfn) { + if (is_abspath(certfn)) { + /* first, initialize path from the certfn */ + strcpy(path, certfn); + /* extract path from cert db filename */ + val = strrchr(path, '/'); + if (!val) { + val = strrchr(path, '\\'); + } + *val = 0; /* path is initialized */ + /* next, init the cert db prefix */ + val++; + strcpy(certPref, val); + } else { + strcpy(val, certfn); + val = strrchr(path, '/'); + if (!val) { + val = strrchr(path, '\\'); + } + val++; + strcpy(certPref, val); + *val = '\0'; + } + /* path represents now the base directory where cert, key, pin, and module db live */ + /* richm - use strrstr to get the last occurance of -cert in the string, in case + the instance is named slapd-cert - the certdb name will be slapd-cert-cert7.db + */ + val = PL_strrstr(certPref, "-cert"); + val++; + *val = '\0'; + /* certPref keeps the prefix added to the cert db, usually "slapd-myserver-" */ + + /* now find the key db prefix */ + val = strrchr(keyfn, '/'); + if (!val) { + val = strrchr(keyfn, '\\'); + } + if (val != NULL) { + val++; + } else { + val = keyfn; + } + strcpy(keyPref, val); + /* richm - use strrstr to get the last occurance of -key in the string, in case + the instance is named slapd-key - the keydb name will be slapd-key-key3.db + */ + val = PL_strrstr(keyPref, "-key"); + val++; + *val = '\0'; + /* keypref keeps the prefix added to the key db, usually "slapd-myserver-" */ + } else { + if ( config_get_security() ) { + /* Have to have the key and cert file names to enable an SSL port */ + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Failed to retrieve SSL " + "configuration information (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s): " + "nskeyfile: %s, nscertfile: %s ", + errorCode, slapd_pr_strerror(errorCode), + (keyfn ? "found" : "not found"), + (certfn ? "found" : "not found")); + } + sprintf(certPref, "%s-", val); + strcpy(keyPref, certPref); + strcpy(val, "alias/"); + } + + slapi_ch_free((void **) &certfn); + slapi_ch_free((void **) &keyfn); + + /******** Initialise NSS *********/ + + nssFlags &= (~NSS_INIT_READONLY); + slapd_pk11_configurePKCS11(NULL, NULL, tokDes, ptokDes, NULL, NULL, NULL, NULL, 0, 0 ); + secStatus = NSS_Initialize(path, certPref, keyPref, "secmod.db", nssFlags); + + dongle_file_name = PR_smprintf("%s/%spin.txt", path, certPref); + + if (secStatus != SECSuccess) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: NSS initialization failed (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s): " + "path: %s, certdb prefix: %s, keydb prefix: %s.", + errorCode, slapd_pr_strerror(errorCode), path, certPref, keyPref); + rv = -1; + } + + /****** end of NSS Initialization ******/ + + return rv; +} + + + + + +/* + * slapd_ssl_init() is called from main() if we plan to listen + * on a secure port. + */ +int +slapd_ssl_init() { + PRErrorCode errorCode; + char ** family_list; + char *val = NULL; + char cipher_string[1024]; + int rv = 0; + PK11SlotInfo *slot; +#ifndef _WIN32 + SVRCOREStdPinObj *StdPinObj; +#else + SVRCOREFilePinObj *FilePinObj; + SVRCOREAltPinObj *AltPinObj; + SVRCORENTUserPinObj *NTUserPinObj; +#endif + Slapi_Entry *entry = NULL; + + /* Get general information */ + + getConfigEntry( configDN, &entry ); + + val = slapi_entry_attr_get_charptr( entry, "nssslSessionTimeout" ); + ciphers = slapi_entry_attr_get_charptr( entry, "nsssl3ciphers" ); + + /* We are currently using the value of sslSessionTimeout + for ssl3SessionTimeout, see SSL_ConfigServerSessionIDCache() */ + /* Note from Tom Weinstein on the meaning of the timeout: + + Timeouts are in seconds. '0' means use the default, which is + 24hrs for SSL3 and 100 seconds for SSL2. + */ + + if(!val) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Failed to retrieve SSL " + "configuration information (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s): " + "nssslSessionTimeout: %s ", + errorCode, slapd_pr_strerror(errorCode), + (val ? "found" : "not found")); + slapi_ch_free((void **) &val); + slapi_ch_free((void **) &ciphers); + return -1; + } + + stimeout = atoi(val); + slapi_ch_free((void **) &val); + +#ifndef _WIN32 + if ( SVRCORE_CreateStdPinObj(&StdPinObj, dongle_file_name, PR_TRUE) != + SVRCORE_Success) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Unable to create PinObj (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return -1; + } + SVRCORE_RegisterPinObj((SVRCOREPinObj *)StdPinObj); +#else + if (SVRCORE_CreateFilePinObj(&FilePinObj, dongle_file_name) != + SVRCORE_Success) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Unable to create FilePinObj (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return -1; + } + if (SVRCORE_CreateNTUserPinObj(&NTUserPinObj) != SVRCORE_Success){ + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Unable to create NTUserPinObj (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return -1; + } + if (SVRCORE_CreateAltPinObj(&AltPinObj, (SVRCOREPinObj *)FilePinObj, + (SVRCOREPinObj *)NTUserPinObj) != SVRCORE_Success) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Unable to create AltPinObj (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return -1; + } + SVRCORE_RegisterPinObj((SVRCOREPinObj *)AltPinObj); + +#endif /* _WIN32 */ + + if((family_list = getChildren(configDN))) { + char **family; + char *token; + char *activation; + + for (family = family_list; *family; family++) { + + token = NULL; + activation = NULL; + + freeConfigEntry( &entry ); + + getConfigEntry( *family, &entry ); + if ( entry == NULL ) { + continue; + } + + activation = slapi_entry_attr_get_charptr( entry, "nssslactivation" ); + if((!activation) || (!strcasecmp(activation, "off"))) { + /* this family was turned off, goto next */ + slapi_ch_free((void **) &activation); + continue; + } + + slapi_ch_free((void **) &activation); + + token = slapi_entry_attr_get_charptr( entry, "nsssltoken" ); + if( token ) { + if( !strcasecmp(token, "internal") || + !strcasecmp(token, "internal (software)")) + slot = slapd_pk11_getInternalKeySlot(); + else + slot = slapd_pk11_findSlotByName(token); + } else { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Unable to get token (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return -1; + } + + slapi_ch_free((void **) &token); + + if (!slot) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Unable to find slot (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return -1; + } + /* authenticate */ + if(slapd_pk11_authenticate(slot, PR_TRUE, NULL) != SECSuccess) + { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Unable to authenticate (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return -1; + } + } + freeChildren( family_list ); + } + freeConfigEntry( &entry ); + + if(SSLPLCY_Install() != PR_SUCCESS) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Unable to set SSL export policy (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return -1; + } + + + /* ugaston- Cipher preferences must be set before any sslSocket is created + * for such sockets to take preferences into account. + */ + + /* Step Three.5: Set SSL cipher preferences */ + *cipher_string = 0; + if(ciphers && (*ciphers) && strcmp(ciphers, "blank")) + strcpy(cipher_string, ciphers); + slapi_ch_free((void **) &ciphers); + + if( NULL != (val = _conf_setciphers(cipher_string)) ) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Failed to set SSL cipher " + "preference information: %s (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + val, errorCode, slapd_pr_strerror(errorCode)); + rv = 3; + slapi_ch_free((void **) &val); + } + + freeConfigEntry( &entry ); + + + /* Introduce a way of knowing whether slapd_ssl_init has + * already been executed. */ + _security_library_initialized = 1; + + + if ( rv != 0 ) + return rv; + + + return 0; + +} + + +int slapd_ssl_init2(PRFileDesc **fd, int startTLS) +{ + PRFileDesc *pr_sock, *sock = (*fd); + PRErrorCode errorCode; + SECStatus rv = SECFailure; + char ** family_list; + CERTCertificate *cert = NULL; + SECKEYPrivateKey *key = NULL; + char errorbuf[BUFSIZ]; + char *val = NULL; + int nFamilies = 0; + SECStatus sslStatus; + int slapd_SSLclientAuth; + char* tmpDir; + Slapi_Entry *e = NULL; + + /* turn off the PKCS11 pin interactive mode */ +#ifndef _WIN32 + SVRCOREStdPinObj *StdPinObj; + + StdPinObj = (SVRCOREStdPinObj *)SVRCORE_GetRegisteredPinObj(); + SVRCORE_SetStdPinInteractive(StdPinObj, PR_FALSE); +#endif + + errorbuf[0] = '\0'; + + /* Import pr fd into SSL */ + pr_sock = SSL_ImportFD( NULL, sock ); + if( pr_sock == (PRFileDesc *)NULL ) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Failed to import NSPR " + "fd into SSL (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return 1; + } + + (*fd) = pr_sock; + + /* Step / Three.6 / + * - If in FIPS mode, authenticate to the token before + * doing anything else + */ + { + PK11SlotInfo *slot = slapd_pk11_getInternalSlot(); + if (!slot) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Unable to get internal slot (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return -1; + } + + if(slapd_pk11_isFIPS()) { + if(slapd_pk11_authenticate(slot, PR_TRUE, NULL) != SECSuccess) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Unable to authenticate (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return -1; + } + } + + slapd_pk11_setSlotPWValues(slot, 0, 0); + } + + + + /* + * Now, get the complete list of cipher families. Each family + * has a token name and personality name which we'll use to find + * appropriate keys and certs, and call SSL_ConfigSecureServer + * with. + */ + + if((family_list = getChildren(configDN))) { + char **family; + char cert_name[1024]; + char *token; + char *personality; + char *activation; + + for (family = family_list; *family; family++) { + token = NULL; + personality = NULL; + activation = NULL; + + getConfigEntry( *family, &e ); + if ( e == NULL ) { + continue; + } + + activation = slapi_entry_attr_get_charptr( e, "nssslactivation" ); + if((!activation) || (!strcasecmp(activation, "off"))) { + /* this family was turned off, goto next */ + slapi_ch_free((void **) &activation); + freeConfigEntry( &e ); + continue; + } + + slapi_ch_free((void **) &activation); + + token = slapi_entry_attr_get_charptr( e, "nsssltoken" ); + personality = slapi_entry_attr_get_charptr( e, "nssslpersonalityssl" ); + if( token && personality ) { + if( !strcasecmp(token, "internal") || + !strcasecmp(token, "internal (software)") ) + strcpy(cert_name, personality); + else + /* external PKCS #11 token - attach token name */ + sprintf(cert_name, "%s:%s", token, personality); + } + else { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Failed to get cipher " + "family information. Missing nsssltoken or" + "nssslpersonalityssl in %s (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + *family, errorCode, slapd_pr_strerror(errorCode)); + slapi_ch_free((void **) &token); + slapi_ch_free((void **) &personality); + freeConfigEntry( &e ); + continue; + } + + slapi_ch_free((void **) &token); + + /* Step Four -- Locate the server certificate */ + cert = slapd_pk11_findCertFromNickname(cert_name, NULL); + + if (cert == NULL) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Can't find " + "certificate (%s) for family %s (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + cert_name, *family, + errorCode, slapd_pr_strerror(errorCode)); + } + /* Step Five -- Get the private key from cert */ + if( cert != NULL ) + key = slapd_pk11_findKeyByAnyCert(cert, NULL); + + if (key == NULL) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Unable to retrieve " + "private key for cert %s of family %s (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + cert_name, *family, + errorCode, slapd_pr_strerror(errorCode)); + slapi_ch_free((void **) &personality); + CERT_DestroyCertificate(cert); + cert = NULL; + freeConfigEntry( &e ); + continue; + } + + /* Step Six -- Configure Secure Server Mode */ + if(pr_sock) { + SECCertificateUsage returnedUsages; + rv = CERT_VerifyCertificateNow( + CERT_GetDefaultCertDB(), cert, PR_TRUE, + certificateUsageSSLServer, + SSL_RevealPinArg(pr_sock), + &returnedUsages); + if (SECSuccess == rv) { + if( slapd_pk11_fortezzaHasKEA(cert) == PR_TRUE ) { + rv = SSL_ConfigSecureServer(*fd, cert, key, kt_fortezza); + } + else { + rv = SSL_ConfigSecureServer(*fd, cert, key, kt_rsa); + } + if (SECSuccess != rv) { + errorCode = PR_GetError(); + slapd_SSL_warn("ConfigSecureServer: " + "Server key/certificate is " + "bad for cert %s of family %s (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + cert_name, *family, errorCode, + slapd_pr_strerror(errorCode)); + } + } else { + /* verify certificate failed */ + /* If the common name in the subject DN for the certificate + * is not identical to the domain name passed in the + * hostname parameter, SECFailure. */ + errorCode = PR_GetError(); + slapd_SSL_warn("CERT_VerifyCertificateNow: " + "verify certificate failed " + "for cert %s of family %s (" + SLAPI_COMPONENT_NAME_NSPR + " error %d - %s)", + cert_name, *family, errorCode, + slapd_pr_strerror(errorCode)); + } + } + if (cert) { + CERT_DestroyCertificate(cert); + cert = NULL; + } + if (SECSuccess != rv) { + slapi_ch_free((void **) &personality); + freeConfigEntry( &e ); + continue; + } + nFamilies++; + freeConfigEntry( &e ); + } + freeChildren( family_list ); + } + + + if ( !nFamilies ) { + slapd_SSL_error("None of the cipher are valid"); + return -1; + } + + /* Step Seven -- Configure Server Session ID Cache */ + + tmpDir = slapd_get_tmp_dir(); + + slapi_log_error( + SLAPI_LOG_TRACE, + "slapd_ssl_init2", + "tmp dir = %s\n", tmpDir); + + rv = SSL_ConfigServerSessionIDCache(0, stimeout, stimeout, tmpDir); + if (rv) { + errorCode = PR_GetError(); + if (errorCode == ENOSPC) { + slapd_SSL_error("Config of server nonce cache failed, " + "out of disk space! Make more room in /tmp " + "and try again. (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + } + else { + slapd_SSL_error("Config of server nonce cache failed (error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + } + return rv; + } + + sslStatus = SSL_OptionSet(pr_sock, SSL_SECURITY, PR_TRUE); + if (sslStatus != SECSuccess) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Failed to enable security " + "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + return -1; + } + + sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, PR_TRUE); + if (sslStatus != SECSuccess) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Failed to enable SSLv3 " + "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + } + + sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, PR_TRUE); + if (sslStatus != SECSuccess) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Failed to enable TLS " + "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + } +/* Explicitly disabling SSL2 - NGK */ + sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL2, PR_FALSE); + + /* Retrieve the SSL Client Authentication status from cn=config */ + /* Set a default value if no value found */ + getConfigEntry( configDN, &e ); + val = NULL; + if ( e != NULL ) { + val = slapi_entry_attr_get_charptr( e, "nssslclientauth" ); + } + + if( !val ) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Cannot get SSL Client " + "Authentication status. No nsslclientauth in %s (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + configDN, errorCode, slapd_pr_strerror(errorCode)); + switch( SLAPD_SSLCLIENTAUTH_DEFAULT ) { + case SLAPD_SSLCLIENTAUTH_OFF: + val = "off"; + break; + case SLAPD_SSLCLIENTAUTH_ALLOWED: + val = "allowed"; + break; + case SLAPD_SSLCLIENTAUTH_REQUIRED: + val = "required"; + break; + default: + val = "allowed"; + break; + } + } + if( config_set_SSLclientAuth( "nssslclientauth", val, errorbuf, + CONFIG_APPLY ) != LDAP_SUCCESS ) { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Cannot set SSL Client " + "Authentication status to \"%s\", error (%s). " + "Supported values are \"off\", \"allowed\" " + "and \"required\". (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + val, errorbuf, errorCode, slapd_pr_strerror(errorCode)); + } + + freeConfigEntry( &e ); + + if(( slapd_SSLclientAuth = config_get_SSLclientAuth()) != SLAPD_SSLCLIENTAUTH_OFF ) { + int err; + switch (slapd_SSLclientAuth) { + case SLAPD_SSLCLIENTAUTH_ALLOWED: +#ifdef SSL_REQUIRE_CERTIFICATE /* new feature */ + if ((err = SSL_OptionSet (pr_sock, SSL_REQUIRE_CERTIFICATE, PR_FALSE)) < 0) { + PRErrorCode prerr = PR_GetError(); + LDAPDebug (LDAP_DEBUG_ANY, + "SSL_OptionSet(SSL_REQUIRE_CERTIFICATE,PR_FALSE) %d " + SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", + err, prerr, slapd_pr_strerror(prerr)); + } +#endif + /* Give the client a clear opportunity to send her certificate: */ + case SLAPD_SSLCLIENTAUTH_REQUIRED: + if ((err = SSL_OptionSet (pr_sock, SSL_REQUEST_CERTIFICATE, PR_TRUE)) < 0) { + PRErrorCode prerr = PR_GetError(); + LDAPDebug (LDAP_DEBUG_ANY, + "SSL_OptionSet(SSL_REQUEST_CERTIFICATE,PR_TRUE) %d " + SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n", + err, prerr, slapd_pr_strerror(prerr)); + } + default: break; + } + } + + /* Introduce a way of knowing whether slapd_ssl_init2 has + * already been executed. + * The cases in which slapd_ssl_init2 is executed during an + * Start TLS operation are not taken into account, for it is + * the fact of being executed by the server's SSL listener socket + * that matters. */ + + if (!startTLS) + _ssl_listener_initialized = 1; /* --ugaston */ + + return 0; +} + +/* richm 20020227 + To do LDAP client SSL init, we need to do + + static void + ldapssl_basic_init( void ) + { + PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); + + PR_SetConcurrency( 4 ); + } + NSS_Init(certdbpath); + SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_FALSE); + SSL_OptionSetDefault(SSL_ENABLE_SSLdirs +3, PR_TRUE); +#ifdef NS_DOMESTIC + s = NSS_SetDomesticPolicy(); +#elif NS_EXPORT + s = NSS_SetExportPolicy(); + +We already do pr_init, we don't need pr_setconcurrency, we already do nss_init and the rest + +*/ + +int +slapd_SSL_client_init() +{ + return 0; +} + +static int +slapd_SSL_client_auth (LDAP* ld) +{ + int rc = 0; + PRErrorCode errorCode; + char* pw = NULL; + char ** family_list; + Slapi_Entry *entry = NULL; + char cert_name[1024]; + char *token = NULL; +#ifndef _WIN32 + SVRCOREStdPinObj *StdPinObj; +#else + SVRCOREAltPinObj *AltPinObj; +#endif + SVRCOREError err = SVRCORE_Success; + + if((family_list = getChildren(configDN))) { + char **family; + char *personality = NULL; + char *activation = NULL; + char *cipher = NULL; + + for (family = family_list; *family; family++) { + getConfigEntry( *family, &entry ); + if ( entry == NULL ) { + continue; + } + + activation = slapi_entry_attr_get_charptr( entry, "nssslactivation" ); + if((!activation) || (!strcasecmp(activation, "off"))) { + /* this family was turned off, goto next */ + slapi_ch_free((void **) &activation); + freeConfigEntry( &entry ); + continue; + } + + slapi_ch_free((void **) &activation); + + personality = slapi_entry_attr_get_charptr( entry, "nssslpersonalityssl" ); + cipher = slapi_entry_attr_get_charptr( entry, "cn" ); + if ( cipher && !strcasecmp(cipher, "RSA" )) { + char *ssltoken; + + /* If there already is a token name, use it */ + if (token) { + slapi_ch_free((void **) &personality); + slapi_ch_free((void **) &cipher); + freeConfigEntry( &entry ); + continue; + } + + ssltoken = slapi_entry_attr_get_charptr( entry, "nsssltoken" ); + if( ssltoken && personality ) { + if( !strcasecmp(ssltoken, "internal") || + !strcasecmp(ssltoken, "internal (software)") ) { + + /* Translate config internal name to more + * readable form. Certificate name is just + * the personality for internal tokens. + */ + token = slapi_ch_strdup(internalTokenName); + strcpy(cert_name, personality); + slapi_ch_free((void **) &ssltoken); + } else { + /* external PKCS #11 token - attach token name */ + /*ssltoken was already dupped and we don't need it anymore*/ + token = ssltoken; + sprintf(cert_name, "%s:%s", token, personality); + } + } else { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Failed to get cipher " + "family information. Missing nsssltoken or" + "nssslpersonalityssl in %s (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + *family, errorCode, slapd_pr_strerror(errorCode)); + slapi_ch_free((void **) &ssltoken); + slapi_ch_free((void **) &personality); + slapi_ch_free((void **) &cipher); + freeConfigEntry( &entry ); + continue; + } + } else { /* external PKCS #11 cipher */ + char *ssltoken; + + ssltoken = slapi_entry_attr_get_charptr( entry, "nsssltoken" ); + if( token && personality ) { + + /* free the old token and remember the new one */ + if (token) slapi_ch_free((void **)&token); + token = ssltoken; /*ssltoken was already dupped and we don't need it anymore*/ + + /* external PKCS #11 token - attach token name */ + sprintf(cert_name, "%s:%s", token, personality); + } else { + errorCode = PR_GetError(); + slapd_SSL_warn("Security Initialization: Failed to get cipher " + "family information. Missing nsssltoken or" + "nssslpersonalityssl in %s (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + *family, errorCode, slapd_pr_strerror(errorCode)); + slapi_ch_free((void **) &ssltoken); + slapi_ch_free((void **) &personality); + slapi_ch_free((void **) &cipher); + freeConfigEntry( &entry ); + continue; + } + + } + slapi_ch_free((void **) &personality); + slapi_ch_free((void **) &cipher); + freeConfigEntry( &entry ); + } /* end of for */ + + freeChildren( family_list ); + } + + /* Free config data */ + + /* We cannot allow NSS to cache outgoing client auth connections - + each client auth connection must have it's own non-shared SSL + connection to the peer so that it will go through the + entire handshake protocol every time including the use of its + own unique client cert - see bug 605457 + */ + + ldapssl_set_option(ld, SSL_NO_CACHE, PR_TRUE); + +#ifndef _WIN32 + StdPinObj = (SVRCOREStdPinObj *)SVRCORE_GetRegisteredPinObj(); + err = SVRCORE_StdPinGetPin( &pw, StdPinObj, token ); +#else + AltPinObj = (SVRCOREAltPinObj *)SVRCORE_GetRegisteredPinObj(); + pw = SVRCORE_GetPin( (SVRCOREPinObj *)AltPinObj, token, PR_FALSE); +#endif + if ( err != SVRCORE_Success || pw == NULL) { + errorCode = PR_GetError(); + slapd_SSL_warn("SSL client authentication cannot be used " + "(no password). (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + errorCode, slapd_pr_strerror(errorCode)); + } else { + rc = ldapssl_enable_clientauth (ld, SERVER_KEY_NAME, pw, cert_name); + if (rc != 0) { + errorCode = PR_GetError(); + slapd_SSL_warn("ldapssl_enable_clientauth(%s, %s) %i (" + SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + SERVER_KEY_NAME, cert_name, rc, + errorCode, slapd_pr_strerror(errorCode)); + } + } + + if (token) slapi_ch_free((void**)&token); + slapi_ch_free((void**)&pw); + + LDAPDebug (LDAP_DEBUG_TRACE, "slapd_SSL_client_auth() %i\n", rc, 0, 0); + return rc; +} + +int +slapd_simple_client_bind_s(LDAP* ld, char* DN, char* pw, int LDAPv) +{ + int rc; + PRErrorCode errorCode; + + ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, (void *) &LDAPv); + rc = ldap_simple_bind_s (ld, DN, pw); + if (rc != 0) { + errorCode = PR_GetError(); + slapd_SSL_warn("ldap_simple_bind_s(%s, %s) %i (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + DN, pw, rc, errorCode, slapd_pr_strerror(errorCode)); + } + LDAPDebug (LDAP_DEBUG_TRACE, "slapd_simple_client_bind_s(%s, %i) %i\n", DN, LDAPv, rc); + return rc; +} + +int +slapd_SSL_client_bind_s (LDAP* ld, char* DN, char* pw, int use_SSL, int LDAPv) +{ + int rc; + struct berval noCred = {0, 0}; + + if (!use_SSL || LDAPv == LDAP_VERSION2) { + rc = slapd_simple_client_bind_s(ld, DN, pw, LDAPv); + } else { + + LDAPDebug ( + LDAP_DEBUG_TRACE, + "slapd_SSL_client_bind_s: Trying SSL Client Authentication\n", + 0, 0, 0); + + rc = slapd_SSL_client_auth(ld); + + if(rc != 0) + { + LDAPDebug ( + LDAP_DEBUG_TRACE, + "slapd_SSL_client_bind_s: SSL Client Auth Failed during replication Bind\n", + 0, 0, 0); + return rc; + } + + rc = ldap_sasl_bind_s (ld, "", LDAP_SASL_EXTERNAL, &noCred, + NULL /* LDAPControl **serverctrls */, + NULL /* LDAPControl **clientctrls */, + NULL /* struct berval **servercredp */); + + } + LDAPDebug ( + LDAP_DEBUG_TRACE, + "slapd_SSL_client_bind_s(%i,%i) %i\n", use_SSL, LDAPv, rc); + return rc; +} + +int +slapd_sasl_ext_client_bind (LDAP* ld, int **msgid) +{ + int rc; + PRErrorCode errorCode; + struct berval noCred = {0, 0}; + + LDAPDebug ( + LDAP_DEBUG_TRACE, + "slapd_sasl_ext_client_bind: Trying SSL Client Authentication\n", + 0, 0, 0); + + rc = slapd_SSL_client_auth(ld); + if(rc != 0) + { + LDAPDebug ( + LDAP_DEBUG_TRACE, + "slapd_sasl_ext_client_bind: SSL Client Auth Failed during replication Bind\n", + 0, 0, 0); + return rc; + } + + rc = ldap_sasl_bind (ld, "", LDAP_SASL_EXTERNAL, &noCred, + NULL, + NULL, + *msgid); + if (rc != 0) { + errorCode = PR_GetError(); + slapd_SSL_warn("ldap_sasl_bind(\"\",LDAP_SASL_EXTERNAL) %i (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)", + rc, errorCode, slapd_pr_strerror(errorCode)); + } + + LDAPDebug ( + LDAP_DEBUG_TRACE, + "slapd_sasl_ext_client_bind %i\n", rc, 0, 0); + + return rc; +} + + +int slapd_Client_auth(LDAP* ld) +{ + int rc=0; + + rc = slapd_SSL_client_auth (ld); + + return rc; +} + + +/* Function for keeping track of the SSL initialization status: + * - returns 1: when slapd_ssl_init has been executed + */ +int +slapd_security_library_is_initialized() +{ + return _security_library_initialized; +} + + +/* Function for keeping track of the SSL listener socket initialization status: + * - returns 1: when slapd_ssl_init2 has been executed + */ +int +slapd_ssl_listener_is_initialized() +{ + return _ssl_listener_initialized; +} + + +char* slapd_get_tmp_dir() +{ + static char tmpdir[] = "/tmp"; + static char tmp[256]; + char* instanceDir; +#if defined( XP_WIN32 ) + unsigned ilen; + char pch; +#endif + struct stat ffinfo; + + tmp[0] = '\0'; + + if((instanceDir = config_get_instancedir()) == NULL) + { + slapi_log_error( + SLAPI_LOG_FATAL, + "slapd_get_tmp_dir", + "config_get_instancedir returns NULL Setting tmp dir to default\n"); + +#if defined( XP_WIN32 ) + ilen = strlen(tmp); + GetTempPath( ilen+1, tmp ); + /* Remove trailing slash. */ + pch = tmp[ilen-1]; + if( pch == '\\' || pch == '/' ) + tmp[ilen-1] = '\0'; + return tmp; +#else + return( tmpdir ); +#endif + } + + sprintf(tmp,"%s/tmp",instanceDir); + +#if defined( XP_WIN32 ) + for(ilen=0;ilen < strlen(tmp); ilen++) + { + if(tmp[ilen]=='/') + tmp[ilen]='\\'; + } +#endif + + if(stat(tmp,&ffinfo) == -1) +#if defined( XP_WIN32 ) + if(CreateDirectory(tmp, NULL) == 0) + { + slapi_log_error( + SLAPI_LOG_FATAL, + "slapd_get_tmp_dir", + "CreateDirectory(%s, NULL) Error: %s\n", + tmp, strerror(errno)); + return ( tmpdir ); + } +#else + if(mkdir(tmp, 00770) == -1) + { + slapi_log_error( + SLAPI_LOG_FATAL, + "slapd_get_tmp_dir", + "mkdir(%s, 00770) Error: %s\n", + tmp, strerror(errno)); + return ( tmpdir ); + } +#endif + + return ( tmp ); + +} + +#endif /* NET_SSL */ |