Print this page
pass 2
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libldap5/sources/ldap/ssldap/clientinit.c
+++ new/usr/src/lib/libldap5/sources/ldap/ssldap/clientinit.c
1 1 /*
2 2 * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
3 3 */
4 4
5 5 /*
6 6 * The contents of this file are subject to the Netscape Public
7 7 * License Version 1.1 (the "License"); you may not use this file
8 8 * except in compliance with the License. You may obtain a copy of
9 9 * the License at http://www.mozilla.org/NPL/
10 10 *
11 11 * Software distributed under the License is distributed on an "AS
12 12 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
13 13 * implied. See the License for the specific language governing
14 14 * rights and limitations under the License.
15 15 *
16 16 * The Original Code is Mozilla Communicator client code, released
17 17 * March 31, 1998.
18 18 *
19 19 * The Initial Developer of the Original Code is Netscape
20 20 * Communications Corporation. Portions created by Netscape are
21 21 * Copyright (C) 1998-1999 Netscape Communications Corporation. All
22 22 * Rights Reserved.
23 23 *
24 24 * Contributor(s):
25 25 */
26 26
27 27 /*
28 28 * clientinit.c
29 29 */
30 30
31 31 #if defined(NET_SSL)
32 32
33 33
34 34 #if defined( _WINDOWS )
35 35 #include <windows.h>
36 36 #include "proto-ntutil.h"
37 37 #endif
38 38
39 39 #include <nspr.h>
40 40 #include <plstr.h>
41 41 #include <synch.h>
42 42 #include <cert.h>
43 43 #include <key.h>
44 44 #include <ssl.h>
45 45 #include <sslproto.h>
46 46 #include <ldap.h>
47 47 #include <ldappr.h>
48 48 #include <solaris-int.h>
49 49
50 50
51 51 #include <nss.h>
52 52
53 53 /* XXX:mhein The following is a workaround for the redefinition of */
54 54 /* const problem on OSF. Fix to be provided by NSS */
55 55 /* This is a pretty benign workaround for us which */
56 56 /* should not cause problems in the future even if */
57 57 /* we forget to take it out :-) */
58 58
59 59 #ifdef OSF1V4D
60 60 #ifndef __STDC__
61 61 # define __STDC__
62 62 #endif /* __STDC__ */
63 63 #endif /* OSF1V4D */
64 64
65 65 #ifndef FILE_PATHSEP
66 66 #define FILE_PATHSEP '/'
67 67 #endif
68 68
69 69 /*
70 70 * StartTls()
71 71 */
72 72
73 73 #define START_TLS_OID "1.3.6.1.4.1.1466.20037"
74 74
75 75 static PRStatus local_SSLPLCY_Install(void);
76 76
77 77 /*
78 78 * This little tricky guy keeps us from initializing twice
79 79 */
80 80 static int inited = 0;
81 81 #ifdef _SOLARIS_SDK
82 82 mutex_t inited_mutex = DEFAULTMUTEX;
83 83 #else
84 84 static mutex_t inited_mutex = DEFAULTMUTEX;
85 85 #endif /* _SOLARIS_SDK */
86 86 #if 0 /* UNNEEDED BY LIBLDAP */
87 87 static char tokDes[34] = "Internal (Software) Database ";
88 88 static char ptokDes[34] = "Internal (Software) Token ";
89 89 #endif /* UNNEEDED BY LIBLDAP */
90 90
91 91
92 92 /* IN: */
93 93 /* string: /u/mhein/.netscape/mykey3.db */
94 94 /* OUT: */
95 95 /* dir: /u/mhein/.netscape/ */
96 96 /* prefix: my */
97 97 /* key: key3.db */
98 98
99 99 static int
100 100 splitpath(char *string, char *dir, char *prefix, char *key) {
101 101 char *k;
102 102 char *s;
103 103 char *d = string;
104 104 char *l;
105 105 int len = 0;
106 106
107 107
108 108 if (string == NULL)
109 109 return (-1);
110 110
111 111 /* goto the end of the string, and walk backwards until */
112 112 /* you get to the first pathseparator */
113 113 len = PL_strlen(string);
114 114 l = string + len - 1;
115 115 while (l != string && *l != '/' && *l != '\\')
116 116 l--;
117 117 /* search for the .db */
118 118 if ((k = PL_strstr(l, ".db")) != NULL) {
119 119 /* now we are sitting on . of .db */
120 120
121 121 /* move backward to the first 'c' or 'k' */
122 122 /* indicating cert or key */
123 123 while (k != l && *k != 'c' && *k != 'k')
124 124 k--;
125 125
126 126 /* move backwards to the first path separator */
127 127 if (k != d && k > d)
128 128 s = k - 1;
129 129 while (s != d && *s != '/' && *s != '\\')
130 130 s--;
131 131
132 132 /* if we are sitting on top of a path */
133 133 /* separator there is no prefix */
134 134 if (s + 1 == k) {
135 135 /* we know there is no prefix */
136 136 prefix = '\0';
137 137 PL_strcpy(key, k);
138 138 *k = '\0';
139 139 PL_strcpy(dir, d);
140 140 } else {
141 141 /* grab the prefix */
142 142 PL_strcpy(key, k);
143 143 *k = '\0';
144 144 PL_strcpy(prefix, ++s);
145 145 *s = '\0';
146 146 PL_strcpy(dir, d);
147 147 }
148 148 } else {
↓ open down ↓ |
148 lines elided |
↑ open up ↑ |
149 149 /* neither *key[0-9].db nor *cert[0=9].db found */
150 150 return (-1);
151 151 }
152 152
153 153 return (0);
154 154 }
155 155
156 156
157 157 static PRStatus local_SSLPLCY_Install(void)
158 158 {
159 - SECStatus s;
160 -
161 -#ifdef NS_DOMESTIC
162 - s = NSS_SetDomesticPolicy();
163 -#elif NS_EXPORT
164 - s = NSS_SetExportPolicy();
165 -#else
166 - s = PR_FAILURE;
167 -#endif
168 - return s?PR_FAILURE:PR_SUCCESS;
159 + return NSS_SetDomesticPolicy() ? PR_FAILURE : PR_SUCCESS;
169 160 }
170 161
171 162
172 163
173 164 static void
174 165 ldapssl_basic_init( void )
175 166 {
176 167 #ifndef _SOLARIS_SDK
177 168 /*
178 169 * NSPR is initialized in .init on SOLARIS
179 170 */
180 171 /* PR_Init() must to be called before everything else... */
181 172 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
182 173 #endif
183 174
184 175 PR_SetConcurrency( 4 ); /* work around for NSPR 3.x I/O hangs */
185 176 }
186 177
187 178
188 179
189 180 /*
190 181 * Cover functions for malloc(), calloc(), strdup() and free() that are
191 182 * compatible with the NSS libraries (they seem to use the C runtime
192 183 * library malloc/free so these functions are quite simple right now).
193 184 */
194 185 static void *
195 186 ldapssl_malloc( size_t size )
196 187 {
197 188 void *p;
198 189
199 190 p = malloc( size );
200 191 return p;
201 192 }
202 193
203 194
204 195 static void *
205 196 ldapssl_calloc( int nelem, size_t elsize )
206 197 {
207 198 void *p;
208 199
209 200 p = calloc( nelem, elsize );
210 201 return p;
211 202 }
212 203
213 204
214 205 static char *
215 206 ldapssl_strdup( const char *s )
216 207 {
217 208 char *scopy;
218 209
219 210 if ( NULL == s ) {
220 211 scopy = NULL;
221 212 } else {
222 213 scopy = strdup( s );
223 214 }
224 215 return scopy;
225 216 }
226 217
227 218
228 219 static void
229 220 ldapssl_free( void **pp )
230 221 {
231 222 if ( NULL != pp && NULL != *pp ) {
232 223 free( (void *)*pp );
233 224 *pp = NULL;
234 225 }
235 226 }
236 227
237 228
238 229 #ifdef _SOLARIS_SDK
239 230 /*
240 231 * Disable strict fork detection of NSS library to allow safe fork of
241 232 * consumers. Otherwise NSS will not work after fork because it was not
242 233 * deinitialized before fork and there is no safe way how to do it after fork.
243 234 *
244 235 * Return values:
245 236 * 1 - DISABLED was already set, no modification to environment
246 237 * 0 - successfully modified environment, old value saved to enval if there
247 238 * was some
248 239 * -1 - setenv or strdup failed, the environment was left unchanged
249 240 *
250 241 */
251 242 static int
252 243 update_nss_strict_fork_env(char **enval)
253 244 {
254 245 char *temps = getenv("NSS_STRICT_NOFORK");
255 246 if (temps == NULL) {
256 247 *enval = NULL;
257 248 } else if (strncmp(temps, "DISABLED", 9) == 0) {
258 249 /* Do not need to set as DISABLED, it is already set. */
259 250 *enval = NULL;
260 251 return (1);
261 252 } else {
262 253 if ((*enval = ldapssl_strdup(temps)) == NULL)
263 254 return (-1);
264 255 }
265 256 return (setenv("NSS_STRICT_NOFORK", "DISABLED", 1));
266 257 }
267 258
268 259 /*
269 260 * Reset environment variable NSS_STRICT_NOFORK to value before
270 261 * update_nss_strict_fork_env() call or remove it from environment if it did
271 262 * not exist.
272 263 * NSS_STRICT_NOFORK=DISABLED is needed only during NSS initialization to
273 264 * disable activation of atfork handler in NSS which is invalidating
274 265 * initialization in child process after fork.
275 266 */
276 267 static int
277 268 reset_nss_strict_fork_env(char *enval)
278 269 {
279 270 if (enval != NULL) {
280 271 return (setenv("NSS_STRICT_NOFORK", enval, 1));
281 272 } else {
282 273 return (unsetenv("NSS_STRICT_NOFORK"));
283 274 }
284 275 }
285 276 #endif
286 277
287 278
288 279 static char *
289 280 buildDBName(const char *basename, const char *dbname)
290 281 {
291 282 char *result;
292 283 PRUint32 len, pathlen, addslash;
293 284
294 285 if (basename)
295 286 {
296 287 if (( len = PL_strlen( basename )) > 3
297 288 && PL_strcasecmp( ".db", basename + len - 3 ) == 0 ) {
298 289 return (ldapssl_strdup(basename));
299 290 }
300 291
301 292 pathlen = len;
302 293 len = pathlen + PL_strlen(dbname) + 1;
303 294 addslash = ( pathlen > 0 &&
304 295 (( *(basename + pathlen - 1) != FILE_PATHSEP ) ||
305 296 ( *(basename + pathlen - 1) != '\\' )));
306 297
307 298 if ( addslash ) {
308 299 ++len;
309 300 }
310 301 if (( result = ldapssl_malloc( len )) != NULL ) {
311 302 PL_strcpy( result, basename );
312 303 if ( addslash ) {
313 304 *(result+pathlen) = FILE_PATHSEP; /* replaces '\0' */
314 305 ++pathlen;
315 306 }
316 307 PL_strcpy(result+pathlen, dbname);
317 308 }
318 309
319 310 }
320 311
321 312
322 313 return result;
323 314 }
324 315
325 316 char *
326 317 GetCertDBName(void *alias, int dbVersion)
327 318 {
328 319 char *source;
329 320 char dbname[128];
330 321
331 322 source = (char *)alias;
332 323
333 324 if (!source)
334 325 {
335 326 source = "";
336 327 }
337 328
338 329 sprintf(dbname, "cert%d.db",dbVersion);
339 330 return(buildDBName(source, dbname));
340 331
341 332
342 333 }
343 334
344 335 /*
345 336 * return database name by appending "dbname" to "path".
346 337 * this code doesn't need to be terribly efficient (not called often).
347 338 */
348 339 /* XXXceb this is the old function. To be removed eventually */
349 340 static char *
350 341 GetDBName(const char *dbname, const char *path)
351 342 {
352 343 char *result;
353 344 PRUint32 len, pathlen;
354 345 int addslash;
355 346
356 347 if ( dbname == NULL ) {
357 348 dbname = "";
358 349 }
359 350
360 351 if ((path == NULL) || (*path == 0)) {
361 352 result = ldapssl_strdup(dbname);
362 353 } else {
363 354 pathlen = PL_strlen(path);
364 355 len = pathlen + PL_strlen(dbname) + 1;
365 356 addslash = ( path[pathlen - 1] != '/' );
366 357 if ( addslash ) {
367 358 ++len;
368 359 }
369 360 if (( result = ldapssl_malloc( len )) != NULL ) {
370 361 PL_strcpy( result, path );
371 362 if ( addslash ) {
372 363 *(result+pathlen) = '/'; /* replaces '\0' */
373 364 ++pathlen;
374 365 }
375 366 PL_strcpy(result+pathlen, dbname);
376 367 }
377 368 }
378 369
379 370 return result;
380 371 }
381 372
382 373 /*
383 374 * Initialize ns/security so it can be used for SSL client authentication.
384 375 * It is safe to call this more than once.
385 376 *
386 377 * If needkeydb == 0, no key database is opened and SSL server authentication
387 378 * is supported but not client authentication.
388 379 *
389 380 * If "certdbpath" is NULL or "", the default cert. db is used (typically
390 381 * ~/.netscape/cert7.db).
391 382 *
392 383 * If "certdbpath" ends with ".db" (case-insensitive compare), then
393 384 * it is assumed to be a full path to the cert. db file; otherwise,
394 385 * it is assumed to be a directory that contains a file called
395 386 * "cert7.db" or "cert.db".
396 387 *
397 388 * If certdbhandle is non-NULL, it is assumed to be a pointer to a
398 389 * SECCertDBHandle structure. It is fine to pass NULL since this
399 390 * routine will allocate one for you (CERT_GetDefaultDB() can be
400 391 * used to retrieve the cert db handle).
401 392 *
402 393 * If "keydbpath" is NULL or "", the default key db is used (typically
403 394 * ~/.netscape/key3.db).
404 395 *
405 396 * If "keydbpath" ends with ".db" (case-insensitive compare), then
406 397 * it is assumed to be a full path to the key db file; otherwise,
407 398 * it is assumed to be a directory that contains a file called
408 399 * "key3.db"
409 400 *
410 401 * If certdbhandle is non-NULL< it is assumed to be a pointed to a
411 402 * SECKEYKeyDBHandle structure. It is fine to pass NULL since this
412 403 * routine will allocate one for you (SECKEY_GetDefaultDB() can be
413 404 * used to retrieve the cert db handle).
414 405 */
415 406 int
416 407 LDAP_CALL
417 408 ldapssl_clientauth_init( const char *certdbpath, void *certdbhandle,
418 409 const int needkeydb, const char *keydbpath, void *keydbhandle )
419 410
420 411 {
421 412 int rc;
422 413 #ifdef _SOLARIS_SDK
423 414 char *enval;
424 415 int rcenv = 0;
425 416 #endif
426 417
427 418 /*
428 419 * LDAPDebug(LDAP_DEBUG_TRACE, "ldapssl_clientauth_init\n",0 ,0 ,0);
429 420 */
430 421
431 422 mutex_lock(&inited_mutex);
432 423 if ( inited ) {
433 424 mutex_unlock(&inited_mutex);
434 425 return( 0 );
435 426 }
436 427
437 428 ldapssl_basic_init();
438 429
439 430 #ifdef _SOLARIS_SDK
440 431 if ((rcenv = update_nss_strict_fork_env(&enval)) == -1) {
441 432 mutex_unlock(&inited_mutex);
442 433 return (-1);
443 434 }
444 435 #endif
445 436
446 437 /* Open the certificate database */
447 438 rc = NSS_Init(certdbpath);
448 439 #ifdef _SOLARIS_SDK
449 440 /* Error from NSS_Init() more important! */
450 441 if ((rcenv != 1) && (reset_nss_strict_fork_env(enval) != 0) && (rc == 0)) {
451 442 ldapssl_free(&enval);
452 443 mutex_unlock(&inited_mutex);
453 444 return (-1);
454 445 }
455 446 ldapssl_free(&enval);
456 447 #endif
457 448 if (rc != 0) {
458 449 if ((rc = PR_GetError()) >= 0)
459 450 rc = -1;
460 451 mutex_unlock(&inited_mutex);
461 452 return (rc);
462 453 }
463 454
464 455 if (SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_FALSE)
↓ open down ↓ |
286 lines elided |
↑ open up ↑ |
465 456 || SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE)) {
466 457 if (( rc = PR_GetError()) >= 0 ) {
467 458 rc = -1;
468 459 }
469 460 mutex_unlock(&inited_mutex);
470 461 return( rc );
471 462 }
472 463
473 464
474 465
475 -#if defined(NS_DOMESTIC)
476 466 if (local_SSLPLCY_Install() == PR_FAILURE) {
477 467 mutex_unlock(&inited_mutex);
478 468 return( -1 );
479 469 }
480 -#elif(NS_EXPORT)
481 - if (local_SSLPLCY_Install() == PR_FAILURE) {
482 - mutex_unlock(&inited_mutex);
483 - return( -1 );
484 - }
485 -#else
486 - mutex_unlock(&inited_mutex);
487 - return( -1 );
488 -#endif
489 470
490 471 inited = 1;
491 472 mutex_unlock(&inited_mutex);
492 473
493 474 return( 0 );
494 475
495 476 }
496 477
497 478 /*
498 479 * Initialize ns/security so it can be used for SSL client authentication.
499 480 * It is safe to call this more than once.
500 481 *
501 482 * If needkeydb == 0, no key database is opened and SSL server authentication
502 483 * is supported but not client authentication.
503 484 *
504 485 * If "certdbpath" is NULL or "", the default cert. db is used (typically
505 486 * ~/.netscape/cert7.db).
506 487 *
507 488 * If "certdbpath" ends with ".db" (case-insensitive compare), then
508 489 * it is assumed to be a full path to the cert. db file; otherwise,
509 490 * it is assumed to be a directory that contains a file called
510 491 * "cert7.db" or "cert.db".
511 492 *
512 493 * If certdbhandle is non-NULL, it is assumed to be a pointer to a
513 494 * SECCertDBHandle structure. It is fine to pass NULL since this
514 495 * routine will allocate one for you (CERT_GetDefaultDB() can be
515 496 * used to retrieve the cert db handle).
516 497 *
517 498 * If "keydbpath" is NULL or "", the default key db is used (typically
518 499 * ~/.netscape/key3.db).
519 500 *
520 501 * If "keydbpath" ends with ".db" (case-insensitive compare), then
521 502 * it is assumed to be a full path to the key db file; otherwise,
522 503 * it is assumed to be a directory that contains a file called
523 504 * "key3.db"
524 505 *
525 506 * If certdbhandle is non-NULL< it is assumed to be a pointed to a
526 507 * SECKEYKeyDBHandle structure. It is fine to pass NULL since this
527 508 * routine will allocate one for you (SECKEY_GetDefaultDB() can be
528 509 * used to retrieve the cert db handle). */
529 510 int
530 511 LDAP_CALL
531 512 ldapssl_advclientauth_init(
532 513 const char *certdbpath, void *certdbhandle,
533 514 const int needkeydb, const char *keydbpath, void *keydbhandle,
534 515 const int needsecmoddb, const char *secmoddbpath,
535 516 const int sslstrength )
536 517 {
537 518 int rc;
538 519 #ifdef _SOLARIS_SDK
539 520 char *enval;
540 521 int rcenv = 0;
541 522 #endif
542 523
543 524 mutex_lock(&inited_mutex);
544 525 if ( inited ) {
545 526 mutex_unlock(&inited_mutex);
546 527 return( 0 );
547 528 }
548 529
549 530 /*
550 531 * LDAPDebug(LDAP_DEBUG_TRACE, "ldapssl_advclientauth_init\n",0 ,0 ,0);
551 532 */
552 533
553 534 ldapssl_basic_init();
554 535
555 536 #ifdef _SOLARIS_SDK
556 537 if ((rcenv = update_nss_strict_fork_env(&enval)) == -1) {
557 538 mutex_unlock(&inited_mutex);
558 539 return (-1);
559 540 }
560 541 #endif
561 542
562 543 rc = NSS_Init(certdbpath);
563 544 #ifdef _SOLARIS_SDK
564 545 /* Error from NSS_Init() more important! */
565 546 if ((rcenv != 1) && (reset_nss_strict_fork_env(enval) != 0) && (rc == 0)) {
566 547 ldapssl_free(&enval);
567 548 mutex_unlock(&inited_mutex);
568 549 return (-1);
↓ open down ↓ |
70 lines elided |
↑ open up ↑ |
569 550 }
570 551 ldapssl_free(&enval);
571 552 #endif
572 553 if (rc != 0) {
573 554 if ((rc = PR_GetError()) >= 0)
574 555 rc = -1;
575 556 mutex_unlock(&inited_mutex);
576 557 return (rc);
577 558 }
578 559
579 -#if defined(NS_DOMESTIC)
580 560 if (local_SSLPLCY_Install() == PR_FAILURE) {
581 561 mutex_unlock(&inited_mutex);
582 562 return( -1 );
583 563 }
584 -#elif(NS_EXPORT)
585 - if (local_SSLPLCY_Install() == PR_FAILURE) {
586 - mutex_unlock(&inited_mutex);
587 - return( -1 );
588 - }
589 -#else
590 - mutex_unlock(&inited_mutex);
591 - return( -1 );
592 -#endif
593 564
594 565 inited = 1;
595 566 mutex_unlock(&inited_mutex);
596 567
597 568 return( ldapssl_set_strength( NULL, sslstrength));
598 569
599 570 }
600 571
601 572
602 573 /*
603 574 * Initialize ns/security so it can be used for SSL client authentication.
604 575 * It is safe to call this more than once.
605 576 */
606 577
607 578 /*
608 579 * XXXceb This is a hack until the new IO functions are done.
609 580 * this function lives in ldapsinit.c
610 581 */
611 582 void set_using_pkcs_functions( int val );
612 583
613 584 int
614 585 LDAP_CALL
615 586 ldapssl_pkcs_init( const struct ldapssl_pkcs_fns *pfns )
616 587 {
617 588
618 589 char *certdbName, *s, *keydbpath;
619 590 char *certdbPrefix, *keydbPrefix;
620 591 char *confDir, *keydbName;
621 592 static char *secmodname = "secmod.db";
622 593 int rc;
623 594 #ifdef _SOLARIS_SDK
624 595 char *enval;
625 596 int rcenv = 0;
626 597 #endif
627 598
628 599 mutex_lock(&inited_mutex);
629 600 if ( inited ) {
630 601 mutex_unlock(&inited_mutex);
631 602 return( 0 );
632 603 }
633 604 /*
634 605 * XXXceb This is a hack until the new IO functions are done.
635 606 * this function MUST be called before ldap_enable_clienauth.
636 607 *
637 608 */
638 609 set_using_pkcs_functions( 1 );
639 610
640 611 /*
641 612 * LDAPDebug(LDAP_DEBUG_TRACE, "ldapssl_pkcs_init\n",0 ,0 ,0);
642 613 */
643 614
644 615
645 616 ldapssl_basic_init();
646 617
647 618 pfns->pkcs_getcertpath( NULL, &s);
648 619 confDir = ldapssl_strdup( s );
649 620 certdbPrefix = ldapssl_strdup( s );
650 621 certdbName = ldapssl_strdup( s );
651 622 *certdbPrefix = 0;
652 623 splitpath(s, confDir, certdbPrefix, certdbName);
653 624
654 625 pfns->pkcs_getkeypath( NULL, &s);
655 626 keydbpath = ldapssl_strdup( s );
656 627 keydbPrefix = ldapssl_strdup( s );
657 628 keydbName = ldapssl_strdup( s );
658 629 *keydbPrefix = 0;
659 630 splitpath(s, keydbpath, keydbPrefix, keydbName);
660 631
661 632
662 633 /* verify confDir == keydbpath and adjust as necessary */
663 634 ldapssl_free((void **)&certdbName);
664 635 ldapssl_free((void **)&keydbName);
665 636 ldapssl_free((void **)&keydbpath);
666 637
667 638 #ifdef _SOLARIS_SDK
668 639 if ((rcenv = update_nss_strict_fork_env(&enval)) == -1) {
669 640 mutex_unlock(&inited_mutex);
670 641 return (-1);
671 642 }
672 643 #endif
673 644
674 645 rc = NSS_Initialize(confDir,certdbPrefix,keydbPrefix,secmodname,
675 646 NSS_INIT_READONLY);
676 647
677 648 ldapssl_free((void **)&certdbPrefix);
678 649 ldapssl_free((void **)&keydbPrefix);
679 650 ldapssl_free((void **)&confDir);
680 651
681 652 #ifdef _SOLARIS_SDK
682 653 /* Error from NSS_Initialize() more important! */
683 654 if ((rcenv != 1) && (reset_nss_strict_fork_env(enval) != 0) && (rc == 0)) {
684 655 ldapssl_free(&enval);
685 656 mutex_unlock(&inited_mutex);
686 657 return (-1);
687 658 }
688 659 ldapssl_free(&enval);
689 660 #endif
690 661
691 662 if (rc != 0) {
692 663 if ((rc = PR_GetError()) >= 0)
693 664 rc = -1;
694 665 mutex_unlock(&inited_mutex);
695 666 return (rc);
696 667 }
697 668
698 669
699 670 #if 0 /* UNNEEDED BY LIBLDAP */
700 671 /* this is odd */
701 672 PK11_ConfigurePKCS11(NULL, NULL, tokDes, ptokDes, NULL, NULL, NULL, NULL, 0, 0 );
702 673 #endif /* UNNEEDED BY LIBLDAP */
703 674
↓ open down ↓ |
101 lines elided |
↑ open up ↑ |
704 675 if (SSL_OptionSetDefault(SSL_ENABLE_SSL2, PR_FALSE)
705 676 || SSL_OptionSetDefault(SSL_ENABLE_SSL3, PR_TRUE)) {
706 677 if (( rc = PR_GetError()) >= 0 ) {
707 678 rc = -1;
708 679 }
709 680
710 681 mutex_unlock(&inited_mutex);
711 682 return( rc );
712 683 }
713 684
714 -#if defined(NS_DOMESTIC)
715 685 if (local_SSLPLCY_Install() == PR_FAILURE) {
716 686 mutex_unlock(&inited_mutex);
717 687 return( -1 );
718 688 }
719 -#elif(NS_EXPORT)
720 - if (local_SSLPLCY_Install() == PR_FAILURE) {
721 - mutex_unlock(&inited_mutex);
722 - return( -1 );
723 - }
724 -#else
725 - mutex_unlock(&inited_mutex);
726 - return( -1 );
727 -#endif
728 689
729 690 inited = 1;
730 691
731 692 if ( certdbName != NULL ) {
732 693 ldapssl_free((void **) &certdbName );
733 694 }
734 695
735 696 return( ldapssl_set_strength( NULL, LDAPSSL_AUTH_CNCHECK));
736 697 }
737 698
738 699
739 700 /*
740 701 * ldapssl_client_init() is a server-authentication only version of
741 702 * ldapssl_clientauth_init().
742 703 */
743 704 int
744 705 LDAP_CALL
745 706 ldapssl_client_init(const char* certdbpath, void *certdbhandle )
746 707 {
747 708 return( ldapssl_clientauth_init( certdbpath, certdbhandle,
748 709 0, NULL, NULL ));
749 710 }
750 711 /*
751 712 * ldapssl_serverauth_init() is a server-authentication only version of
752 713 * ldapssl_clientauth_init(). This function allows the sslstrength
753 714 * to be passed in. The sslstrength can take one of the following
754 715 * values:
755 716 * LDAPSSL_AUTH_WEAK: indicate that you accept the server's
756 717 * certificate without checking the CA who
757 718 * issued the certificate
758 719 * LDAPSSL_AUTH_CERT: indicates that you accept the server's
759 720 * certificate only if you trust the CA who
760 721 * issued the certificate
761 722 * LDAPSSL_AUTH_CNCHECK:
762 723 indicates that you accept the server's
763 724 * certificate only if you trust the CA who
764 725 * issued the certificate and if the value
765 726 * of the cn attribute in the DNS hostname
766 727 * of the server
767 728 */
768 729 int
769 730 LDAP_CALL
770 731 ldapssl_serverauth_init(const char* certdbpath,
771 732 void *certdbhandle,
772 733 const int sslstrength )
773 734 {
774 735 if ( ldapssl_set_strength( NULL, sslstrength ) != 0) {
775 736 return ( -1 );
776 737 }
777 738
778 739 return( ldapssl_clientauth_init( certdbpath, certdbhandle,
779 740 0, NULL, NULL ));
780 741 }
781 742
782 743 /*
783 744 * Function that makes an asynchronous Start TLS extended operation request.
784 745 */
785 746 static int ldapssl_tls_start(LDAP *ld, int *msgidp)
786 747 {
787 748 int version, rc;
788 749 BerValue extreq_data;
789 750
790 751 /* Start TLS extended operation requires an absent "requestValue" field. */
791 752
792 753 extreq_data.bv_val = NULL;
793 754 extreq_data.bv_len = 0;
794 755
795 756 /* Make sure version is set to LDAPv3 for extended operations to be
796 757 supported. */
797 758
798 759 version = LDAP_VERSION3;
799 760 ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
800 761
801 762 /* Send the Start TLS request (OID: 1.3.6.1.4.1.1466.20037) */
802 763 rc = ldap_extended_operation( ld, START_TLS_OID, &extreq_data,
803 764 NULL, NULL, msgidp );
804 765
805 766 return rc;
806 767 }
807 768
808 769
809 770 /*
810 771 * Function that enables SSL on an already open non-secured LDAP connection.
811 772 * (i.e. the connection is henceforth secured)
812 773 */
813 774 static int ldapssl_enableSSL_on_open_connection(LDAP *ld, int defsecure,
814 775 char *certdbpath, char *keydbpath)
815 776 {
816 777 PRLDAPSocketInfo soi;
817 778
818 779
819 780 if ( ldapssl_clientauth_init( certdbpath, NULL, 1, keydbpath, NULL ) < 0 ) {
820 781 goto ssl_setup_failure;
821 782 }
822 783
823 784 /*
824 785 * Retrieve socket info. so we have the PRFileDesc.
825 786 */
826 787 memset( &soi, 0, sizeof(soi));
827 788 soi.soinfo_size = PRLDAP_SOCKETINFO_SIZE;
828 789 if ( prldap_get_default_socket_info( ld, &soi ) < 0 ) {
829 790 goto ssl_setup_failure;
830 791 }
831 792
832 793 if ( ldapssl_install_routines( ld ) < 0 ) {
833 794 goto ssl_setup_failure;
834 795 }
835 796
836 797
837 798 if (soi.soinfo_prfd == NULL) {
838 799 int sd;
839 800 ldap_get_option( ld, LDAP_OPT_DESC, &sd );
840 801 soi.soinfo_prfd = (PRFileDesc *) PR_ImportTCPSocket( sd );
841 802 }
842 803 /* set the socket information back into the connection handle,
843 804 * because ldapssl_install_routines() resets the socket_arg info in the
844 805 * socket buffer. */
845 806 if ( prldap_set_default_socket_info( ld, &soi ) != LDAP_SUCCESS ) {
846 807 goto ssl_setup_failure;
847 808 }
848 809
849 810 if ( ldap_set_option( ld, LDAP_OPT_SSL,
850 811 defsecure ? LDAP_OPT_ON : LDAP_OPT_OFF ) < 0 ) {
851 812 goto ssl_setup_failure;
852 813 }
853 814
854 815 if ( ldapssl_import_fd( ld, defsecure ) < 0 ) {
855 816 goto ssl_setup_failure;
856 817 }
857 818
858 819 return 0;
859 820
860 821 ssl_setup_failure:
861 822 ldapssl_reset_to_nonsecure( ld );
862 823
863 824 /* we should here warn the server that we switch back to a non-secure
864 825 connection */
865 826
866 827 return( -1 );
867 828 }
868 829
869 830
870 831 /*
871 832 * ldapssl_tls_start_s() performs a synchronous Start TLS extended operation
872 833 * request.
873 834 *
874 835 * The function returns the result code of the extended operation response
875 836 * sent by the server.
876 837 *
877 838 * In case of a successfull response (LDAP_SUCCESS returned), by the time
878 839 * this function returns the LDAP session designed by ld will have been
879 840 * secured, i.e. the connection will have been imported into SSL.
880 841 *
881 842 * Should the Start TLS request be rejected by the server, the result code
882 843 * returned will be one of the following:
883 844 * LDAP_OPERATIONS_ERROR,
884 845 * LDAP_PROTOCOL_ERROR,
885 846 * LDAP_REFERRAL,
886 847 * LDAP_UNAVAILABLE.
887 848 *
888 849 * Any other error code returned will be due to a failure in the course
889 850 * of operations done on the client side.
890 851 *
891 852 * "certdbpath" and "keydbpath" should contain the path to the client's
892 853 * certificate and key databases respectively. Either the path to the
893 854 * directory containing "default name" databases (i.e. cert7.db and key3.db)
894 855 * can be specified or the actual filenames can be included.
895 856 * If any of these parameters is NULL, the function will assume the database
896 857 * is the same used by Netscape Communicator, which is usually under
897 858 * ~/.netsca /)
898 859 *
899 860 * "referralsp" is a pointer to a list of referrals the server might
900 861 * eventually send back with an LDAP_REFERRAL result code.
901 862 *
902 863 */
903 864
904 865 int
905 866 LDAP_CALL
906 867 ldapssl_tls_start_s(LDAP *ld,int defsecure, char *certdbpath, char *keydbpath,
907 868 char ***referralsp)
908 869 {
909 870 int rc, resultCode, msgid;
910 871 char *extresp_oid;
911 872 BerValue *extresp_data;
912 873 LDAPMessage *res;
913 874
914 875 rc = ldapssl_tls_start( ld, &msgid );
915 876 if ( rc != LDAP_SUCCESS ) {
916 877 return rc;
917 878 }
918 879
919 880 rc = ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res );
920 881 if ( rc != LDAP_RES_EXTENDED ) {
921 882
922 883 /* the first response received must be an extended response to an
923 884 Start TLS request */
924 885
925 886 ldap_msgfree( res );
926 887 return( -1 );
927 888
928 889 }
929 890
930 891 rc = ldap_parse_extended_result( ld, res, &extresp_oid, &extresp_data, 0 );
931 892
932 893 if ( rc != LDAP_SUCCESS ) {
933 894 ldap_msgfree( res );
934 895 return rc;
935 896 }
936 897
937 898 if ( strcasecmp( extresp_oid, START_TLS_OID ) != 0 ) {
938 899
939 900 /* the extended response received doesn't correspond to the
940 901 Start TLS request */
941 902
942 903 ldap_msgfree( res );
943 904 return -1;
944 905 }
945 906
946 907 resultCode = ldap_get_lderrno( ld, NULL, NULL );
947 908
948 909 /* Analyze the server's response */
949 910 switch (resultCode) {
950 911 case LDAP_REFERRAL:
951 912 {
952 913 rc = ldap_parse_result( ld, res, NULL, NULL, NULL, referralsp, NULL, 0 );
953 914 if ( rc != LDAP_SUCCESS ) {
954 915 ldap_msgfree( res );
955 916 return rc;
956 917 }
957 918 }
958 919 case LDAP_OPERATIONS_ERROR:
959 920
960 921 case LDAP_PROTOCOL_ERROR:
961 922
962 923 case LDAP_UNAVAILABLE:
963 924 goto free_msg_and_return;
964 925 case LDAP_SUCCESS:
965 926 {
966 927 /*
967 928 * If extended response successfull, get connection ready for
968 929 * communicating with the server over SSL/TLS.
969 930 */
970 931
971 932 if ( ldapssl_enableSSL_on_open_connection( ld, defsecure,
972 933 certdbpath, keydbpath ) < 0 ) {
973 934 resultCode = -1;
974 935 }
975 936
976 937 } /* case LDAP_SUCCESS */
977 938 default:
978 939 goto free_msg_and_return;
979 940 } /* switch */
980 941
981 942 free_msg_and_return:
982 943 ldap_msgfree( res );
983 944 return resultCode;
984 945 }
985 946
986 947 #endif /* NET_SSL */
↓ open down ↓ |
249 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX