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