xref: /titanic_51/usr/src/lib/libldap5/sources/ldap/ssldap/clientinit.c (revision 694c35faa87b858ecdadfe4fc592615f4eefbb07)
17c478bd9Sstevel@tonic-gate /*
24a16f9a6SMilan Jurik  * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
37c478bd9Sstevel@tonic-gate  */
47c478bd9Sstevel@tonic-gate 
57c478bd9Sstevel@tonic-gate /*
67c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the Netscape Public
77c478bd9Sstevel@tonic-gate  * License Version 1.1 (the "License"); you may not use this file
87c478bd9Sstevel@tonic-gate  * except in compliance with the License. You may obtain a copy of
97c478bd9Sstevel@tonic-gate  * the License at http://www.mozilla.org/NPL/
107c478bd9Sstevel@tonic-gate  *
117c478bd9Sstevel@tonic-gate  * Software distributed under the License is distributed on an "AS
127c478bd9Sstevel@tonic-gate  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
137c478bd9Sstevel@tonic-gate  * implied. See the License for the specific language governing
147c478bd9Sstevel@tonic-gate  * rights and limitations under the License.
157c478bd9Sstevel@tonic-gate  *
167c478bd9Sstevel@tonic-gate  * The Original Code is Mozilla Communicator client code, released
177c478bd9Sstevel@tonic-gate  * March 31, 1998.
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * The Initial Developer of the Original Code is Netscape
207c478bd9Sstevel@tonic-gate  * Communications Corporation. Portions created by Netscape are
217c478bd9Sstevel@tonic-gate  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
227c478bd9Sstevel@tonic-gate  * Rights Reserved.
237c478bd9Sstevel@tonic-gate  *
247c478bd9Sstevel@tonic-gate  * Contributor(s):
257c478bd9Sstevel@tonic-gate  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate /*
287c478bd9Sstevel@tonic-gate  * clientinit.c
297c478bd9Sstevel@tonic-gate  */
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate #if defined(NET_SSL)
327c478bd9Sstevel@tonic-gate 
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #if defined( _WINDOWS )
357c478bd9Sstevel@tonic-gate #include <windows.h>
367c478bd9Sstevel@tonic-gate #include "proto-ntutil.h"
377c478bd9Sstevel@tonic-gate #endif
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate #include <nspr.h>
407c478bd9Sstevel@tonic-gate #include <plstr.h>
417c478bd9Sstevel@tonic-gate #include <synch.h>
427c478bd9Sstevel@tonic-gate #include <cert.h>
437c478bd9Sstevel@tonic-gate #include <key.h>
447c478bd9Sstevel@tonic-gate #include <ssl.h>
457c478bd9Sstevel@tonic-gate #include <sslproto.h>
467c478bd9Sstevel@tonic-gate #include <ldap.h>
477c478bd9Sstevel@tonic-gate #include <ldappr.h>
487c478bd9Sstevel@tonic-gate #include <solaris-int.h>
497c478bd9Sstevel@tonic-gate 
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate #include <nss.h>
527c478bd9Sstevel@tonic-gate 
537c478bd9Sstevel@tonic-gate /* XXX:mhein The following is a workaround for the redefinition of */
547c478bd9Sstevel@tonic-gate /*	     const problem on OSF.  Fix to be provided by NSS */
557c478bd9Sstevel@tonic-gate /*	     This is a pretty benign workaround for us which */
567c478bd9Sstevel@tonic-gate /*	     should not cause problems in the future even if */
577c478bd9Sstevel@tonic-gate /*	     we forget to take it out :-) */
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate #ifdef OSF1V4D
607c478bd9Sstevel@tonic-gate #ifndef __STDC__
617c478bd9Sstevel@tonic-gate #  define __STDC__
627c478bd9Sstevel@tonic-gate #endif /* __STDC__ */
637c478bd9Sstevel@tonic-gate #endif /* OSF1V4D */
647c478bd9Sstevel@tonic-gate 
657c478bd9Sstevel@tonic-gate #ifndef FILE_PATHSEP
667c478bd9Sstevel@tonic-gate #define FILE_PATHSEP '/'
677c478bd9Sstevel@tonic-gate #endif
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate  * StartTls()
717c478bd9Sstevel@tonic-gate  */
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate #define START_TLS_OID "1.3.6.1.4.1.1466.20037"
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate static PRStatus local_SSLPLCY_Install(void);
767c478bd9Sstevel@tonic-gate 
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate  * This little tricky guy keeps us from initializing twice
797c478bd9Sstevel@tonic-gate  */
807c478bd9Sstevel@tonic-gate static int		inited = 0;
817c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK
827c478bd9Sstevel@tonic-gate mutex_t			inited_mutex = DEFAULTMUTEX;
837c478bd9Sstevel@tonic-gate #else
847c478bd9Sstevel@tonic-gate static mutex_t		inited_mutex = DEFAULTMUTEX;
857c478bd9Sstevel@tonic-gate #endif	/* _SOLARIS_SDK */
867c478bd9Sstevel@tonic-gate #if 0	/* UNNEEDED BY LIBLDAP */
877c478bd9Sstevel@tonic-gate static char  tokDes[34] = "Internal (Software) Database     ";
887c478bd9Sstevel@tonic-gate static char ptokDes[34] = "Internal (Software) Token        ";
897c478bd9Sstevel@tonic-gate #endif	/* UNNEEDED BY LIBLDAP */
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate 
927c478bd9Sstevel@tonic-gate /* IN:					     */
937c478bd9Sstevel@tonic-gate /* string:	/u/mhein/.netscape/mykey3.db */
947c478bd9Sstevel@tonic-gate /* OUT:					     */
957c478bd9Sstevel@tonic-gate /* dir: 	/u/mhein/.netscape/	     */
967c478bd9Sstevel@tonic-gate /* prefix:	my			     */
977c478bd9Sstevel@tonic-gate /* key:		key3.db			     */
987c478bd9Sstevel@tonic-gate 
997c478bd9Sstevel@tonic-gate static int
1007c478bd9Sstevel@tonic-gate splitpath(char *string, char *dir, char *prefix, char *key) {
1017c478bd9Sstevel@tonic-gate         char *k;
1027c478bd9Sstevel@tonic-gate         char *s;
1037c478bd9Sstevel@tonic-gate         char *d = string;
1047c478bd9Sstevel@tonic-gate         char *l;
1057c478bd9Sstevel@tonic-gate         int  len = 0;
1067c478bd9Sstevel@tonic-gate 
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate         if (string == NULL)
1097c478bd9Sstevel@tonic-gate                 return (-1);
1107c478bd9Sstevel@tonic-gate 
1117c478bd9Sstevel@tonic-gate         /* goto the end of the string, and walk backwards until */
1127c478bd9Sstevel@tonic-gate         /* you get to the first pathseparator */
1137c478bd9Sstevel@tonic-gate         len = PL_strlen(string);
1147c478bd9Sstevel@tonic-gate         l = string + len - 1;
1157c478bd9Sstevel@tonic-gate         while (l != string && *l != '/' && *l != '\\')
1167c478bd9Sstevel@tonic-gate                         l--;
1177c478bd9Sstevel@tonic-gate         /* search for the .db */
1187c478bd9Sstevel@tonic-gate         if ((k = PL_strstr(l, ".db")) != NULL) {
1197c478bd9Sstevel@tonic-gate                 /* now we are sitting on . of .db */
1207c478bd9Sstevel@tonic-gate 
1217c478bd9Sstevel@tonic-gate                 /* move backward to the first 'c' or 'k' */
1227c478bd9Sstevel@tonic-gate                 /* indicating cert or key */
1237c478bd9Sstevel@tonic-gate                 while (k != l && *k != 'c' && *k != 'k')
1247c478bd9Sstevel@tonic-gate                         k--;
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate                 /* move backwards to the first path separator */
1277c478bd9Sstevel@tonic-gate                 if (k != d && k > d)
1287c478bd9Sstevel@tonic-gate                         s = k - 1;
1297c478bd9Sstevel@tonic-gate                 while (s != d && *s != '/' && *s != '\\')
1307c478bd9Sstevel@tonic-gate                         s--;
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate                 /* if we are sitting on top of a path */
1337c478bd9Sstevel@tonic-gate                 /* separator there is no prefix */
1347c478bd9Sstevel@tonic-gate                 if (s + 1 == k) {
1357c478bd9Sstevel@tonic-gate                         /* we know there is no prefix */
1367c478bd9Sstevel@tonic-gate                         prefix = '\0';
1377c478bd9Sstevel@tonic-gate                         PL_strcpy(key, k);
1387c478bd9Sstevel@tonic-gate                         *k = '\0';
1397c478bd9Sstevel@tonic-gate                         PL_strcpy(dir, d);
1407c478bd9Sstevel@tonic-gate                 } else {
1417c478bd9Sstevel@tonic-gate                         /* grab the prefix */
1427c478bd9Sstevel@tonic-gate                         PL_strcpy(key, k);
1437c478bd9Sstevel@tonic-gate                         *k = '\0';
1447c478bd9Sstevel@tonic-gate                         PL_strcpy(prefix, ++s);
1457c478bd9Sstevel@tonic-gate                         *s = '\0';
1467c478bd9Sstevel@tonic-gate                         PL_strcpy(dir, d);
1477c478bd9Sstevel@tonic-gate                 }
1487c478bd9Sstevel@tonic-gate         } else {
1497c478bd9Sstevel@tonic-gate                 /* neither *key[0-9].db nor *cert[0=9].db found */
1507c478bd9Sstevel@tonic-gate                 return (-1);
1517c478bd9Sstevel@tonic-gate         }
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	return (0);
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 
1577c478bd9Sstevel@tonic-gate static PRStatus local_SSLPLCY_Install(void)
1587c478bd9Sstevel@tonic-gate {
159*694c35faSJosef 'Jeff' Sipek 	return NSS_SetDomesticPolicy() ? PR_FAILURE : PR_SUCCESS;
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate 
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 
1647c478bd9Sstevel@tonic-gate static void
1657c478bd9Sstevel@tonic-gate ldapssl_basic_init( void )
1667c478bd9Sstevel@tonic-gate {
1677c478bd9Sstevel@tonic-gate #ifndef _SOLARIS_SDK
1687c478bd9Sstevel@tonic-gate 	/*
1697c478bd9Sstevel@tonic-gate 	 * NSPR is initialized in .init on SOLARIS
1707c478bd9Sstevel@tonic-gate 	 */
1717c478bd9Sstevel@tonic-gate     /* PR_Init() must to be called before everything else... */
1727c478bd9Sstevel@tonic-gate     PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
1737c478bd9Sstevel@tonic-gate #endif
1747c478bd9Sstevel@tonic-gate 
1757c478bd9Sstevel@tonic-gate     PR_SetConcurrency( 4 );	/* work around for NSPR 3.x I/O hangs */
1767c478bd9Sstevel@tonic-gate }
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate /*
1817c478bd9Sstevel@tonic-gate  * Cover  functions for malloc(), calloc(), strdup() and free() that are
1827c478bd9Sstevel@tonic-gate  * compatible with the NSS libraries (they seem to use the C runtime
1837c478bd9Sstevel@tonic-gate  * library malloc/free so these functions are quite simple right now).
1847c478bd9Sstevel@tonic-gate  */
1857c478bd9Sstevel@tonic-gate static void *
1867c478bd9Sstevel@tonic-gate ldapssl_malloc( size_t size )
1877c478bd9Sstevel@tonic-gate {
1887c478bd9Sstevel@tonic-gate     void	*p;
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate     p = malloc( size );
1917c478bd9Sstevel@tonic-gate     return p;
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate 
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate static void *
1967c478bd9Sstevel@tonic-gate ldapssl_calloc( int nelem, size_t elsize )
1977c478bd9Sstevel@tonic-gate {
1987c478bd9Sstevel@tonic-gate     void	*p;
1997c478bd9Sstevel@tonic-gate 
2007c478bd9Sstevel@tonic-gate     p = calloc( nelem, elsize );
2017c478bd9Sstevel@tonic-gate     return p;
2027c478bd9Sstevel@tonic-gate }
2037c478bd9Sstevel@tonic-gate 
2047c478bd9Sstevel@tonic-gate 
2057c478bd9Sstevel@tonic-gate static char *
2067c478bd9Sstevel@tonic-gate ldapssl_strdup( const char *s )
2077c478bd9Sstevel@tonic-gate {
2087c478bd9Sstevel@tonic-gate     char	*scopy;
2097c478bd9Sstevel@tonic-gate 
2107c478bd9Sstevel@tonic-gate     if ( NULL == s ) {
2117c478bd9Sstevel@tonic-gate 	scopy = NULL;
2127c478bd9Sstevel@tonic-gate     } else {
2137c478bd9Sstevel@tonic-gate 	scopy = strdup( s );
2147c478bd9Sstevel@tonic-gate     }
2157c478bd9Sstevel@tonic-gate     return scopy;
2167c478bd9Sstevel@tonic-gate }
2177c478bd9Sstevel@tonic-gate 
2187c478bd9Sstevel@tonic-gate 
2197c478bd9Sstevel@tonic-gate static void
2207c478bd9Sstevel@tonic-gate ldapssl_free( void **pp )
2217c478bd9Sstevel@tonic-gate {
2227c478bd9Sstevel@tonic-gate     if ( NULL != pp && NULL != *pp ) {
2237c478bd9Sstevel@tonic-gate 	free( (void *)*pp );
2247c478bd9Sstevel@tonic-gate 	*pp = NULL;
2257c478bd9Sstevel@tonic-gate     }
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate 
2287c478bd9Sstevel@tonic-gate 
2294a16f9a6SMilan Jurik #ifdef _SOLARIS_SDK
2304a16f9a6SMilan Jurik /*
2314a16f9a6SMilan Jurik  * Disable strict fork detection of NSS library to allow safe fork of
2324a16f9a6SMilan Jurik  * consumers. Otherwise NSS will not work after fork because it was not
2334a16f9a6SMilan Jurik  * deinitialized before fork and there is no safe way how to do it after fork.
2344a16f9a6SMilan Jurik  *
2354a16f9a6SMilan Jurik  * Return values:
2364a16f9a6SMilan Jurik  *     1 - DISABLED was already set, no modification to environment
2374a16f9a6SMilan Jurik  *     0 - successfully modified environment, old value saved to enval if there
2384a16f9a6SMilan Jurik  *         was some
2394a16f9a6SMilan Jurik  *    -1 - setenv or strdup failed, the environment was left unchanged
2404a16f9a6SMilan Jurik  *
2414a16f9a6SMilan Jurik  */
2424a16f9a6SMilan Jurik static int
2434a16f9a6SMilan Jurik update_nss_strict_fork_env(char **enval)
2444a16f9a6SMilan Jurik {
2454a16f9a6SMilan Jurik 	char *temps = getenv("NSS_STRICT_NOFORK");
2464a16f9a6SMilan Jurik 	if (temps == NULL) {
2474a16f9a6SMilan Jurik 		*enval = NULL;
2484a16f9a6SMilan Jurik 	} else if (strncmp(temps, "DISABLED", 9) == 0) {
2494a16f9a6SMilan Jurik 		/* Do not need to set as DISABLED, it is already set. */
2504a16f9a6SMilan Jurik 		*enval = NULL;
2514a16f9a6SMilan Jurik 		return (1);
2524a16f9a6SMilan Jurik 	} else {
2534a16f9a6SMilan Jurik 		if ((*enval = ldapssl_strdup(temps)) == NULL)
2544a16f9a6SMilan Jurik 			return (-1);
2554a16f9a6SMilan Jurik 	}
2564a16f9a6SMilan Jurik 	return (setenv("NSS_STRICT_NOFORK", "DISABLED", 1));
2574a16f9a6SMilan Jurik }
2584a16f9a6SMilan Jurik 
2594a16f9a6SMilan Jurik /*
2604a16f9a6SMilan Jurik  * Reset environment variable NSS_STRICT_NOFORK to value before
2614a16f9a6SMilan Jurik  * update_nss_strict_fork_env() call or remove it from environment if it did
2624a16f9a6SMilan Jurik  * not exist.
2634a16f9a6SMilan Jurik  * NSS_STRICT_NOFORK=DISABLED is needed only during NSS initialization to
2644a16f9a6SMilan Jurik  * disable activation of atfork handler in NSS which is invalidating
2654a16f9a6SMilan Jurik  * initialization in child process after fork.
2664a16f9a6SMilan Jurik  */
2674a16f9a6SMilan Jurik static int
2684a16f9a6SMilan Jurik reset_nss_strict_fork_env(char *enval)
2694a16f9a6SMilan Jurik {
2704a16f9a6SMilan Jurik 	if (enval != NULL) {
2714a16f9a6SMilan Jurik 		return (setenv("NSS_STRICT_NOFORK", enval, 1));
2724a16f9a6SMilan Jurik 	} else {
2734a16f9a6SMilan Jurik 		return (unsetenv("NSS_STRICT_NOFORK"));
2744a16f9a6SMilan Jurik 	}
2754a16f9a6SMilan Jurik }
2764a16f9a6SMilan Jurik #endif
2774a16f9a6SMilan Jurik 
2784a16f9a6SMilan Jurik 
2797c478bd9Sstevel@tonic-gate static char *
2807c478bd9Sstevel@tonic-gate buildDBName(const char *basename, const char *dbname)
2817c478bd9Sstevel@tonic-gate {
2827c478bd9Sstevel@tonic-gate 	char		*result;
2837c478bd9Sstevel@tonic-gate 	PRUint32	len, pathlen, addslash;
2847c478bd9Sstevel@tonic-gate 
2857c478bd9Sstevel@tonic-gate 	if (basename)
2867c478bd9Sstevel@tonic-gate 	{
2877c478bd9Sstevel@tonic-gate 	    if (( len = PL_strlen( basename )) > 3
2887c478bd9Sstevel@tonic-gate 		&& PL_strcasecmp( ".db", basename + len - 3 ) == 0 ) {
2897c478bd9Sstevel@tonic-gate 		return (ldapssl_strdup(basename));
2907c478bd9Sstevel@tonic-gate 	    }
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate 	    pathlen = len;
2937c478bd9Sstevel@tonic-gate 	    len = pathlen + PL_strlen(dbname) + 1;
2947c478bd9Sstevel@tonic-gate 	    addslash = ( pathlen > 0 &&
2957c478bd9Sstevel@tonic-gate 		(( *(basename + pathlen - 1) != FILE_PATHSEP ) ||
2967c478bd9Sstevel@tonic-gate 		( *(basename + pathlen - 1) != '\\'  )));
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	    if ( addslash ) {
2997c478bd9Sstevel@tonic-gate 		++len;
3007c478bd9Sstevel@tonic-gate 	    }
3017c478bd9Sstevel@tonic-gate 	    if (( result = ldapssl_malloc( len )) != NULL ) {
3027c478bd9Sstevel@tonic-gate 		PL_strcpy( result, basename );
3037c478bd9Sstevel@tonic-gate 		if ( addslash ) {
3047c478bd9Sstevel@tonic-gate 		    *(result+pathlen) = FILE_PATHSEP;  /* replaces '\0' */
3057c478bd9Sstevel@tonic-gate 		    ++pathlen;
3067c478bd9Sstevel@tonic-gate 		}
3077c478bd9Sstevel@tonic-gate 		PL_strcpy(result+pathlen, dbname);
3087c478bd9Sstevel@tonic-gate 	    }
3097c478bd9Sstevel@tonic-gate 
3107c478bd9Sstevel@tonic-gate 	}
3117c478bd9Sstevel@tonic-gate 
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate 	return result;
3147c478bd9Sstevel@tonic-gate }
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate char *
3177c478bd9Sstevel@tonic-gate GetCertDBName(void *alias, int dbVersion)
3187c478bd9Sstevel@tonic-gate {
3197c478bd9Sstevel@tonic-gate     char		*source;
3207c478bd9Sstevel@tonic-gate     char dbname[128];
3217c478bd9Sstevel@tonic-gate 
3227c478bd9Sstevel@tonic-gate     source = (char *)alias;
3237c478bd9Sstevel@tonic-gate 
3247c478bd9Sstevel@tonic-gate     if (!source)
3257c478bd9Sstevel@tonic-gate     {
3267c478bd9Sstevel@tonic-gate 	source = "";
3277c478bd9Sstevel@tonic-gate     }
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate     sprintf(dbname, "cert%d.db",dbVersion);
3307c478bd9Sstevel@tonic-gate     return(buildDBName(source, dbname));
3317c478bd9Sstevel@tonic-gate 
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate }
3347c478bd9Sstevel@tonic-gate 
3357c478bd9Sstevel@tonic-gate /*
3367c478bd9Sstevel@tonic-gate  * return database name by appending "dbname" to "path".
3377c478bd9Sstevel@tonic-gate  * this code doesn't need to be terribly efficient (not called often).
3387c478bd9Sstevel@tonic-gate  */
3397c478bd9Sstevel@tonic-gate /* XXXceb this is the old function.  To be removed eventually */
3407c478bd9Sstevel@tonic-gate static char *
3417c478bd9Sstevel@tonic-gate GetDBName(const char *dbname, const char *path)
3427c478bd9Sstevel@tonic-gate {
3437c478bd9Sstevel@tonic-gate     char		*result;
3447c478bd9Sstevel@tonic-gate     PRUint32	len, pathlen;
3457c478bd9Sstevel@tonic-gate     int		addslash;
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate     if ( dbname == NULL ) {
3487c478bd9Sstevel@tonic-gate 	dbname = "";
3497c478bd9Sstevel@tonic-gate     }
3507c478bd9Sstevel@tonic-gate 
3517c478bd9Sstevel@tonic-gate     if ((path == NULL) || (*path == 0)) {
3527c478bd9Sstevel@tonic-gate 	result = ldapssl_strdup(dbname);
3537c478bd9Sstevel@tonic-gate     } else {
3547c478bd9Sstevel@tonic-gate 	pathlen = PL_strlen(path);
3557c478bd9Sstevel@tonic-gate 	len = pathlen + PL_strlen(dbname) + 1;
3567c478bd9Sstevel@tonic-gate 	addslash = ( path[pathlen - 1] != '/' );
3577c478bd9Sstevel@tonic-gate 	if ( addslash ) {
3587c478bd9Sstevel@tonic-gate 	    ++len;
3597c478bd9Sstevel@tonic-gate 	}
3607c478bd9Sstevel@tonic-gate 	if (( result = ldapssl_malloc( len )) != NULL ) {
3617c478bd9Sstevel@tonic-gate 	    PL_strcpy( result, path );
3627c478bd9Sstevel@tonic-gate 	    if ( addslash ) {
3637c478bd9Sstevel@tonic-gate 		*(result+pathlen) = '/';  /* replaces '\0' */
3647c478bd9Sstevel@tonic-gate 		++pathlen;
3657c478bd9Sstevel@tonic-gate 	    }
3667c478bd9Sstevel@tonic-gate 	    PL_strcpy(result+pathlen, dbname);
3677c478bd9Sstevel@tonic-gate 	}
3687c478bd9Sstevel@tonic-gate     }
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate     return result;
3717c478bd9Sstevel@tonic-gate }
3727c478bd9Sstevel@tonic-gate 
3737c478bd9Sstevel@tonic-gate /*
3747c478bd9Sstevel@tonic-gate  * Initialize ns/security so it can be used for SSL client authentication.
3757c478bd9Sstevel@tonic-gate  * It is safe to call this more than once.
3767c478bd9Sstevel@tonic-gate  *
3777c478bd9Sstevel@tonic-gate  * If needkeydb == 0, no key database is opened and SSL server authentication
3787c478bd9Sstevel@tonic-gate  * is supported but not client authentication.
3797c478bd9Sstevel@tonic-gate  *
3807c478bd9Sstevel@tonic-gate  * If "certdbpath" is NULL or "", the default cert. db is used (typically
3817c478bd9Sstevel@tonic-gate  * ~/.netscape/cert7.db).
3827c478bd9Sstevel@tonic-gate  *
3837c478bd9Sstevel@tonic-gate  * If "certdbpath" ends with ".db" (case-insensitive compare), then
3847c478bd9Sstevel@tonic-gate  * it is assumed to be a full path to the cert. db file; otherwise,
3857c478bd9Sstevel@tonic-gate  * it is assumed to be a directory that contains a file called
3867c478bd9Sstevel@tonic-gate  * "cert7.db" or "cert.db".
3877c478bd9Sstevel@tonic-gate  *
3887c478bd9Sstevel@tonic-gate  * If certdbhandle is non-NULL, it is assumed to be a pointer to a
3897c478bd9Sstevel@tonic-gate  * SECCertDBHandle structure.  It is fine to pass NULL since this
3907c478bd9Sstevel@tonic-gate  * routine will allocate one for you (CERT_GetDefaultDB() can be
3917c478bd9Sstevel@tonic-gate  * used to retrieve the cert db handle).
3927c478bd9Sstevel@tonic-gate  *
3937c478bd9Sstevel@tonic-gate  * If "keydbpath" is NULL or "", the default key db is used (typically
3947c478bd9Sstevel@tonic-gate  * ~/.netscape/key3.db).
3957c478bd9Sstevel@tonic-gate  *
3967c478bd9Sstevel@tonic-gate  * If "keydbpath" ends with ".db" (case-insensitive compare), then
3977c478bd9Sstevel@tonic-gate  * it is assumed to be a full path to the key db file; otherwise,
3987c478bd9Sstevel@tonic-gate  * it is assumed to be a directory that contains a file called
3997c478bd9Sstevel@tonic-gate  * "key3.db"
4007c478bd9Sstevel@tonic-gate  *
4017c478bd9Sstevel@tonic-gate  * If certdbhandle is non-NULL< it is assumed to be a pointed to a
4027c478bd9Sstevel@tonic-gate  * SECKEYKeyDBHandle structure.  It is fine to pass NULL since this
4037c478bd9Sstevel@tonic-gate  * routine will allocate one for you (SECKEY_GetDefaultDB() can be
4047c478bd9Sstevel@tonic-gate  * used to retrieve the cert db handle).
4057c478bd9Sstevel@tonic-gate  */
4067c478bd9Sstevel@tonic-gate int
4077c478bd9Sstevel@tonic-gate LDAP_CALL
4087c478bd9Sstevel@tonic-gate ldapssl_clientauth_init( const char *certdbpath, void *certdbhandle,
4097c478bd9Sstevel@tonic-gate     const int needkeydb, const char *keydbpath, void *keydbhandle )
4107c478bd9Sstevel@tonic-gate 
4117c478bd9Sstevel@tonic-gate {
4127c478bd9Sstevel@tonic-gate     int	rc;
4134a16f9a6SMilan Jurik #ifdef _SOLARIS_SDK
4144a16f9a6SMilan Jurik     char *enval;
4154a16f9a6SMilan Jurik     int rcenv = 0;
4164a16f9a6SMilan Jurik #endif
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate     /*
4197c478bd9Sstevel@tonic-gate      *     LDAPDebug(LDAP_DEBUG_TRACE, "ldapssl_clientauth_init\n",0 ,0 ,0);
4207c478bd9Sstevel@tonic-gate      */
4217c478bd9Sstevel@tonic-gate 
4227c478bd9Sstevel@tonic-gate     mutex_lock(&inited_mutex);
4237c478bd9Sstevel@tonic-gate     if ( inited ) {
4247c478bd9Sstevel@tonic-gate 	mutex_unlock(&inited_mutex);
4257c478bd9Sstevel@tonic-gate 	return( 0 );
4267c478bd9Sstevel@tonic-gate     }
4277c478bd9Sstevel@tonic-gate 
4287c478bd9Sstevel@tonic-gate     ldapssl_basic_init();
4297c478bd9Sstevel@tonic-gate 
4304a16f9a6SMilan Jurik #ifdef _SOLARIS_SDK
4314a16f9a6SMilan Jurik     if ((rcenv = update_nss_strict_fork_env(&enval)) == -1) {
4324a16f9a6SMilan Jurik 	mutex_unlock(&inited_mutex);
4334a16f9a6SMilan Jurik 	return (-1);
4344a16f9a6SMilan Jurik     }
4354a16f9a6SMilan Jurik #endif
4367c478bd9Sstevel@tonic-gate 
4377c478bd9Sstevel@tonic-gate     /* Open the certificate database */
4387c478bd9Sstevel@tonic-gate     rc = NSS_Init(certdbpath);
4394a16f9a6SMilan Jurik #ifdef _SOLARIS_SDK
4404a16f9a6SMilan Jurik     /* Error from NSS_Init() more important! */
4414a16f9a6SMilan Jurik     if ((rcenv != 1) && (reset_nss_strict_fork_env(enval) != 0) && (rc == 0)) {
4424a16f9a6SMilan Jurik 	ldapssl_free(&enval);
4434a16f9a6SMilan Jurik 	mutex_unlock(&inited_mutex);
4444a16f9a6SMilan Jurik 	return (-1);
4454a16f9a6SMilan Jurik     }
4464a16f9a6SMilan Jurik     ldapssl_free(&enval);
4474a16f9a6SMilan Jurik #endif
4487c478bd9Sstevel@tonic-gate     if (rc != 0) {
4497c478bd9Sstevel@tonic-gate 	if ((rc = PR_GetError()) >= 0)
4507c478bd9Sstevel@tonic-gate 	    rc = -1;
4517c478bd9Sstevel@tonic-gate 	mutex_unlock(&inited_mutex);
4527c478bd9Sstevel@tonic-gate 	return (rc);
4537c478bd9Sstevel@tonic-gate     }
4547c478bd9Sstevel@tonic-gate 
4557c478bd9Sstevel@tonic-gate     if (SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_FALSE)
4567c478bd9Sstevel@tonic-gate 	    || SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE)) {
4577c478bd9Sstevel@tonic-gate 	if (( rc = PR_GetError()) >= 0 ) {
4587c478bd9Sstevel@tonic-gate 	    rc = -1;
4597c478bd9Sstevel@tonic-gate 	}
4607c478bd9Sstevel@tonic-gate 	mutex_unlock(&inited_mutex);
4617c478bd9Sstevel@tonic-gate 	return( rc );
4627c478bd9Sstevel@tonic-gate     }
4637c478bd9Sstevel@tonic-gate 
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate     if (local_SSLPLCY_Install() == PR_FAILURE) {
4677c478bd9Sstevel@tonic-gate       mutex_unlock(&inited_mutex);
4687c478bd9Sstevel@tonic-gate       return( -1 );
4697c478bd9Sstevel@tonic-gate     }
4707c478bd9Sstevel@tonic-gate 
4717c478bd9Sstevel@tonic-gate     inited = 1;
4727c478bd9Sstevel@tonic-gate     mutex_unlock(&inited_mutex);
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate     return( 0 );
4757c478bd9Sstevel@tonic-gate 
4767c478bd9Sstevel@tonic-gate }
4777c478bd9Sstevel@tonic-gate 
4787c478bd9Sstevel@tonic-gate /*
4797c478bd9Sstevel@tonic-gate  * Initialize ns/security so it can be used for SSL client authentication.
4807c478bd9Sstevel@tonic-gate  * It is safe to call this more than once.
4817c478bd9Sstevel@tonic-gate  *
4827c478bd9Sstevel@tonic-gate  * If needkeydb == 0, no key database is opened and SSL server authentication
4837c478bd9Sstevel@tonic-gate  * is supported but not client authentication.
4847c478bd9Sstevel@tonic-gate  *
4857c478bd9Sstevel@tonic-gate  * If "certdbpath" is NULL or "", the default cert. db is used (typically
4867c478bd9Sstevel@tonic-gate  * ~/.netscape/cert7.db).
4877c478bd9Sstevel@tonic-gate  *
4887c478bd9Sstevel@tonic-gate  * If "certdbpath" ends with ".db" (case-insensitive compare), then
4897c478bd9Sstevel@tonic-gate  * it is assumed to be a full path to the cert. db file; otherwise,
4907c478bd9Sstevel@tonic-gate  * it is assumed to be a directory that contains a file called
4917c478bd9Sstevel@tonic-gate  * "cert7.db" or "cert.db".
4927c478bd9Sstevel@tonic-gate  *
4937c478bd9Sstevel@tonic-gate  * If certdbhandle is non-NULL, it is assumed to be a pointer to a
4947c478bd9Sstevel@tonic-gate  * SECCertDBHandle structure.  It is fine to pass NULL since this
4957c478bd9Sstevel@tonic-gate  * routine will allocate one for you (CERT_GetDefaultDB() can be
4967c478bd9Sstevel@tonic-gate  * used to retrieve the cert db handle).
4977c478bd9Sstevel@tonic-gate  *
4987c478bd9Sstevel@tonic-gate  * If "keydbpath" is NULL or "", the default key db is used (typically
4997c478bd9Sstevel@tonic-gate  * ~/.netscape/key3.db).
5007c478bd9Sstevel@tonic-gate  *
5017c478bd9Sstevel@tonic-gate  * If "keydbpath" ends with ".db" (case-insensitive compare), then
5027c478bd9Sstevel@tonic-gate  * it is assumed to be a full path to the key db file; otherwise,
5037c478bd9Sstevel@tonic-gate  * it is assumed to be a directory that contains a file called
5047c478bd9Sstevel@tonic-gate  * "key3.db"
5057c478bd9Sstevel@tonic-gate  *
5067c478bd9Sstevel@tonic-gate  * If certdbhandle is non-NULL< it is assumed to be a pointed to a
5077c478bd9Sstevel@tonic-gate  * SECKEYKeyDBHandle structure.  It is fine to pass NULL since this
5087c478bd9Sstevel@tonic-gate  * routine will allocate one for you (SECKEY_GetDefaultDB() can be
5097c478bd9Sstevel@tonic-gate  * used to retrieve the cert db handle).  */
5107c478bd9Sstevel@tonic-gate int
5117c478bd9Sstevel@tonic-gate LDAP_CALL
5127c478bd9Sstevel@tonic-gate ldapssl_advclientauth_init(
5137c478bd9Sstevel@tonic-gate     const char *certdbpath, void *certdbhandle,
5147c478bd9Sstevel@tonic-gate     const int needkeydb, const char *keydbpath, void *keydbhandle,
5157c478bd9Sstevel@tonic-gate     const int needsecmoddb, const char *secmoddbpath,
5167c478bd9Sstevel@tonic-gate     const int sslstrength )
5177c478bd9Sstevel@tonic-gate {
5187c478bd9Sstevel@tonic-gate     int	rc;
5194a16f9a6SMilan Jurik #ifdef _SOLARIS_SDK
5204a16f9a6SMilan Jurik     char *enval;
5214a16f9a6SMilan Jurik     int rcenv = 0;
5224a16f9a6SMilan Jurik #endif
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate     mutex_lock(&inited_mutex);
5257c478bd9Sstevel@tonic-gate     if ( inited ) {
5267c478bd9Sstevel@tonic-gate 	mutex_unlock(&inited_mutex);
5277c478bd9Sstevel@tonic-gate 	return( 0 );
5287c478bd9Sstevel@tonic-gate     }
5297c478bd9Sstevel@tonic-gate 
5307c478bd9Sstevel@tonic-gate     /*
5317c478bd9Sstevel@tonic-gate      *    LDAPDebug(LDAP_DEBUG_TRACE, "ldapssl_advclientauth_init\n",0 ,0 ,0);
5327c478bd9Sstevel@tonic-gate      */
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate     ldapssl_basic_init();
5357c478bd9Sstevel@tonic-gate 
5364a16f9a6SMilan Jurik #ifdef _SOLARIS_SDK
5374a16f9a6SMilan Jurik     if ((rcenv = update_nss_strict_fork_env(&enval)) == -1) {
5384a16f9a6SMilan Jurik 	mutex_unlock(&inited_mutex);
5394a16f9a6SMilan Jurik 	return (-1);
5404a16f9a6SMilan Jurik     }
5414a16f9a6SMilan Jurik #endif
5424a16f9a6SMilan Jurik 
5437c478bd9Sstevel@tonic-gate     rc = NSS_Init(certdbpath);
5444a16f9a6SMilan Jurik #ifdef _SOLARIS_SDK
5454a16f9a6SMilan Jurik     /* Error from NSS_Init() more important! */
5464a16f9a6SMilan Jurik     if ((rcenv != 1) && (reset_nss_strict_fork_env(enval) != 0) && (rc == 0)) {
5474a16f9a6SMilan Jurik 	ldapssl_free(&enval);
5484a16f9a6SMilan Jurik 	mutex_unlock(&inited_mutex);
5494a16f9a6SMilan Jurik 	return (-1);
5504a16f9a6SMilan Jurik     }
5514a16f9a6SMilan Jurik     ldapssl_free(&enval);
5524a16f9a6SMilan Jurik #endif
5537c478bd9Sstevel@tonic-gate     if (rc != 0) {
5547c478bd9Sstevel@tonic-gate 	if ((rc = PR_GetError()) >= 0)
5557c478bd9Sstevel@tonic-gate 	    rc = -1;
5567c478bd9Sstevel@tonic-gate 	mutex_unlock(&inited_mutex);
5577c478bd9Sstevel@tonic-gate 	return (rc);
5587c478bd9Sstevel@tonic-gate     }
5597c478bd9Sstevel@tonic-gate 
5607c478bd9Sstevel@tonic-gate     if (local_SSLPLCY_Install() == PR_FAILURE) {
5617c478bd9Sstevel@tonic-gate       mutex_unlock(&inited_mutex);
5627c478bd9Sstevel@tonic-gate       return( -1 );
5637c478bd9Sstevel@tonic-gate     }
5647c478bd9Sstevel@tonic-gate 
5657c478bd9Sstevel@tonic-gate     inited = 1;
5667c478bd9Sstevel@tonic-gate     mutex_unlock(&inited_mutex);
5677c478bd9Sstevel@tonic-gate 
5687c478bd9Sstevel@tonic-gate     return( ldapssl_set_strength( NULL, sslstrength));
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate 
5737c478bd9Sstevel@tonic-gate /*
5747c478bd9Sstevel@tonic-gate  * Initialize ns/security so it can be used for SSL client authentication.
5757c478bd9Sstevel@tonic-gate  * It is safe to call this more than once.
5767c478bd9Sstevel@tonic-gate   */
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate /*
5797c478bd9Sstevel@tonic-gate  * XXXceb  This is a hack until the new IO functions are done.
5807c478bd9Sstevel@tonic-gate  * this function lives in ldapsinit.c
5817c478bd9Sstevel@tonic-gate  */
5827c478bd9Sstevel@tonic-gate void set_using_pkcs_functions( int val );
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate int
5857c478bd9Sstevel@tonic-gate LDAP_CALL
5867c478bd9Sstevel@tonic-gate ldapssl_pkcs_init( const struct ldapssl_pkcs_fns *pfns )
5877c478bd9Sstevel@tonic-gate {
5887c478bd9Sstevel@tonic-gate 
5897c478bd9Sstevel@tonic-gate     char		*certdbName, *s, *keydbpath;
5907c478bd9Sstevel@tonic-gate     char		*certdbPrefix, *keydbPrefix;
5917c478bd9Sstevel@tonic-gate     char		*confDir, *keydbName;
5927c478bd9Sstevel@tonic-gate     static char         *secmodname =  "secmod.db";
5937c478bd9Sstevel@tonic-gate     int			rc;
5944a16f9a6SMilan Jurik #ifdef _SOLARIS_SDK
5954a16f9a6SMilan Jurik     char *enval;
5964a16f9a6SMilan Jurik     int rcenv = 0;
5974a16f9a6SMilan Jurik #endif
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate     mutex_lock(&inited_mutex);
6007c478bd9Sstevel@tonic-gate     if ( inited ) {
6017c478bd9Sstevel@tonic-gate 	mutex_unlock(&inited_mutex);
6027c478bd9Sstevel@tonic-gate 	return( 0 );
6037c478bd9Sstevel@tonic-gate     }
6047c478bd9Sstevel@tonic-gate /*
6057c478bd9Sstevel@tonic-gate  * XXXceb  This is a hack until the new IO functions are done.
6067c478bd9Sstevel@tonic-gate  * this function MUST be called before ldap_enable_clienauth.
6077c478bd9Sstevel@tonic-gate  *
6087c478bd9Sstevel@tonic-gate  */
6097c478bd9Sstevel@tonic-gate     set_using_pkcs_functions( 1 );
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate     /*
6127c478bd9Sstevel@tonic-gate      *    LDAPDebug(LDAP_DEBUG_TRACE, "ldapssl_pkcs_init\n",0 ,0 ,0);
6137c478bd9Sstevel@tonic-gate      */
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate 
6167c478bd9Sstevel@tonic-gate     ldapssl_basic_init();
6177c478bd9Sstevel@tonic-gate 
6187c478bd9Sstevel@tonic-gate     pfns->pkcs_getcertpath( NULL, &s);
6197c478bd9Sstevel@tonic-gate     confDir = ldapssl_strdup( s );
6207c478bd9Sstevel@tonic-gate     certdbPrefix = ldapssl_strdup( s );
6217c478bd9Sstevel@tonic-gate     certdbName = ldapssl_strdup( s );
6227c478bd9Sstevel@tonic-gate     *certdbPrefix = 0;
6237c478bd9Sstevel@tonic-gate     splitpath(s, confDir, certdbPrefix, certdbName);
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate     pfns->pkcs_getkeypath( NULL, &s);
6267c478bd9Sstevel@tonic-gate     keydbpath = ldapssl_strdup( s );
6277c478bd9Sstevel@tonic-gate     keydbPrefix = ldapssl_strdup( s );
6287c478bd9Sstevel@tonic-gate     keydbName = ldapssl_strdup( s );
6297c478bd9Sstevel@tonic-gate     *keydbPrefix = 0;
6307c478bd9Sstevel@tonic-gate     splitpath(s, keydbpath, keydbPrefix, keydbName);
6317c478bd9Sstevel@tonic-gate 
6327c478bd9Sstevel@tonic-gate 
6337c478bd9Sstevel@tonic-gate     /* verify confDir == keydbpath and adjust as necessary */
6347c478bd9Sstevel@tonic-gate     ldapssl_free((void **)&certdbName);
6357c478bd9Sstevel@tonic-gate     ldapssl_free((void **)&keydbName);
6367c478bd9Sstevel@tonic-gate     ldapssl_free((void **)&keydbpath);
6377c478bd9Sstevel@tonic-gate 
6384a16f9a6SMilan Jurik #ifdef _SOLARIS_SDK
6394a16f9a6SMilan Jurik     if ((rcenv = update_nss_strict_fork_env(&enval)) == -1) {
6404a16f9a6SMilan Jurik 	mutex_unlock(&inited_mutex);
6414a16f9a6SMilan Jurik 	return (-1);
6424a16f9a6SMilan Jurik     }
6434a16f9a6SMilan Jurik #endif
6444a16f9a6SMilan Jurik 
6457c478bd9Sstevel@tonic-gate     rc = NSS_Initialize(confDir,certdbPrefix,keydbPrefix,secmodname,
6467c478bd9Sstevel@tonic-gate 		NSS_INIT_READONLY);
6477c478bd9Sstevel@tonic-gate 
6487c478bd9Sstevel@tonic-gate     ldapssl_free((void **)&certdbPrefix);
6497c478bd9Sstevel@tonic-gate     ldapssl_free((void **)&keydbPrefix);
6507c478bd9Sstevel@tonic-gate     ldapssl_free((void **)&confDir);
6517c478bd9Sstevel@tonic-gate 
6524a16f9a6SMilan Jurik #ifdef _SOLARIS_SDK
6534a16f9a6SMilan Jurik     /* Error from NSS_Initialize() more important! */
6544a16f9a6SMilan Jurik     if ((rcenv != 1) && (reset_nss_strict_fork_env(enval) != 0) && (rc == 0)) {
6554a16f9a6SMilan Jurik 	ldapssl_free(&enval);
6564a16f9a6SMilan Jurik 	mutex_unlock(&inited_mutex);
6574a16f9a6SMilan Jurik 	return (-1);
6584a16f9a6SMilan Jurik     }
6594a16f9a6SMilan Jurik     ldapssl_free(&enval);
6604a16f9a6SMilan Jurik #endif
6614a16f9a6SMilan Jurik 
6627c478bd9Sstevel@tonic-gate     if (rc != 0) {
6637c478bd9Sstevel@tonic-gate 	if ((rc = PR_GetError()) >= 0)
6647c478bd9Sstevel@tonic-gate 	    rc = -1;
6657c478bd9Sstevel@tonic-gate 	mutex_unlock(&inited_mutex);
6667c478bd9Sstevel@tonic-gate 	return (rc);
6677c478bd9Sstevel@tonic-gate     }
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate 
6707c478bd9Sstevel@tonic-gate #if 0	/* UNNEEDED BY LIBLDAP */
6717c478bd9Sstevel@tonic-gate     /* this is odd */
6727c478bd9Sstevel@tonic-gate     PK11_ConfigurePKCS11(NULL, NULL, tokDes, ptokDes, NULL, NULL, NULL, NULL, 0, 0 );
6737c478bd9Sstevel@tonic-gate #endif	/* UNNEEDED BY LIBLDAP */
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate     if (SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_FALSE)
6767c478bd9Sstevel@tonic-gate 	|| SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE)) {
6777c478bd9Sstevel@tonic-gate 	if (( rc = PR_GetError()) >= 0 ) {
6787c478bd9Sstevel@tonic-gate 	    rc = -1;
6797c478bd9Sstevel@tonic-gate 	}
6807c478bd9Sstevel@tonic-gate 
6817c478bd9Sstevel@tonic-gate 	mutex_unlock(&inited_mutex);
6827c478bd9Sstevel@tonic-gate 	return( rc );
6837c478bd9Sstevel@tonic-gate     }
6847c478bd9Sstevel@tonic-gate 
6857c478bd9Sstevel@tonic-gate     if (local_SSLPLCY_Install() == PR_FAILURE) {
6867c478bd9Sstevel@tonic-gate       mutex_unlock(&inited_mutex);
6877c478bd9Sstevel@tonic-gate       return( -1 );
6887c478bd9Sstevel@tonic-gate     }
6897c478bd9Sstevel@tonic-gate 
6907c478bd9Sstevel@tonic-gate     inited = 1;
6917c478bd9Sstevel@tonic-gate 
6927c478bd9Sstevel@tonic-gate     if ( certdbName != NULL ) {
6937c478bd9Sstevel@tonic-gate 	ldapssl_free((void **) &certdbName );
6947c478bd9Sstevel@tonic-gate     }
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate     return( ldapssl_set_strength( NULL, LDAPSSL_AUTH_CNCHECK));
6977c478bd9Sstevel@tonic-gate }
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate 
7007c478bd9Sstevel@tonic-gate /*
7017c478bd9Sstevel@tonic-gate  * ldapssl_client_init() is a server-authentication only version of
7027c478bd9Sstevel@tonic-gate  * ldapssl_clientauth_init().
7037c478bd9Sstevel@tonic-gate  */
7047c478bd9Sstevel@tonic-gate int
7057c478bd9Sstevel@tonic-gate LDAP_CALL
7067c478bd9Sstevel@tonic-gate ldapssl_client_init(const char* certdbpath, void *certdbhandle )
7077c478bd9Sstevel@tonic-gate {
7087c478bd9Sstevel@tonic-gate     return( ldapssl_clientauth_init( certdbpath, certdbhandle,
7097c478bd9Sstevel@tonic-gate 	    0, NULL, NULL ));
7107c478bd9Sstevel@tonic-gate }
7117c478bd9Sstevel@tonic-gate /*
7127c478bd9Sstevel@tonic-gate  * ldapssl_serverauth_init() is a server-authentication only version of
7137c478bd9Sstevel@tonic-gate  * ldapssl_clientauth_init().  This function allows the sslstrength
7147c478bd9Sstevel@tonic-gate  * to be passed in.  The sslstrength can take one of the following
7157c478bd9Sstevel@tonic-gate  * values:
7167c478bd9Sstevel@tonic-gate  *      LDAPSSL_AUTH_WEAK: indicate that you accept the server's
7177c478bd9Sstevel@tonic-gate  *                         certificate without checking the CA who
7187c478bd9Sstevel@tonic-gate  *                         issued the certificate
7197c478bd9Sstevel@tonic-gate  *      LDAPSSL_AUTH_CERT: indicates that you accept the server's
7207c478bd9Sstevel@tonic-gate  *                         certificate only if you trust the CA who
7217c478bd9Sstevel@tonic-gate  *                         issued the certificate
7227c478bd9Sstevel@tonic-gate  *      LDAPSSL_AUTH_CNCHECK:
7237c478bd9Sstevel@tonic-gate                            indicates that you accept the server's
7247c478bd9Sstevel@tonic-gate  *                         certificate only if you trust the CA who
7257c478bd9Sstevel@tonic-gate  *                         issued the certificate and if the value
7267c478bd9Sstevel@tonic-gate  *                         of the cn attribute in the DNS hostname
7277c478bd9Sstevel@tonic-gate  *                         of the server
7287c478bd9Sstevel@tonic-gate  */
7297c478bd9Sstevel@tonic-gate int
7307c478bd9Sstevel@tonic-gate LDAP_CALL
7317c478bd9Sstevel@tonic-gate ldapssl_serverauth_init(const char* certdbpath,
7327c478bd9Sstevel@tonic-gate                      void *certdbhandle,
7337c478bd9Sstevel@tonic-gate                      const int sslstrength )
7347c478bd9Sstevel@tonic-gate {
7357c478bd9Sstevel@tonic-gate     if ( ldapssl_set_strength( NULL, sslstrength ) != 0) {
7367c478bd9Sstevel@tonic-gate         return ( -1 );
7377c478bd9Sstevel@tonic-gate     }
7387c478bd9Sstevel@tonic-gate 
7397c478bd9Sstevel@tonic-gate     return( ldapssl_clientauth_init( certdbpath, certdbhandle,
7407c478bd9Sstevel@tonic-gate             0, NULL, NULL ));
7417c478bd9Sstevel@tonic-gate }
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate /*
7447c478bd9Sstevel@tonic-gate  * Function that makes an asynchronous Start TLS extended operation request.
7457c478bd9Sstevel@tonic-gate  */
7467c478bd9Sstevel@tonic-gate static int ldapssl_tls_start(LDAP *ld, int *msgidp)
7477c478bd9Sstevel@tonic-gate {
7487c478bd9Sstevel@tonic-gate     int version, rc;
7497c478bd9Sstevel@tonic-gate     BerValue extreq_data;
7507c478bd9Sstevel@tonic-gate 
7517c478bd9Sstevel@tonic-gate     /* Start TLS extended operation requires an absent "requestValue" field. */
7527c478bd9Sstevel@tonic-gate 
7537c478bd9Sstevel@tonic-gate     extreq_data.bv_val = NULL;
7547c478bd9Sstevel@tonic-gate     extreq_data.bv_len = 0;
7557c478bd9Sstevel@tonic-gate 
7567c478bd9Sstevel@tonic-gate     /* Make sure version is set to LDAPv3 for extended operations to be
7577c478bd9Sstevel@tonic-gate        supported. */
7587c478bd9Sstevel@tonic-gate 
7597c478bd9Sstevel@tonic-gate     version = LDAP_VERSION3;
7607c478bd9Sstevel@tonic-gate     ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate     /* Send the Start TLS request (OID: 1.3.6.1.4.1.1466.20037) */
7637c478bd9Sstevel@tonic-gate     rc = ldap_extended_operation( ld, START_TLS_OID, &extreq_data,
7647c478bd9Sstevel@tonic-gate               NULL, NULL, msgidp );
7657c478bd9Sstevel@tonic-gate 
7667c478bd9Sstevel@tonic-gate     return rc;
7677c478bd9Sstevel@tonic-gate }
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate 
7707c478bd9Sstevel@tonic-gate /*
7717c478bd9Sstevel@tonic-gate  * Function that enables SSL on an already open non-secured LDAP connection.
7727c478bd9Sstevel@tonic-gate  * (i.e. the connection is henceforth secured)
7737c478bd9Sstevel@tonic-gate  */
7747c478bd9Sstevel@tonic-gate static int ldapssl_enableSSL_on_open_connection(LDAP *ld, int defsecure,
7757c478bd9Sstevel@tonic-gate 	char *certdbpath, char *keydbpath)
7767c478bd9Sstevel@tonic-gate {
7777c478bd9Sstevel@tonic-gate     PRLDAPSocketInfo  soi;
7787c478bd9Sstevel@tonic-gate 
7797c478bd9Sstevel@tonic-gate 
7807c478bd9Sstevel@tonic-gate     if ( ldapssl_clientauth_init( certdbpath, NULL, 1, keydbpath, NULL ) < 0 ) {
7817c478bd9Sstevel@tonic-gate 	goto ssl_setup_failure;
7827c478bd9Sstevel@tonic-gate     }
7837c478bd9Sstevel@tonic-gate 
7847c478bd9Sstevel@tonic-gate     /*
7857c478bd9Sstevel@tonic-gate      * Retrieve socket info. so we have the PRFileDesc.
7867c478bd9Sstevel@tonic-gate      */
7877c478bd9Sstevel@tonic-gate     memset( &soi, 0, sizeof(soi));
7887c478bd9Sstevel@tonic-gate     soi.soinfo_size = PRLDAP_SOCKETINFO_SIZE;
7897c478bd9Sstevel@tonic-gate     if ( prldap_get_default_socket_info( ld, &soi ) < 0 ) {
7907c478bd9Sstevel@tonic-gate         goto ssl_setup_failure;
7917c478bd9Sstevel@tonic-gate     }
7927c478bd9Sstevel@tonic-gate 
7937c478bd9Sstevel@tonic-gate     if ( ldapssl_install_routines( ld ) < 0 ) {
7947c478bd9Sstevel@tonic-gate         goto ssl_setup_failure;
7957c478bd9Sstevel@tonic-gate     }
7967c478bd9Sstevel@tonic-gate 
7977c478bd9Sstevel@tonic-gate 
7987c478bd9Sstevel@tonic-gate     if (soi.soinfo_prfd == NULL) {
7997c478bd9Sstevel@tonic-gate         int sd;
8007c478bd9Sstevel@tonic-gate         ldap_get_option( ld, LDAP_OPT_DESC, &sd );
8017c478bd9Sstevel@tonic-gate         soi.soinfo_prfd = (PRFileDesc *) PR_ImportTCPSocket( sd );
8027c478bd9Sstevel@tonic-gate     }
8037c478bd9Sstevel@tonic-gate     /* set the socket information back into the connection handle,
8047c478bd9Sstevel@tonic-gate      * because ldapssl_install_routines() resets the socket_arg info in the
8057c478bd9Sstevel@tonic-gate      * socket buffer. */
8067c478bd9Sstevel@tonic-gate     if ( prldap_set_default_socket_info( ld, &soi ) != LDAP_SUCCESS ) {
8077c478bd9Sstevel@tonic-gate       goto ssl_setup_failure;
8087c478bd9Sstevel@tonic-gate     }
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate     if ( ldap_set_option( ld, LDAP_OPT_SSL,
8117c478bd9Sstevel@tonic-gate 	defsecure ? LDAP_OPT_ON : LDAP_OPT_OFF ) < 0 ) {
8127c478bd9Sstevel@tonic-gate         goto ssl_setup_failure;
8137c478bd9Sstevel@tonic-gate     }
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate     if ( ldapssl_import_fd( ld, defsecure ) < 0 ) {
8167c478bd9Sstevel@tonic-gate         goto ssl_setup_failure;
8177c478bd9Sstevel@tonic-gate     }
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate     return 0;
8207c478bd9Sstevel@tonic-gate 
8217c478bd9Sstevel@tonic-gate ssl_setup_failure:
8227c478bd9Sstevel@tonic-gate     ldapssl_reset_to_nonsecure( ld );
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate     /* we should here warn the server that we switch back to a non-secure
8257c478bd9Sstevel@tonic-gate        connection */
8267c478bd9Sstevel@tonic-gate 
8277c478bd9Sstevel@tonic-gate     return( -1 );
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate 
8307c478bd9Sstevel@tonic-gate 
8317c478bd9Sstevel@tonic-gate /*
8327c478bd9Sstevel@tonic-gate  * ldapssl_tls_start_s() performs a synchronous Start TLS extended operation
8337c478bd9Sstevel@tonic-gate  * request.
8347c478bd9Sstevel@tonic-gate  *
8357c478bd9Sstevel@tonic-gate  * The function returns the result code of the extended operation response
8367c478bd9Sstevel@tonic-gate  * sent by the server.
8377c478bd9Sstevel@tonic-gate  *
8387c478bd9Sstevel@tonic-gate  * In case of a successfull response (LDAP_SUCCESS returned), by the time
8397c478bd9Sstevel@tonic-gate  * this function returns the LDAP session designed by ld will have been
8407c478bd9Sstevel@tonic-gate  * secured, i.e. the connection will have been imported into SSL.
8417c478bd9Sstevel@tonic-gate  *
8427c478bd9Sstevel@tonic-gate  * Should the Start TLS request be rejected by the server, the result code
8437c478bd9Sstevel@tonic-gate  * returned will be one of the following:
8447c478bd9Sstevel@tonic-gate  *    LDAP_OPERATIONS_ERROR,
8457c478bd9Sstevel@tonic-gate  *    LDAP_PROTOCOL_ERROR,
8467c478bd9Sstevel@tonic-gate  *    LDAP_REFERRAL,
8477c478bd9Sstevel@tonic-gate  *    LDAP_UNAVAILABLE.
8487c478bd9Sstevel@tonic-gate  *
8497c478bd9Sstevel@tonic-gate  * Any other error code returned will be due to a failure in the course
8507c478bd9Sstevel@tonic-gate  * of operations done on the client side.
8517c478bd9Sstevel@tonic-gate  *
8527c478bd9Sstevel@tonic-gate  * "certdbpath" and "keydbpath" should contain the path to the client's
8537c478bd9Sstevel@tonic-gate  * certificate and key databases respectively. Either the path to the
8547c478bd9Sstevel@tonic-gate  * directory containing "default name" databases (i.e. cert7.db and key3.db)
8557c478bd9Sstevel@tonic-gate  * can be specified or the actual filenames can be included.
8567c478bd9Sstevel@tonic-gate  * If any of these parameters is NULL, the function will assume the database
8577c478bd9Sstevel@tonic-gate  * is the same used by Netscape Communicator, which is usually under
8587c478bd9Sstevel@tonic-gate  * ~/.netsca /)
8597c478bd9Sstevel@tonic-gate  *
8607c478bd9Sstevel@tonic-gate  * "referralsp" is a pointer to a list of referrals the server might
8617c478bd9Sstevel@tonic-gate  * eventually send back with an LDAP_REFERRAL result code.
8627c478bd9Sstevel@tonic-gate  *
8637c478bd9Sstevel@tonic-gate  */
8647c478bd9Sstevel@tonic-gate 
8657c478bd9Sstevel@tonic-gate int
8667c478bd9Sstevel@tonic-gate LDAP_CALL
8677c478bd9Sstevel@tonic-gate ldapssl_tls_start_s(LDAP *ld,int defsecure, char *certdbpath, char *keydbpath,
8687c478bd9Sstevel@tonic-gate 	char ***referralsp)
8697c478bd9Sstevel@tonic-gate {
8707c478bd9Sstevel@tonic-gate     int             rc, resultCode, msgid;
8717c478bd9Sstevel@tonic-gate     char            *extresp_oid;
8727c478bd9Sstevel@tonic-gate     BerValue        *extresp_data;
8737c478bd9Sstevel@tonic-gate     LDAPMessage     *res;
8747c478bd9Sstevel@tonic-gate 
8757c478bd9Sstevel@tonic-gate     rc = ldapssl_tls_start( ld, &msgid );
8767c478bd9Sstevel@tonic-gate     if ( rc != LDAP_SUCCESS ) {
8777c478bd9Sstevel@tonic-gate          return rc;
8787c478bd9Sstevel@tonic-gate     }
8797c478bd9Sstevel@tonic-gate 
8807c478bd9Sstevel@tonic-gate     rc = ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res );
8817c478bd9Sstevel@tonic-gate     if ( rc != LDAP_RES_EXTENDED ) {
8827c478bd9Sstevel@tonic-gate 
8837c478bd9Sstevel@tonic-gate       /* the first response received must be an extended response to an
8847c478bd9Sstevel@tonic-gate        Start TLS request */
8857c478bd9Sstevel@tonic-gate 
8867c478bd9Sstevel@tonic-gate          ldap_msgfree( res );
8877c478bd9Sstevel@tonic-gate          return( -1 );
8887c478bd9Sstevel@tonic-gate 
8897c478bd9Sstevel@tonic-gate     }
8907c478bd9Sstevel@tonic-gate 
8917c478bd9Sstevel@tonic-gate     rc = ldap_parse_extended_result( ld, res, &extresp_oid, &extresp_data, 0 );
8927c478bd9Sstevel@tonic-gate 
8937c478bd9Sstevel@tonic-gate     if ( rc != LDAP_SUCCESS ) {
8947c478bd9Sstevel@tonic-gate          ldap_msgfree( res );
8957c478bd9Sstevel@tonic-gate          return rc;
8967c478bd9Sstevel@tonic-gate     }
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate     if ( strcasecmp( extresp_oid, START_TLS_OID ) != 0 ) {
8997c478bd9Sstevel@tonic-gate 
9007c478bd9Sstevel@tonic-gate          /* the extended response received doesn't correspond to the
9017c478bd9Sstevel@tonic-gate           Start TLS request */
9027c478bd9Sstevel@tonic-gate 
9037c478bd9Sstevel@tonic-gate          ldap_msgfree( res );
9047c478bd9Sstevel@tonic-gate          return -1;
9057c478bd9Sstevel@tonic-gate     }
9067c478bd9Sstevel@tonic-gate 
9077c478bd9Sstevel@tonic-gate     resultCode = ldap_get_lderrno( ld, NULL, NULL );
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate     /* Analyze the server's response */
9107c478bd9Sstevel@tonic-gate     switch (resultCode) {
9117c478bd9Sstevel@tonic-gate     case LDAP_REFERRAL:
9127c478bd9Sstevel@tonic-gate       {
9137c478bd9Sstevel@tonic-gate       rc = ldap_parse_result( ld, res, NULL, NULL, NULL, referralsp, NULL, 0 );
9147c478bd9Sstevel@tonic-gate       if ( rc != LDAP_SUCCESS ) {
9157c478bd9Sstevel@tonic-gate           ldap_msgfree( res );
9167c478bd9Sstevel@tonic-gate           return rc;
9177c478bd9Sstevel@tonic-gate       }
9187c478bd9Sstevel@tonic-gate     }
9197c478bd9Sstevel@tonic-gate     case LDAP_OPERATIONS_ERROR:
9207c478bd9Sstevel@tonic-gate 
9217c478bd9Sstevel@tonic-gate     case LDAP_PROTOCOL_ERROR:
9227c478bd9Sstevel@tonic-gate 
9237c478bd9Sstevel@tonic-gate     case LDAP_UNAVAILABLE:
9247c478bd9Sstevel@tonic-gate         goto free_msg_and_return;
9257c478bd9Sstevel@tonic-gate     case LDAP_SUCCESS:
9267c478bd9Sstevel@tonic-gate       {
9277c478bd9Sstevel@tonic-gate       /*
9287c478bd9Sstevel@tonic-gate        * If extended response successfull, get connection ready for
9297c478bd9Sstevel@tonic-gate        * communicating with the server over SSL/TLS.
9307c478bd9Sstevel@tonic-gate        */
9317c478bd9Sstevel@tonic-gate 
9327c478bd9Sstevel@tonic-gate       if ( ldapssl_enableSSL_on_open_connection( ld, defsecure,
9337c478bd9Sstevel@tonic-gate                                          certdbpath, keydbpath ) < 0 ) {
9347c478bd9Sstevel@tonic-gate           resultCode = -1;
9357c478bd9Sstevel@tonic-gate       }
9367c478bd9Sstevel@tonic-gate 
9377c478bd9Sstevel@tonic-gate     } /* case LDAP_SUCCESS */
9387c478bd9Sstevel@tonic-gate     default:
9397c478bd9Sstevel@tonic-gate         goto free_msg_and_return;
9407c478bd9Sstevel@tonic-gate     } /* switch */
9417c478bd9Sstevel@tonic-gate 
9427c478bd9Sstevel@tonic-gate free_msg_and_return:
9437c478bd9Sstevel@tonic-gate     ldap_msgfree( res );
9447c478bd9Sstevel@tonic-gate     return resultCode;
9457c478bd9Sstevel@tonic-gate }
9467c478bd9Sstevel@tonic-gate 
9477c478bd9Sstevel@tonic-gate #endif /* NET_SSL */
948