]> git.sur5r.net Git - openldap/blob - libraries/libldap/tls.c
ITS#3755 silence strict-aliasing warnings
[openldap] / libraries / libldap / tls.c
1 /* tls.c - Handle tls/ssl using SSLeay or OpenSSL. */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 1998-2006 The OpenLDAP Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16
17 #include "portable.h"
18 #include "ldap_config.h"
19
20 #include <stdio.h>
21
22 #include <ac/stdlib.h>
23 #include <ac/errno.h>
24 #include <ac/socket.h>
25 #include <ac/string.h>
26 #include <ac/ctype.h>
27 #include <ac/time.h>
28 #include <ac/unistd.h>
29 #include <ac/param.h>
30 #include <ac/dirent.h>
31
32 #include "ldap-int.h"
33
34 #ifdef HAVE_TLS
35
36 #ifdef LDAP_R_COMPILE
37 #include <ldap_pvt_thread.h>
38 #endif
39
40 #ifdef HAVE_OPENSSL_SSL_H
41 #include <openssl/ssl.h>
42 #include <openssl/x509v3.h>
43 #include <openssl/err.h>
44 #include <openssl/rand.h>
45 #include <openssl/safestack.h>
46 #elif defined( HAVE_SSL_H )
47 #include <ssl.h>
48 #endif
49
50 static int  tls_opt_trace = 1;
51 static char *tls_opt_randfile = NULL;
52
53 #define HAS_TLS( sb )   ber_sockbuf_ctrl( sb, LBER_SB_OPT_HAS_IO, \
54                                 (void *)&sb_tls_sbio )
55
56 static void tls_report_error( void );
57
58 static void tls_info_cb( const SSL *ssl, int where, int ret );
59 static int tls_verify_cb( int ok, X509_STORE_CTX *ctx );
60 static int tls_verify_ok( int ok, X509_STORE_CTX *ctx );
61 static RSA * tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length );
62 static STACK_OF(X509_NAME) * get_ca_list( char * bundle, char * dir );
63
64 static DH * tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length );
65
66 typedef struct dhplist {
67         struct dhplist *next;
68         int keylength;
69         DH *param;
70 } dhplist;
71
72 static dhplist *dhparams;
73
74 static int tls_seed_PRNG( const char *randfile );
75
76 #ifdef LDAP_R_COMPILE
77 /*
78  * provide mutexes for the SSLeay library.
79  */
80 static ldap_pvt_thread_mutex_t  tls_mutexes[CRYPTO_NUM_LOCKS];
81
82 static void tls_locking_cb( int mode, int type, const char *file, int line )
83 {
84         if ( mode & CRYPTO_LOCK ) {
85                 ldap_pvt_thread_mutex_lock( &tls_mutexes[type] );
86         } else {
87                 ldap_pvt_thread_mutex_unlock( &tls_mutexes[type] );
88         }
89 }
90
91 /*
92  * an extra mutex for the default ctx.
93  */
94
95 static ldap_pvt_thread_mutex_t tls_def_ctx_mutex;
96 static ldap_pvt_thread_mutex_t tls_connect_mutex;
97
98 static void tls_init_threads( void )
99 {
100         int i;
101
102         for( i=0; i< CRYPTO_NUM_LOCKS ; i++ ) {
103                 ldap_pvt_thread_mutex_init( &tls_mutexes[i] );
104         }
105         CRYPTO_set_locking_callback( tls_locking_cb );
106         /* FIXME: the thread id should be added somehow... */
107
108         ldap_pvt_thread_mutex_init( &tls_def_ctx_mutex );
109         ldap_pvt_thread_mutex_init( &tls_connect_mutex );
110 }
111 #endif /* LDAP_R_COMPILE */
112
113 void
114 ldap_int_tls_destroy( struct ldapoptions *lo )
115 {
116         if ( lo->ldo_tls_ctx ) {
117                 SSL_CTX_free( lo->ldo_tls_ctx );
118                 lo->ldo_tls_ctx = NULL;
119         }
120
121         if ( lo->ldo_tls_certfile ) {
122                 LDAP_FREE( lo->ldo_tls_certfile );
123                 lo->ldo_tls_certfile = NULL;
124         }
125         if ( lo->ldo_tls_keyfile ) {
126                 LDAP_FREE( lo->ldo_tls_keyfile );
127                 lo->ldo_tls_keyfile = NULL;
128         }
129         if ( lo->ldo_tls_dhfile ) {
130                 LDAP_FREE( lo->ldo_tls_dhfile );
131                 lo->ldo_tls_dhfile = NULL;
132         }
133         if ( lo->ldo_tls_cacertfile ) {
134                 LDAP_FREE( lo->ldo_tls_cacertfile );
135                 lo->ldo_tls_cacertfile = NULL;
136         }
137         if ( lo->ldo_tls_cacertdir ) {
138                 LDAP_FREE( lo->ldo_tls_cacertdir );
139                 lo->ldo_tls_cacertdir = NULL;
140         }
141         if ( lo->ldo_tls_ciphersuite ) {
142                 LDAP_FREE( lo->ldo_tls_ciphersuite );
143                 lo->ldo_tls_ciphersuite = NULL;
144         }
145 }
146
147 /*
148  * Tear down the TLS subsystem. Should only be called once.
149  */
150 void
151 ldap_pvt_tls_destroy( void )
152 {
153         struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();   
154
155         ldap_int_tls_destroy( lo );
156
157         EVP_cleanup();
158         ERR_remove_state(0);
159         ERR_free_strings();
160
161         if ( tls_opt_randfile ) {
162                 LDAP_FREE( tls_opt_randfile );
163                 tls_opt_randfile = NULL;
164         }
165 }
166
167 /*
168  * Initialize TLS subsystem. Should be called only once.
169  */
170 int
171 ldap_pvt_tls_init( void )
172 {
173         static int tls_initialized = 0;
174
175         if ( tls_initialized++ ) return 0;
176
177 #ifdef HAVE_EBCDIC
178         {
179                 char *file = LDAP_STRDUP( tls_opt_randfile );
180                 if ( file ) __atoe( file );
181                 (void) tls_seed_PRNG( file );
182                 LDAP_FREE( file );
183         }
184 #else
185         (void) tls_seed_PRNG( tls_opt_randfile );
186 #endif
187
188 #ifdef LDAP_R_COMPILE
189         tls_init_threads();
190 #endif
191
192         SSL_load_error_strings();
193         SSLeay_add_ssl_algorithms();
194
195         /* FIXME: mod_ssl does this */
196         X509V3_add_standard_extensions();
197         return 0;
198 }
199
200 /*
201  * initialize a new TLS context
202  */
203 static int
204 ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server )
205 {
206         STACK_OF(X509_NAME) *calist;
207         int i, rc = 0;
208         char *ciphersuite = lo->ldo_tls_ciphersuite;
209         char *cacertfile = lo->ldo_tls_cacertfile;
210         char *cacertdir = lo->ldo_tls_cacertdir;
211         char *certfile = lo->ldo_tls_certfile;
212         char *keyfile = lo->ldo_tls_keyfile;
213         char *dhfile = lo->ldo_tls_dhfile;
214
215         if ( lo->ldo_tls_ctx )
216                 return 0;
217
218         ldap_pvt_tls_init();
219
220         if ( is_server && !certfile && !keyfile && !cacertfile && !cacertdir ) {
221                 /* minimum configuration not provided */
222                 return LDAP_NOT_SUPPORTED;
223         }
224
225 #ifdef HAVE_EBCDIC
226         /* This ASCII/EBCDIC handling is a real pain! */
227         if ( ciphersuite ) {
228                 ciphersuite = LDAP_STRDUP( ciphersuite );
229                 __atoe( ciphersuite );
230         }
231         if ( cacertfile ) {
232                 cacertfile = LDAP_STRDUP( cacertfile );
233                 __atoe( cacertfile );
234         }
235         if ( cacertdir ) {
236                 cacertdir = LDAP_STRDUP( cacertdir );
237                 __atoe( cacertdir );
238         }
239         if ( certfile ) {
240                 certfile = LDAP_STRDUP( certfile );
241                 __atoe( certfile );
242         }
243         if ( keyfile ) {
244                 keyfile = LDAP_STRDUP( keyfile );
245                 __atoe( keyfile );
246         }
247         if ( dhfile ) {
248                 dhfile = LDAP_STRDUP( dhfile );
249                 __atoe( dhfile );
250         }
251 #endif
252         lo->ldo_tls_ctx = SSL_CTX_new( SSLv23_method() );
253         if ( lo->ldo_tls_ctx == NULL ) {
254                 Debug( LDAP_DEBUG_ANY,
255                    "TLS: could not allocate default ctx (%lu).\n",
256                         ERR_peek_error(),0,0);
257                 rc = -1;
258                 goto error_exit;
259         }
260
261         if ( is_server ) {
262                 SSL_CTX_set_session_id_context( lo->ldo_tls_ctx,
263                         (const unsigned char *) "OpenLDAP", sizeof("OpenLDAP")-1 );
264         }
265
266         if ( lo->ldo_tls_ciphersuite &&
267                 !SSL_CTX_set_cipher_list( lo->ldo_tls_ctx, ciphersuite ) )
268         {
269                 Debug( LDAP_DEBUG_ANY,
270                            "TLS: could not set cipher list %s.\n",
271                            lo->ldo_tls_ciphersuite, 0, 0 );
272                 tls_report_error();
273                 rc = -1;
274                 goto error_exit;
275         }
276
277         if (lo->ldo_tls_cacertfile != NULL || lo->ldo_tls_cacertdir != NULL) {
278                 if ( !SSL_CTX_load_verify_locations( lo->ldo_tls_ctx,
279                                 cacertfile, cacertdir ) ||
280                         !SSL_CTX_set_default_verify_paths( lo->ldo_tls_ctx ) )
281                 {
282                         Debug( LDAP_DEBUG_ANY, "TLS: "
283                                 "could not load verify locations (file:`%s',dir:`%s').\n",
284                                 lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
285                                 lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "",
286                                 0 );
287                         tls_report_error();
288                         rc = -1;
289                         goto error_exit;
290                 }
291
292                 if ( is_server ) {
293                         /* List of CA names to send to a client */
294                         calist = get_ca_list( cacertfile, cacertdir );
295                         if ( !calist ) {
296                                 Debug( LDAP_DEBUG_ANY, "TLS: "
297                                         "could not load client CA list (file:`%s',dir:`%s').\n",
298                                         lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
299                                         lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "",
300                                         0 );
301                                 tls_report_error();
302                                 rc = -1;
303                                 goto error_exit;
304                         }
305
306                         SSL_CTX_set_client_CA_list( lo->ldo_tls_ctx, calist );
307                 }
308         }
309
310         if ( lo->ldo_tls_certfile &&
311                 !SSL_CTX_use_certificate_file( lo->ldo_tls_ctx,
312                         certfile, SSL_FILETYPE_PEM ) )
313         {
314                 Debug( LDAP_DEBUG_ANY,
315                         "TLS: could not use certificate `%s'.\n",
316                         lo->ldo_tls_certfile,0,0);
317                 tls_report_error();
318                 rc = -1;
319                 goto error_exit;
320         }
321
322         /* Key validity is checked automatically if cert has already been set */
323         if ( lo->ldo_tls_keyfile &&
324                 !SSL_CTX_use_PrivateKey_file( lo->ldo_tls_ctx,
325                         keyfile, SSL_FILETYPE_PEM ) )
326         {
327                 Debug( LDAP_DEBUG_ANY,
328                         "TLS: could not use key file `%s'.\n",
329                         lo->ldo_tls_keyfile,0,0);
330                 tls_report_error();
331                 rc = -1;
332                 goto error_exit;
333         }
334
335         if ( lo->ldo_tls_dhfile ) {
336                 DH *dh = NULL;
337                 BIO *bio;
338                 dhplist *p;
339
340                 if (( bio=BIO_new_file( dhfile,"r" )) == NULL ) {
341                         Debug( LDAP_DEBUG_ANY,
342                                 "TLS: could not use DH parameters file `%s'.\n",
343                                 lo->ldo_tls_dhfile,0,0);
344                         tls_report_error();
345                         rc = -1;
346                         goto error_exit;
347                 }
348                 while (( dh=PEM_read_bio_DHparams( bio, NULL, NULL, NULL ))) {
349                         p = LDAP_MALLOC( sizeof(dhplist) );
350                         if ( p != NULL ) {
351                                 p->keylength = DH_size( dh ) * 8;
352                                 p->param = dh;
353                                 p->next = dhparams;
354                                 dhparams = p;
355                         }
356                 }
357                 BIO_free( bio );
358         }
359
360         if ( tls_opt_trace ) {
361                 SSL_CTX_set_info_callback( (SSL_CTX *)lo->ldo_tls_ctx, tls_info_cb );
362         }
363
364         i = SSL_VERIFY_NONE;
365         if ( lo->ldo_tls_require_cert ) {
366                 i = SSL_VERIFY_PEER;
367                 if ( lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_DEMAND ||
368                          lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_HARD ) {
369                         i |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
370                 }
371         }
372
373         SSL_CTX_set_verify( lo->ldo_tls_ctx, i,
374                 lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_ALLOW ?
375                 tls_verify_ok : tls_verify_cb );
376         SSL_CTX_set_tmp_rsa_callback( lo->ldo_tls_ctx, tls_tmp_rsa_cb );
377         if ( lo->ldo_tls_dhfile ) {
378                 SSL_CTX_set_tmp_dh_callback( lo->ldo_tls_ctx, tls_tmp_dh_cb );
379         }
380 #ifdef HAVE_OPENSSL_CRL
381         if ( lo->ldo_tls_crlcheck ) {
382                 X509_STORE *x509_s = SSL_CTX_get_cert_store( lo->ldo_tls_ctx );
383                 if ( lo->ldo_tls_crlcheck == LDAP_OPT_X_TLS_CRL_PEER ) {
384                         X509_STORE_set_flags( x509_s, X509_V_FLAG_CRL_CHECK );
385                 } else if ( lo->ldo_tls_crlcheck == LDAP_OPT_X_TLS_CRL_ALL ) {
386                         X509_STORE_set_flags( x509_s, 
387                                         X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL  );
388                 }
389         }
390 #endif
391
392 error_exit:
393         if ( rc == -1 && lo->ldo_tls_ctx != NULL ) {
394                 SSL_CTX_free( lo->ldo_tls_ctx );
395                 lo->ldo_tls_ctx = NULL;
396         }
397 #ifdef HAVE_EBCDIC
398         LDAP_FREE( ciphersuite );
399         LDAP_FREE( cacertfile );
400         LDAP_FREE( cacertdir );
401         LDAP_FREE( certfile );
402         LDAP_FREE( keyfile );
403         LDAP_FREE( dhfile );
404 #endif
405         return rc;
406 }
407
408 /*
409  * initialize the default context
410  */
411 int
412 ldap_pvt_tls_init_def_ctx( int is_server )
413 {
414         struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();   
415         int rc;
416 #ifdef LDAP_R_COMPILE
417         ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
418 #endif
419         rc = ldap_int_tls_init_ctx( lo, is_server );
420 #ifdef LDAP_R_COMPILE
421         ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
422 #endif
423         return rc;
424 }
425
426 static STACK_OF(X509_NAME) *
427 get_ca_list( char * bundle, char * dir )
428 {
429         STACK_OF(X509_NAME) *ca_list = NULL;
430
431         if ( bundle ) {
432                 ca_list = SSL_load_client_CA_file( bundle );
433         }
434 #if defined(HAVE_DIRENT_H) || defined(dirent)
435         if ( dir ) {
436                 int freeit = 0;
437
438                 if ( !ca_list ) {
439                         ca_list = sk_X509_NAME_new_null();
440                         freeit = 1;
441                 }
442                 if ( !SSL_add_dir_cert_subjects_to_stack( ca_list, dir ) &&
443                         freeit ) {
444                         sk_X509_NAME_free( ca_list );
445                         ca_list = NULL;
446                 }
447         }
448 #endif
449         return ca_list;
450 }
451
452 static SSL *
453 alloc_handle( void *ctx_arg, int is_server )
454 {
455         SSL_CTX *ctx;
456         SSL     *ssl;
457
458         if ( ctx_arg ) {
459                 ctx = (SSL_CTX *) ctx_arg;
460         } else {
461                 struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();   
462                 if ( ldap_pvt_tls_init_def_ctx( is_server ) < 0 ) return NULL;
463                 ctx = lo->ldo_tls_ctx;
464         }
465
466         ssl = SSL_new( ctx );
467         if ( ssl == NULL ) {
468                 Debug( LDAP_DEBUG_ANY,"TLS: can't create ssl handle.\n",0,0,0);
469                 return NULL;
470         }
471         return ssl;
472 }
473
474 static int
475 update_flags( Sockbuf *sb, SSL * ssl, int rc )
476 {
477         int err = SSL_get_error(ssl, rc);
478
479         sb->sb_trans_needs_read  = 0;
480         sb->sb_trans_needs_write = 0;
481
482         if (err == SSL_ERROR_WANT_READ) {
483                 sb->sb_trans_needs_read  = 1;
484                 return 1;
485
486         } else if (err == SSL_ERROR_WANT_WRITE) {
487                 sb->sb_trans_needs_write = 1;
488                 return 1;
489
490         } else if (err == SSL_ERROR_WANT_CONNECT) {
491                 return 1;
492         }
493         return 0;
494 }
495
496 /*
497  * TLS support for LBER Sockbufs
498  */
499
500 struct tls_data {
501         SSL                     *ssl;
502         Sockbuf_IO_Desc         *sbiod;
503 };
504
505 static BIO_METHOD sb_tls_bio_method;
506
507 static int
508 sb_tls_setup( Sockbuf_IO_Desc *sbiod, void *arg )
509 {
510         struct tls_data         *p;
511         BIO                     *bio;
512
513         assert( sbiod != NULL );
514
515         p = LBER_MALLOC( sizeof( *p ) );
516         if ( p == NULL ) {
517                 return -1;
518         }
519         
520         p->ssl = (SSL *)arg;
521         p->sbiod = sbiod;
522         bio = BIO_new( &sb_tls_bio_method );
523         bio->ptr = (void *)p;
524         SSL_set_bio( p->ssl, bio, bio );
525         sbiod->sbiod_pvt = p;
526         return 0;
527 }
528
529 static int
530 sb_tls_remove( Sockbuf_IO_Desc *sbiod )
531 {
532         struct tls_data         *p;
533         
534         assert( sbiod != NULL );
535         assert( sbiod->sbiod_pvt != NULL );
536
537         p = (struct tls_data *)sbiod->sbiod_pvt;
538         SSL_free( p->ssl );
539         LBER_FREE( sbiod->sbiod_pvt );
540         sbiod->sbiod_pvt = NULL;
541         return 0;
542 }
543
544 static int
545 sb_tls_close( Sockbuf_IO_Desc *sbiod )
546 {
547         struct tls_data         *p;
548         
549         assert( sbiod != NULL );
550         assert( sbiod->sbiod_pvt != NULL );
551
552         p = (struct tls_data *)sbiod->sbiod_pvt;
553         SSL_shutdown( p->ssl );
554         return 0;
555 }
556
557 static int
558 sb_tls_ctrl( Sockbuf_IO_Desc *sbiod, int opt, void *arg )
559 {
560         struct tls_data         *p;
561         
562         assert( sbiod != NULL );
563         assert( sbiod->sbiod_pvt != NULL );
564
565         p = (struct tls_data *)sbiod->sbiod_pvt;
566         
567         if ( opt == LBER_SB_OPT_GET_SSL ) {
568                 *((SSL **)arg) = p->ssl;
569                 return 1;
570
571         } else if ( opt == LBER_SB_OPT_DATA_READY ) {
572                 if( SSL_pending( p->ssl ) > 0 ) {
573                         return 1;
574                 }
575         }
576         
577         return LBER_SBIOD_CTRL_NEXT( sbiod, opt, arg );
578 }
579
580 static ber_slen_t
581 sb_tls_read( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
582 {
583         struct tls_data         *p;
584         ber_slen_t              ret;
585         int                     err;
586
587         assert( sbiod != NULL );
588         assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
589
590         p = (struct tls_data *)sbiod->sbiod_pvt;
591
592         ret = SSL_read( p->ssl, (char *)buf, len );
593 #ifdef HAVE_WINSOCK
594         errno = WSAGetLastError();
595 #endif
596         err = SSL_get_error( p->ssl, ret );
597         if (err == SSL_ERROR_WANT_READ ) {
598                 sbiod->sbiod_sb->sb_trans_needs_read = 1;
599                 sock_errset(EWOULDBLOCK);
600         }
601         else
602                 sbiod->sbiod_sb->sb_trans_needs_read = 0;
603         return ret;
604 }
605
606 static ber_slen_t
607 sb_tls_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
608 {
609         struct tls_data         *p;
610         ber_slen_t              ret;
611         int                     err;
612
613         assert( sbiod != NULL );
614         assert( SOCKBUF_VALID( sbiod->sbiod_sb ) );
615
616         p = (struct tls_data *)sbiod->sbiod_pvt;
617
618         ret = SSL_write( p->ssl, (char *)buf, len );
619 #ifdef HAVE_WINSOCK
620         errno = WSAGetLastError();
621 #endif
622         err = SSL_get_error( p->ssl, ret );
623         if (err == SSL_ERROR_WANT_WRITE ) {
624                 sbiod->sbiod_sb->sb_trans_needs_write = 1;
625                 sock_errset(EWOULDBLOCK);
626
627         } else {
628                 sbiod->sbiod_sb->sb_trans_needs_write = 0;
629         }
630         return ret;
631 }
632
633 static Sockbuf_IO sb_tls_sbio =
634 {
635         sb_tls_setup,           /* sbi_setup */
636         sb_tls_remove,          /* sbi_remove */
637         sb_tls_ctrl,            /* sbi_ctrl */
638         sb_tls_read,            /* sbi_read */
639         sb_tls_write,           /* sbi_write */
640         sb_tls_close            /* sbi_close */
641 };
642
643 static int
644 sb_tls_bio_create( BIO *b ) {
645         b->init = 1;
646         b->num = 0;
647         b->ptr = NULL;
648         b->flags = 0;
649         return 1;
650 }
651
652 static int
653 sb_tls_bio_destroy( BIO *b )
654 {
655         if ( b == NULL ) return 0;
656
657         b->ptr = NULL;          /* sb_tls_remove() will free it */
658         b->init = 0;
659         b->flags = 0;
660         return 1;
661 }
662
663 static int
664 sb_tls_bio_read( BIO *b, char *buf, int len )
665 {
666         struct tls_data         *p;
667         int                     ret;
668                 
669         if ( buf == NULL || len <= 0 ) return 0;
670
671         p = (struct tls_data *)b->ptr;
672
673         if ( p == NULL || p->sbiod == NULL ) {
674                 return 0;
675         }
676
677         ret = LBER_SBIOD_READ_NEXT( p->sbiod, buf, len );
678
679         BIO_clear_retry_flags( b );
680         if ( ret < 0 ) {
681                 int err = sock_errno();
682                 if ( err == EAGAIN || err == EWOULDBLOCK ) {
683                         BIO_set_retry_read( b );
684                 }
685         }
686
687         return ret;
688 }
689
690 static int
691 sb_tls_bio_write( BIO *b, const char *buf, int len )
692 {
693         struct tls_data         *p;
694         int                     ret;
695         
696         if ( buf == NULL || len <= 0 ) return 0;
697         
698         p = (struct tls_data *)b->ptr;
699
700         if ( p == NULL || p->sbiod == NULL ) {
701                 return 0;
702         }
703
704         ret = LBER_SBIOD_WRITE_NEXT( p->sbiod, (char *)buf, len );
705
706         BIO_clear_retry_flags( b );
707         if ( ret < 0 ) {
708                 int err = sock_errno();
709                 if ( err == EAGAIN || err == EWOULDBLOCK ) {
710                         BIO_set_retry_write( b );
711                 }
712         }
713
714         return ret;
715 }
716
717 static long
718 sb_tls_bio_ctrl( BIO *b, int cmd, long num, void *ptr )
719 {
720         if ( cmd == BIO_CTRL_FLUSH ) {
721                 /* The OpenSSL library needs this */
722                 return 1;
723         }
724         return 0;
725 }
726
727 static int
728 sb_tls_bio_gets( BIO *b, char *buf, int len )
729 {
730         return -1;
731 }
732
733 static int
734 sb_tls_bio_puts( BIO *b, const char *str )
735 {
736         return sb_tls_bio_write( b, str, strlen( str ) );
737 }
738         
739 static BIO_METHOD sb_tls_bio_method =
740 {
741         ( 100 | 0x400 ),                /* it's a source/sink BIO */
742         "sockbuf glue",
743         sb_tls_bio_write,
744         sb_tls_bio_read,
745         sb_tls_bio_puts,
746         sb_tls_bio_gets,
747         sb_tls_bio_ctrl,
748         sb_tls_bio_create,
749         sb_tls_bio_destroy
750 };
751
752 /*
753  * Call this to do a TLS connect on a sockbuf. ctx_arg can be
754  * a SSL_CTX * or NULL, in which case the default ctx is used.
755  *
756  * Return value:
757  *
758  *  0 - Success. Connection is ready for communication.
759  * <0 - Error. Can't create a TLS stream.
760  * >0 - Partial success.
761  *        Do a select (using information from lber_pvt_sb_needs_{read,write}
762  *              and call again.
763  */
764
765 static int
766 ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
767 {
768         Sockbuf *sb = conn->lconn_sb;
769         int     err;
770         SSL     *ssl;
771
772         if ( HAS_TLS( sb ) ) {
773                 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
774
775         } else {
776                 struct ldapoptions *lo;
777                 SSL_CTX *ctx;
778
779                 ctx = ld->ld_options.ldo_tls_ctx;
780
781                 ssl = alloc_handle( ctx, 0 );
782
783                 if ( ssl == NULL ) return -1;
784
785 #ifdef LDAP_DEBUG
786                 ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
787                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
788 #endif
789                 ber_sockbuf_add_io( sb, &sb_tls_sbio,
790                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
791
792                 lo = LDAP_INT_GLOBAL_OPT();   
793                 if( ctx == NULL ) {
794                         ctx = lo->ldo_tls_ctx;
795                         ld->ld_options.ldo_tls_ctx = ctx;
796                         CRYPTO_add( &ctx->references, 1, CRYPTO_LOCK_SSL_CTX );
797                 }
798                 if ( ld->ld_options.ldo_tls_connect_cb )
799                         ld->ld_options.ldo_tls_connect_cb( ld, ssl, ctx,
800                         ld->ld_options.ldo_tls_connect_arg );
801                 if ( lo && lo->ldo_tls_connect_cb && lo->ldo_tls_connect_cb !=
802                         ld->ld_options.ldo_tls_connect_cb )
803                         lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg );
804         }
805
806         err = SSL_connect( ssl );
807
808 #ifdef HAVE_WINSOCK
809         errno = WSAGetLastError();
810 #endif
811
812         if ( err <= 0 ) {
813                 if ( update_flags( sb, ssl, err )) {
814                         return 1;
815                 }
816
817                 if ((err = ERR_peek_error())) {
818                         char buf[256];
819
820                         if ( ld->ld_error ) {
821                                 LDAP_FREE( ld->ld_error );
822                         }
823                         ld->ld_error = LDAP_STRDUP(ERR_error_string(err, buf));
824 #ifdef HAVE_EBCDIC
825                         if ( ld->ld_error ) __etoa(ld->ld_error);
826 #endif
827                 }
828
829                 Debug( LDAP_DEBUG_ANY,"TLS: can't connect: %s.\n",
830                         ld->ld_error ? ld->ld_error : "" ,0,0);
831
832                 ber_sockbuf_remove_io( sb, &sb_tls_sbio,
833                         LBER_SBIOD_LEVEL_TRANSPORT );
834 #ifdef LDAP_DEBUG
835                 ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
836                         LBER_SBIOD_LEVEL_TRANSPORT );
837 #endif
838                 return -1;
839         }
840
841         return 0;
842 }
843
844 /*
845  * Call this to do a TLS accept on a sockbuf.
846  * Everything else is the same as with tls_connect.
847  */
848 int
849 ldap_pvt_tls_accept( Sockbuf *sb, void *ctx_arg )
850 {
851         int     err;
852         SSL     *ssl;
853
854         if ( HAS_TLS( sb ) ) {
855                 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&ssl );
856
857         } else {
858                 ssl = alloc_handle( ctx_arg, 1 );
859                 if ( ssl == NULL ) return -1;
860
861 #ifdef LDAP_DEBUG
862                 ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug,
863                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)"tls_" );
864 #endif
865                 ber_sockbuf_add_io( sb, &sb_tls_sbio,
866                         LBER_SBIOD_LEVEL_TRANSPORT, (void *)ssl );
867         }
868
869 #ifdef LDAP_R_COMPILE
870         ldap_pvt_thread_mutex_lock( &tls_connect_mutex );
871 #endif
872         err = SSL_accept( ssl );
873 #ifdef LDAP_R_COMPILE
874         ldap_pvt_thread_mutex_unlock( &tls_connect_mutex );
875 #endif
876
877 #ifdef HAVE_WINSOCK
878         errno = WSAGetLastError();
879 #endif
880         if ( err <= 0 ) {
881                 if ( update_flags( sb, ssl, err )) return 1;
882
883                 Debug( LDAP_DEBUG_ANY,"TLS: can't accept.\n",0,0,0 );
884
885                 tls_report_error();
886                 ber_sockbuf_remove_io( sb, &sb_tls_sbio,
887                         LBER_SBIOD_LEVEL_TRANSPORT );
888 #ifdef LDAP_DEBUG
889                 ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
890                         LBER_SBIOD_LEVEL_TRANSPORT );
891 #endif
892                 return -1;
893         }
894
895         return 0;
896 }
897
898 int
899 ldap_pvt_tls_inplace ( Sockbuf *sb )
900 {
901         return HAS_TLS( sb ) ? 1 : 0;
902 }
903
904 int
905 ldap_tls_inplace( LDAP *ld )
906 {
907         Sockbuf         *sb = NULL;
908
909         if ( ld->ld_defconn && ld->ld_defconn->lconn_sb ) {
910                 sb = ld->ld_defconn->lconn_sb;
911
912         } else if ( ld->ld_sb ) {
913                 sb = ld->ld_sb;
914
915         } else {
916                 return 0;
917         }
918
919         return ldap_pvt_tls_inplace( sb );
920 }
921
922 static X509 *
923 tls_get_cert( SSL *s )
924 {
925         /* If peer cert was bad, treat as if no cert was given */
926         if (SSL_get_verify_result(s)) {
927                 /* If we can send an alert, do so */
928                 if (SSL_version(s) != SSL2_VERSION) {
929                         ssl3_send_alert(s,SSL3_AL_WARNING,SSL3_AD_BAD_CERTIFICATE);
930                 }
931                 return NULL;
932         }
933         return SSL_get_peer_certificate(s);
934 }
935
936 int
937 ldap_pvt_tls_get_peer_dn( void *s, struct berval *dn,
938         LDAPDN_rewrite_dummy *func, unsigned flags )
939 {
940         X509 *x;
941         X509_NAME *xn;
942         int rc;
943
944         x = tls_get_cert((SSL *)s);
945
946         if (!x) return LDAP_INVALID_CREDENTIALS;
947         
948         xn = X509_get_subject_name(x);
949         rc = ldap_X509dn2bv(xn, dn, (LDAPDN_rewrite_func *)func, flags);
950         X509_free(x);
951         return rc;
952 }
953
954 char *
955 ldap_pvt_tls_get_peer_hostname( void *s )
956 {
957         X509 *x;
958         X509_NAME *xn;
959         char buf[2048], *p;
960         int ret;
961
962         x = tls_get_cert((SSL *)s);
963         if (!x) return NULL;
964         
965         xn = X509_get_subject_name(x);
966
967         ret = X509_NAME_get_text_by_NID(xn, NID_commonName, buf, sizeof(buf));
968         if( ret == -1 ) {
969                 X509_free(x);
970                 return NULL;
971         }
972
973         p = LDAP_STRDUP(buf);
974         X509_free(x);
975         return p;
976 }
977
978 /* what kind of hostname were we given? */
979 #define IS_DNS  0
980 #define IS_IP4  1
981 #define IS_IP6  2
982
983 int
984 ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
985 {
986         int i, ret = LDAP_LOCAL_ERROR;
987         X509 *x;
988         const char *name;
989         char *ptr;
990         int ntype = IS_DNS;
991 #ifdef LDAP_PF_INET6
992         struct in6_addr addr;
993 #else
994         struct in_addr addr;
995 #endif
996
997         if( ldap_int_hostname &&
998                 ( !name_in || !strcasecmp( name_in, "localhost" ) ) )
999         {
1000                 name = ldap_int_hostname;
1001         } else {
1002                 name = name_in;
1003         }
1004
1005         x = tls_get_cert((SSL *)s);
1006         if (!x) {
1007                 Debug( LDAP_DEBUG_ANY,
1008                         "TLS: unable to get peer certificate.\n",
1009                         0, 0, 0 );
1010                 /* If this was a fatal condition, things would have
1011                  * aborted long before now.
1012                  */
1013                 return LDAP_SUCCESS;
1014         }
1015
1016 #ifdef LDAP_PF_INET6
1017         if (name[0] == '[' && strchr(name, ']')) {
1018                 char *n2 = ldap_strdup(name+1);
1019                 *strchr(n2, ']') = 2;
1020                 if (inet_pton(AF_INET6, n2, &addr))
1021                         ntype = IS_IP6;
1022                 LDAP_FREE(n2);
1023         } else 
1024 #endif
1025         if ((ptr = strrchr(name, '.')) && isdigit((unsigned char)ptr[1])) {
1026                 if (inet_aton(name, (struct in_addr *)&addr)) ntype = IS_IP4;
1027         }
1028         
1029         i = X509_get_ext_by_NID(x, NID_subject_alt_name, -1);
1030         if (i >= 0) {
1031                 X509_EXTENSION *ex;
1032                 STACK_OF(GENERAL_NAME) *alt;
1033
1034                 ex = X509_get_ext(x, i);
1035                 alt = X509V3_EXT_d2i(ex);
1036                 if (alt) {
1037                         int n, len1 = 0, len2 = 0;
1038                         char *domain = NULL;
1039                         GENERAL_NAME *gn;
1040
1041                         if (ntype == IS_DNS) {
1042                                 len1 = strlen(name);
1043                                 domain = strchr(name, '.');
1044                                 if (domain) {
1045                                         len2 = len1 - (domain-name);
1046                                 }
1047                         }
1048                         n = sk_GENERAL_NAME_num(alt);
1049                         for (i=0; i<n; i++) {
1050                                 char *sn;
1051                                 int sl;
1052                                 gn = sk_GENERAL_NAME_value(alt, i);
1053                                 if (gn->type == GEN_DNS) {
1054                                         if (ntype != IS_DNS) continue;
1055
1056                                         sn = (char *) ASN1_STRING_data(gn->d.ia5);
1057                                         sl = ASN1_STRING_length(gn->d.ia5);
1058
1059                                         /* ignore empty */
1060                                         if (sl == 0) continue;
1061
1062                                         /* Is this an exact match? */
1063                                         if ((len1 == sl) && !strncasecmp(name, sn, len1)) {
1064                                                 break;
1065                                         }
1066
1067                                         /* Is this a wildcard match? */
1068                                         if (domain && (sn[0] == '*') && (sn[1] == '.') &&
1069                                                 (len2 == sl-1) && !strncasecmp(domain, &sn[1], len2))
1070                                         {
1071                                                 break;
1072                                         }
1073
1074                                 } else if (gn->type == GEN_IPADD) {
1075                                         if (ntype == IS_DNS) continue;
1076
1077                                         sn = (char *) ASN1_STRING_data(gn->d.ia5);
1078                                         sl = ASN1_STRING_length(gn->d.ia5);
1079
1080 #ifdef LDAP_PF_INET6
1081                                         if (ntype == IS_IP6 && sl != sizeof(struct in6_addr)) {
1082                                                 continue;
1083                                         } else
1084 #endif
1085                                         if (ntype == IS_IP4 && sl != sizeof(struct in_addr)) {
1086                                                 continue;
1087                                         }
1088                                         if (!memcmp(sn, &addr, sl)) {
1089                                                 break;
1090                                         }
1091                                 }
1092                         }
1093
1094                         GENERAL_NAMES_free(alt);
1095                         if (i < n) {    /* Found a match */
1096                                 ret = LDAP_SUCCESS;
1097                         }
1098                 }
1099         }
1100
1101         if (ret != LDAP_SUCCESS) {
1102                 X509_NAME *xn;
1103                 char buf[2048];
1104                 buf[0] = '\0';
1105
1106                 xn = X509_get_subject_name(x);
1107                 if( X509_NAME_get_text_by_NID( xn, NID_commonName,
1108                         buf, sizeof(buf)) == -1)
1109                 {
1110                         Debug( LDAP_DEBUG_ANY,
1111                                 "TLS: unable to get common name from peer certificate.\n",
1112                                 0, 0, 0 );
1113                         ret = LDAP_CONNECT_ERROR;
1114                         if ( ld->ld_error ) {
1115                                 LDAP_FREE( ld->ld_error );
1116                         }
1117                         ld->ld_error = LDAP_STRDUP(
1118                                 _("TLS: unable to get CN from peer certificate"));
1119
1120                 } else if (strcasecmp(name, buf) == 0 ) {
1121                         ret = LDAP_SUCCESS;
1122
1123                 } else if (( buf[0] == '*' ) && ( buf[1] == '.' )) {
1124                         char *domain = strchr(name, '.');
1125                         if( domain ) {
1126                                 size_t dlen = 0;
1127                                 size_t sl;
1128
1129                                 sl = strlen(name);
1130                                 dlen = sl - (domain-name);
1131                                 sl = strlen(buf);
1132
1133                                 /* Is this a wildcard match? */
1134                                 if ((dlen == sl-1) && !strncasecmp(domain, &buf[1], dlen)) {
1135                                         ret = LDAP_SUCCESS;
1136                                 }
1137                         }
1138                 }
1139
1140                 if( ret == LDAP_LOCAL_ERROR ) {
1141                         Debug( LDAP_DEBUG_ANY, "TLS: hostname (%s) does not match "
1142                                 "common name in certificate (%s).\n", 
1143                                 name, buf, 0 );
1144                         ret = LDAP_CONNECT_ERROR;
1145                         if ( ld->ld_error ) {
1146                                 LDAP_FREE( ld->ld_error );
1147                         }
1148                         ld->ld_error = LDAP_STRDUP(
1149                                 _("TLS: hostname does not match CN in peer certificate"));
1150                 }
1151         }
1152         X509_free(x);
1153         return ret;
1154 }
1155
1156 const char *
1157 ldap_pvt_tls_get_peer_issuer( void *s )
1158 {
1159 #if 0   /* currently unused; see ldap_pvt_tls_get_peer_dn() if needed */
1160         X509 *x;
1161         X509_NAME *xn;
1162         char buf[2048], *p;
1163
1164         x = SSL_get_peer_certificate((SSL *)s);
1165
1166         if (!x) return NULL;
1167         
1168         xn = X509_get_issuer_name(x);
1169         p = LDAP_STRDUP(X509_NAME_oneline(xn, buf, sizeof(buf)));
1170         X509_free(x);
1171         return p;
1172 #else
1173         return NULL;
1174 #endif
1175 }
1176
1177 int
1178 ldap_int_tls_config( LDAP *ld, int option, const char *arg )
1179 {
1180         int i;
1181
1182         switch( option ) {
1183         case LDAP_OPT_X_TLS_CACERTFILE:
1184         case LDAP_OPT_X_TLS_CACERTDIR:
1185         case LDAP_OPT_X_TLS_CERTFILE:
1186         case LDAP_OPT_X_TLS_KEYFILE:
1187         case LDAP_OPT_X_TLS_RANDOM_FILE:
1188         case LDAP_OPT_X_TLS_CIPHER_SUITE:
1189         case LDAP_OPT_X_TLS_DHFILE:
1190                 return ldap_pvt_tls_set_option( ld, option, (void *) arg );
1191
1192         case LDAP_OPT_X_TLS_REQUIRE_CERT:
1193         case LDAP_OPT_X_TLS:
1194                 i = -1;
1195                 if ( strcasecmp( arg, "never" ) == 0 ) {
1196                         i = LDAP_OPT_X_TLS_NEVER ;
1197
1198                 } else if ( strcasecmp( arg, "demand" ) == 0 ) {
1199                         i = LDAP_OPT_X_TLS_DEMAND ;
1200
1201                 } else if ( strcasecmp( arg, "allow" ) == 0 ) {
1202                         i = LDAP_OPT_X_TLS_ALLOW ;
1203
1204                 } else if ( strcasecmp( arg, "try" ) == 0 ) {
1205                         i = LDAP_OPT_X_TLS_TRY ;
1206
1207                 } else if ( ( strcasecmp( arg, "hard" ) == 0 ) ||
1208                         ( strcasecmp( arg, "on" ) == 0 ) ||
1209                         ( strcasecmp( arg, "yes" ) == 0) ||
1210                         ( strcasecmp( arg, "true" ) == 0 ) )
1211                 {
1212                         i = LDAP_OPT_X_TLS_HARD ;
1213                 }
1214
1215                 if (i >= 0) {
1216                         return ldap_pvt_tls_set_option( ld, option, &i );
1217                 }
1218                 return -1;
1219 #ifdef HAVE_OPENSSL_CRL
1220         case LDAP_OPT_X_TLS_CRLCHECK:
1221                 i = -1;
1222                 if ( strcasecmp( arg, "none" ) == 0 ) {
1223                         i = LDAP_OPT_X_TLS_CRL_NONE ;
1224                 } else if ( strcasecmp( arg, "peer" ) == 0 ) {
1225                         i = LDAP_OPT_X_TLS_CRL_PEER ;
1226                 } else if ( strcasecmp( arg, "all" ) == 0 ) {
1227                         i = LDAP_OPT_X_TLS_CRL_ALL ;
1228                 }
1229                 if (i >= 0) {
1230                         return ldap_pvt_tls_set_option( ld, option, &i );
1231                 }
1232                 return -1;
1233 #endif
1234         }
1235         return -1;
1236 }
1237
1238 int
1239 ldap_pvt_tls_get_option( LDAP *ld, int option, void *arg )
1240 {
1241         struct ldapoptions *lo;
1242
1243         if( ld != NULL ) {
1244                 assert( LDAP_VALID( ld ) );
1245
1246                 if( !LDAP_VALID( ld ) ) {
1247                         return LDAP_OPT_ERROR;
1248                 }
1249
1250                 lo = &ld->ld_options;
1251
1252         } else {
1253                 /* Get pointer to global option structure */
1254                 lo = LDAP_INT_GLOBAL_OPT();   
1255                 if ( lo == NULL ) {
1256                         return LDAP_NO_MEMORY;
1257                 }
1258         }
1259
1260         switch( option ) {
1261         case LDAP_OPT_X_TLS:
1262                 *(int *)arg = lo->ldo_tls_mode;
1263                 break;
1264         case LDAP_OPT_X_TLS_CTX:
1265                 *(void **)arg = lo->ldo_tls_ctx;
1266                 if ( lo->ldo_tls_ctx ) {
1267                         SSL_CTX *ctx = lo->ldo_tls_ctx;
1268                         CRYPTO_add( &ctx->references, 1, CRYPTO_LOCK_SSL_CTX );
1269                 }
1270                 break;
1271         case LDAP_OPT_X_TLS_CACERTFILE:
1272                 *(char **)arg = lo->ldo_tls_cacertfile ?
1273                         LDAP_STRDUP( lo->ldo_tls_cacertfile ) : NULL;
1274                 break;
1275         case LDAP_OPT_X_TLS_CACERTDIR:
1276                 *(char **)arg = lo->ldo_tls_cacertdir ?
1277                         LDAP_STRDUP( lo->ldo_tls_cacertdir ) : NULL;
1278                 break;
1279         case LDAP_OPT_X_TLS_CERTFILE:
1280                 *(char **)arg = lo->ldo_tls_certfile ?
1281                         LDAP_STRDUP( lo->ldo_tls_certfile ) : NULL;
1282                 break;
1283         case LDAP_OPT_X_TLS_KEYFILE:
1284                 *(char **)arg = lo->ldo_tls_keyfile ?
1285                         LDAP_STRDUP( lo->ldo_tls_keyfile ) : NULL;
1286                 break;
1287         case LDAP_OPT_X_TLS_DHFILE:
1288                 *(char **)arg = lo->ldo_tls_dhfile ?
1289                         LDAP_STRDUP( lo->ldo_tls_dhfile ) : NULL;
1290                 break;
1291         case LDAP_OPT_X_TLS_REQUIRE_CERT:
1292                 *(int *)arg = lo->ldo_tls_require_cert;
1293                 break;
1294 #ifdef HAVE_OPENSSL_CRL
1295         case LDAP_OPT_X_TLS_CRLCHECK:
1296                 *(int *)arg = lo->ldo_tls_crlcheck;
1297                 break;
1298 #endif
1299         case LDAP_OPT_X_TLS_RANDOM_FILE:
1300                 *(char **)arg = tls_opt_randfile ?
1301                         LDAP_STRDUP( tls_opt_randfile ) : NULL;
1302                 break;
1303         case LDAP_OPT_X_TLS_SSL_CTX: {
1304                 void *retval = 0;
1305                 if ( ld != NULL ) {
1306                         LDAPConn *conn = ld->ld_defconn;
1307                         if ( conn != NULL ) {
1308                                 Sockbuf *sb = conn->lconn_sb;
1309                                 retval = ldap_pvt_tls_sb_ctx( sb );
1310                         }
1311                 }
1312                 *(void **)arg = retval;
1313                 break;
1314         }
1315         case LDAP_OPT_X_TLS_CONNECT_CB:
1316                 *(LDAP_TLS_CONNECT_CB **)arg = lo->ldo_tls_connect_cb;
1317                 break;
1318         case LDAP_OPT_X_TLS_CONNECT_ARG:
1319                 *(void **)arg = lo->ldo_tls_connect_arg;
1320                 break;
1321         default:
1322                 return -1;
1323         }
1324         return 0;
1325 }
1326
1327 int
1328 ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
1329 {
1330         struct ldapoptions *lo;
1331
1332         if( ld != NULL ) {
1333                 assert( LDAP_VALID( ld ) );
1334
1335                 if( !LDAP_VALID( ld ) ) {
1336                         return LDAP_OPT_ERROR;
1337                 }
1338
1339                 lo = &ld->ld_options;
1340
1341         } else {
1342                 /* Get pointer to global option structure */
1343                 lo = LDAP_INT_GLOBAL_OPT();   
1344                 if ( lo == NULL ) {
1345                         return LDAP_NO_MEMORY;
1346                 }
1347         }
1348
1349         switch( option ) {
1350         case LDAP_OPT_X_TLS:
1351                 if ( !arg ) return -1;
1352
1353                 switch( *(int *) arg ) {
1354                 case LDAP_OPT_X_TLS_NEVER:
1355                 case LDAP_OPT_X_TLS_DEMAND:
1356                 case LDAP_OPT_X_TLS_ALLOW:
1357                 case LDAP_OPT_X_TLS_TRY:
1358                 case LDAP_OPT_X_TLS_HARD:
1359                         if (lo != NULL) {
1360                                 lo->ldo_tls_mode = *(int *)arg;
1361                         }
1362
1363                         return 0;
1364                 }
1365                 return -1;
1366
1367         case LDAP_OPT_X_TLS_CTX:
1368                 if ( lo->ldo_tls_ctx )
1369                         SSL_CTX_free( lo->ldo_tls_ctx );
1370                 lo->ldo_tls_ctx = arg;
1371                 CRYPTO_add( &((SSL_CTX *)arg)->references, 1, CRYPTO_LOCK_SSL_CTX );
1372                 return 0;
1373         case LDAP_OPT_X_TLS_CONNECT_CB:
1374                 lo->ldo_tls_connect_cb = (LDAP_TLS_CONNECT_CB *)arg;
1375                 return 0;
1376         case LDAP_OPT_X_TLS_CONNECT_ARG:
1377                 lo->ldo_tls_connect_arg = arg;
1378                 return 0;
1379         case LDAP_OPT_X_TLS_CACERTFILE:
1380                 if ( lo->ldo_tls_cacertfile ) LDAP_FREE( lo->ldo_tls_cacertfile );
1381                 lo->ldo_tls_cacertfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1382                 return 0;
1383         case LDAP_OPT_X_TLS_CACERTDIR:
1384                 if ( lo->ldo_tls_cacertdir ) LDAP_FREE( lo->ldo_tls_cacertdir );
1385                 lo->ldo_tls_cacertdir = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1386                 return 0;
1387         case LDAP_OPT_X_TLS_CERTFILE:
1388                 if ( lo->ldo_tls_certfile ) LDAP_FREE( lo->ldo_tls_certfile );
1389                 lo->ldo_tls_certfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1390                 return 0;
1391         case LDAP_OPT_X_TLS_KEYFILE:
1392                 if ( lo->ldo_tls_keyfile ) LDAP_FREE( lo->ldo_tls_keyfile );
1393                 lo->ldo_tls_keyfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1394                 return 0;
1395         case LDAP_OPT_X_TLS_DHFILE:
1396                 if ( lo->ldo_tls_dhfile ) LDAP_FREE( lo->ldo_tls_dhfile );
1397                 lo->ldo_tls_dhfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1398                 return 0;
1399         case LDAP_OPT_X_TLS_REQUIRE_CERT:
1400                 if ( !arg ) return -1;
1401                 switch( *(int *) arg ) {
1402                 case LDAP_OPT_X_TLS_NEVER:
1403                 case LDAP_OPT_X_TLS_DEMAND:
1404                 case LDAP_OPT_X_TLS_ALLOW:
1405                 case LDAP_OPT_X_TLS_TRY:
1406                 case LDAP_OPT_X_TLS_HARD:
1407                         lo->ldo_tls_require_cert = * (int *) arg;
1408                         return 0;
1409                 }
1410                 return -1;
1411 #ifdef HAVE_OPENSSL_CRL
1412         case LDAP_OPT_X_TLS_CRLCHECK:
1413                 if ( !arg ) return -1;
1414                 switch( *(int *) arg ) {
1415                 case LDAP_OPT_X_TLS_CRL_NONE:
1416                 case LDAP_OPT_X_TLS_CRL_PEER:
1417                 case LDAP_OPT_X_TLS_CRL_ALL:
1418                         lo->ldo_tls_crlcheck = * (int *) arg;
1419                         return 0;
1420                 }
1421                 return -1;
1422 #endif
1423         case LDAP_OPT_X_TLS_CIPHER_SUITE:
1424                 if ( lo->ldo_tls_ciphersuite ) LDAP_FREE( lo->ldo_tls_ciphersuite );
1425                 lo->ldo_tls_ciphersuite = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1426                 return 0;
1427
1428         case LDAP_OPT_X_TLS_RANDOM_FILE:
1429                 if ( ld != NULL )
1430                         return -1;
1431                 if (tls_opt_randfile ) LDAP_FREE (tls_opt_randfile );
1432                 tls_opt_randfile = arg ? LDAP_STRDUP( (char *) arg ) : NULL;
1433                 break;
1434
1435         case LDAP_OPT_X_TLS_NEWCTX:
1436                 if ( !arg ) return -1;
1437                 if ( lo->ldo_tls_ctx )
1438                         SSL_CTX_free( lo->ldo_tls_ctx );
1439                 lo->ldo_tls_ctx = NULL;
1440                 return ldap_int_tls_init_ctx( lo, *(int *)arg );
1441         default:
1442                 return -1;
1443         }
1444         return 0;
1445 }
1446
1447 int
1448 ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
1449 {
1450         Sockbuf *sb = conn->lconn_sb;
1451         char *host;
1452         void *ssl;
1453
1454         if( srv ) {
1455                 host = srv->lud_host;
1456         } else {
1457                 host = conn->lconn_server->lud_host;
1458         }
1459
1460         /* avoid NULL host */
1461         if( host == NULL ) {
1462                 host = "localhost";
1463         }
1464
1465         (void) ldap_pvt_tls_init();
1466
1467         /*
1468          * Fortunately, the lib uses blocking io...
1469          */
1470         if ( ldap_int_tls_connect( ld, conn ) < 0 ) {
1471                 ld->ld_errno = LDAP_CONNECT_ERROR;
1472                 return (ld->ld_errno);
1473         }
1474
1475         ssl = ldap_pvt_tls_sb_ctx( sb );
1476         assert( ssl != NULL );
1477
1478         /* 
1479          * compare host with name(s) in certificate
1480          */
1481         if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER) {
1482                 ld->ld_errno = ldap_pvt_tls_check_hostname( ld, ssl, host );
1483                 if (ld->ld_errno != LDAP_SUCCESS) {
1484                         return ld->ld_errno;
1485                 }
1486         }
1487
1488         return LDAP_SUCCESS;
1489 }
1490
1491 /* Derived from openssl/apps/s_cb.c */
1492 static void
1493 tls_info_cb( const SSL *ssl, int where, int ret )
1494 {
1495         int w;
1496         char *op;
1497         char *state = (char *) SSL_state_string_long( (SSL *)ssl );
1498
1499         w = where & ~SSL_ST_MASK;
1500         if ( w & SSL_ST_CONNECT ) {
1501                 op = "SSL_connect";
1502         } else if ( w & SSL_ST_ACCEPT ) {
1503                 op = "SSL_accept";
1504         } else {
1505                 op = "undefined";
1506         }
1507
1508 #ifdef HAVE_EBCDIC
1509         if ( state ) {
1510                 state = LDAP_STRDUP( state );
1511                 __etoa( state );
1512         }
1513 #endif
1514         if ( where & SSL_CB_LOOP ) {
1515                 Debug( LDAP_DEBUG_TRACE,
1516                            "TLS trace: %s:%s\n",
1517                            op, state, 0 );
1518
1519         } else if ( where & SSL_CB_ALERT ) {
1520                 char *atype = (char *) SSL_alert_type_string_long( ret );
1521                 char *adesc = (char *) SSL_alert_desc_string_long( ret );
1522                 op = ( where & SSL_CB_READ ) ? "read" : "write";
1523 #ifdef HAVE_EBCDIC
1524                 if ( atype ) {
1525                         atype = LDAP_STRDUP( atype );
1526                         __etoa( atype );
1527                 }
1528                 if ( adesc ) {
1529                         adesc = LDAP_STRDUP( adesc );
1530                         __etoa( adesc );
1531                 }
1532 #endif
1533                 Debug( LDAP_DEBUG_TRACE,
1534                            "TLS trace: SSL3 alert %s:%s:%s\n",
1535                            op, atype, adesc );
1536 #ifdef HAVE_EBCDIC
1537                 if ( atype ) LDAP_FREE( atype );
1538                 if ( adesc ) LDAP_FREE( adesc );
1539 #endif
1540         } else if ( where & SSL_CB_EXIT ) {
1541                 if ( ret == 0 ) {
1542                         Debug( LDAP_DEBUG_TRACE,
1543                                    "TLS trace: %s:failed in %s\n",
1544                                    op, state, 0 );
1545                 } else if ( ret < 0 ) {
1546                         Debug( LDAP_DEBUG_TRACE,
1547                                    "TLS trace: %s:error in %s\n",
1548                                    op, state, 0 );
1549                 }
1550         }
1551 #ifdef HAVE_EBCDIC
1552         if ( state ) LDAP_FREE( state );
1553 #endif
1554 }
1555
1556 static int
1557 tls_verify_cb( int ok, X509_STORE_CTX *ctx )
1558 {
1559         X509 *cert;
1560         int errnum;
1561         int errdepth;
1562         X509_NAME *subject;
1563         X509_NAME *issuer;
1564         char *sname;
1565         char *iname;
1566         char *certerr = NULL;
1567
1568         cert = X509_STORE_CTX_get_current_cert( ctx );
1569         errnum = X509_STORE_CTX_get_error( ctx );
1570         errdepth = X509_STORE_CTX_get_error_depth( ctx );
1571
1572         /*
1573          * X509_get_*_name return pointers to the internal copies of
1574          * those things requested.  So do not free them.
1575          */
1576         subject = X509_get_subject_name( cert );
1577         issuer = X509_get_issuer_name( cert );
1578         /* X509_NAME_oneline, if passed a NULL buf, allocate memomry */
1579         sname = X509_NAME_oneline( subject, NULL, 0 );
1580         iname = X509_NAME_oneline( issuer, NULL, 0 );
1581         if ( !ok ) certerr = (char *)X509_verify_cert_error_string( errnum );
1582 #ifdef HAVE_EBCDIC
1583         if ( sname ) __etoa( sname );
1584         if ( iname ) __etoa( iname );
1585         if ( certerr ) {
1586                 certerr = LDAP_STRDUP( certerr );
1587                 __etoa( certerr );
1588         }
1589 #endif
1590         Debug( LDAP_DEBUG_TRACE,
1591                    "TLS certificate verification: depth: %d, err: %d, subject: %s,",
1592                    errdepth, errnum,
1593                    sname ? sname : "-unknown-" );
1594         Debug( LDAP_DEBUG_TRACE, " issuer: %s\n", iname ? iname : "-unknown-", 0, 0 );
1595         if ( !ok ) {
1596                 Debug( LDAP_DEBUG_ANY,
1597                         "TLS certificate verification: Error, %s\n",
1598                         certerr, 0, 0 );
1599         }
1600         if ( sname )
1601                 CRYPTO_free ( sname );
1602         if ( iname )
1603                 CRYPTO_free ( iname );
1604 #ifdef HAVE_EBCDIC
1605         if ( certerr ) LDAP_FREE( certerr );
1606 #endif
1607         return ok;
1608 }
1609
1610 static int
1611 tls_verify_ok( int ok, X509_STORE_CTX *ctx )
1612 {
1613         (void) tls_verify_cb( ok, ctx );
1614         return 1;
1615 }
1616
1617 /* Inspired by ERR_print_errors in OpenSSL */
1618 static void
1619 tls_report_error( void )
1620 {
1621         unsigned long l;
1622         char buf[200];
1623         const char *file;
1624         int line;
1625
1626         while ( ( l = ERR_get_error_line( &file, &line ) ) != 0 ) {
1627                 ERR_error_string_n( l, buf, sizeof( buf ) );
1628 #ifdef HAVE_EBCDIC
1629                 if ( file ) {
1630                         file = LDAP_STRDUP( file );
1631                         __etoa( (char *)file );
1632                 }
1633                 __etoa( buf );
1634 #endif
1635                 Debug( LDAP_DEBUG_ANY, "TLS: %s %s:%d\n",
1636                         buf, file, line );
1637 #ifdef HAVE_EBCDIC
1638                 if ( file ) LDAP_FREE( (void *)file );
1639 #endif
1640         }
1641 }
1642
1643 static RSA *
1644 tls_tmp_rsa_cb( SSL *ssl, int is_export, int key_length )
1645 {
1646         RSA *tmp_rsa;
1647
1648         /* FIXME:  Pregenerate the key on startup */
1649         /* FIXME:  Who frees the key? */
1650         tmp_rsa = RSA_generate_key( key_length, RSA_F4, NULL, NULL );
1651
1652         if ( !tmp_rsa ) {
1653                 Debug( LDAP_DEBUG_ANY,
1654                         "TLS: Failed to generate temporary %d-bit %s RSA key\n",
1655                         key_length, is_export ? "export" : "domestic", 0 );
1656                 return NULL;
1657         }
1658         return tmp_rsa;
1659 }
1660
1661 static int
1662 tls_seed_PRNG( const char *randfile )
1663 {
1664 #ifndef URANDOM_DEVICE
1665         /* no /dev/urandom (or equiv) */
1666         long total=0;
1667         char buffer[MAXPATHLEN];
1668
1669         if (randfile == NULL) {
1670                 /* The seed file is $RANDFILE if defined, otherwise $HOME/.rnd.
1671                  * If $HOME is not set or buffer too small to hold the pathname,
1672                  * an error occurs.     - From RAND_file_name() man page.
1673                  * The fact is that when $HOME is NULL, .rnd is used.
1674                  */
1675                 randfile = RAND_file_name( buffer, sizeof( buffer ) );
1676
1677         } else if (RAND_egd(randfile) > 0) {
1678                 /* EGD socket */
1679                 return 0;
1680         }
1681
1682         if (randfile == NULL) {
1683                 Debug( LDAP_DEBUG_ANY,
1684                         "TLS: Use configuration file or $RANDFILE to define seed PRNG\n",
1685                         0, 0, 0);
1686                 return -1;
1687         }
1688
1689         total = RAND_load_file(randfile, -1);
1690
1691         if (RAND_status() == 0) {
1692                 Debug( LDAP_DEBUG_ANY,
1693                         "TLS: PRNG not been seeded with enough data\n",
1694                         0, 0, 0);
1695                 return -1;
1696         }
1697
1698         /* assume if there was enough bits to seed that it's okay
1699          * to write derived bits to the file
1700          */
1701         RAND_write_file(randfile);
1702
1703 #endif
1704
1705         return 0;
1706 }
1707
1708 struct dhinfo {
1709         int keylength;
1710         const char *pem;
1711         size_t size;
1712 };
1713
1714
1715 /* From the OpenSSL 0.9.7 distro */
1716 static const char dhpem512[] =
1717 "-----BEGIN DH PARAMETERS-----\n\
1718 MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn\n\
1719 a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC\n\
1720 -----END DH PARAMETERS-----\n";
1721
1722 static const char dhpem1024[] =
1723 "-----BEGIN DH PARAMETERS-----\n\
1724 MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq\n\
1725 /Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx\n\
1726 /mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC\n\
1727 -----END DH PARAMETERS-----\n";
1728
1729 static const char dhpem2048[] =
1730 "-----BEGIN DH PARAMETERS-----\n\
1731 MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o\n\
1732 AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh\n\
1733 z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo\n\
1734 pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW\n\
1735 aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA\n\
1736 Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg==\n\
1737 -----END DH PARAMETERS-----\n";
1738
1739 static const char dhpem4096[] =
1740 "-----BEGIN DH PARAMETERS-----\n\
1741 MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7\n\
1742 vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H\n\
1743 TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF\n\
1744 bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1\n\
1745 rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE\n\
1746 EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9\n\
1747 bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3\n\
1748 W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH\n\
1749 ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb\n\
1750 NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR\n\
1751 jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI=\n\
1752 -----END DH PARAMETERS-----\n";
1753
1754 static const struct dhinfo dhpem[] = {
1755         { 512, dhpem512, sizeof(dhpem512) },
1756         { 1024, dhpem1024, sizeof(dhpem1024) },
1757         { 2048, dhpem2048, sizeof(dhpem2048) },
1758         { 4096, dhpem4096, sizeof(dhpem4096) },
1759         { 0, NULL, 0 }
1760 };
1761
1762 static DH *
1763 tls_tmp_dh_cb( SSL *ssl, int is_export, int key_length )
1764 {
1765         struct dhplist *p = NULL;
1766         BIO *b = NULL;
1767         DH *dh = NULL;
1768         int i;
1769
1770         /* Do we have params of this length already? */
1771 #ifdef LDAP_R_COMPILE
1772         ldap_pvt_thread_mutex_lock( &tls_def_ctx_mutex );
1773 #endif
1774         for ( p = dhparams; p; p=p->next ) {
1775                 if ( p->keylength == key_length ) {
1776 #ifdef LDAP_R_COMPILE
1777                         ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
1778 #endif
1779                         return p->param;
1780                 }
1781         }
1782
1783         /* No - check for hardcoded params */
1784
1785         for (i=0; dhpem[i].keylength; i++) {
1786                 if ( dhpem[i].keylength == key_length ) {
1787                         b = BIO_new_mem_buf( (char *)dhpem[i].pem, dhpem[i].size );
1788                         break;
1789                 }
1790         }
1791
1792         if ( b ) {
1793                 dh = PEM_read_bio_DHparams( b, NULL, NULL, NULL );
1794                 BIO_free( b );
1795         }
1796
1797         /* Generating on the fly is expensive/slow... */
1798         if ( !dh ) {
1799                 dh = DH_generate_parameters( key_length, DH_GENERATOR_2, NULL, NULL );
1800         }
1801         if ( dh ) {
1802                 p = LDAP_MALLOC( sizeof(struct dhplist) );
1803                 if ( p != NULL ) {
1804                         p->keylength = key_length;
1805                         p->param = dh;
1806                         p->next = dhparams;
1807                         dhparams = p;
1808                 }
1809         }
1810
1811 #ifdef LDAP_R_COMPILE
1812         ldap_pvt_thread_mutex_unlock( &tls_def_ctx_mutex );
1813 #endif
1814         return dh;
1815 }
1816 #endif
1817
1818 void *
1819 ldap_pvt_tls_sb_ctx( Sockbuf *sb )
1820 {
1821 #ifdef HAVE_TLS
1822         void                    *p;
1823         
1824         if (HAS_TLS( sb )) {
1825                 ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_SSL, (void *)&p );
1826                 return p;
1827         }
1828 #endif
1829
1830         return NULL;
1831 }
1832
1833 int
1834 ldap_pvt_tls_get_strength( void *s )
1835 {
1836 #ifdef HAVE_TLS
1837         SSL_CIPHER *c;
1838
1839         c = SSL_get_current_cipher((SSL *)s);
1840         return SSL_CIPHER_get_bits(c, NULL);
1841 #else
1842         return 0;
1843 #endif
1844 }
1845
1846
1847 int
1848 ldap_pvt_tls_get_my_dn( void *s, struct berval *dn, LDAPDN_rewrite_dummy *func, unsigned flags )
1849 {
1850 #ifdef HAVE_TLS
1851         X509 *x;
1852         X509_NAME *xn;
1853         int rc;
1854
1855         x = SSL_get_certificate((SSL *)s);
1856
1857         if (!x) return LDAP_INVALID_CREDENTIALS;
1858         
1859         xn = X509_get_subject_name(x);
1860         rc = ldap_X509dn2bv(xn, dn, (LDAPDN_rewrite_func *)func, flags );
1861         return rc;
1862 #else
1863         return LDAP_NOT_SUPPORTED;
1864 #endif
1865 }
1866
1867 int
1868 ldap_start_tls( LDAP *ld,
1869         LDAPControl **serverctrls,
1870         LDAPControl **clientctrls,
1871         int *msgidp )
1872 {
1873         return ldap_extended_operation( ld, LDAP_EXOP_START_TLS,
1874                 NULL, serverctrls, clientctrls, msgidp );
1875 }
1876
1877 int
1878 ldap_install_tls( LDAP *ld )
1879 {
1880 #ifndef HAVE_TLS
1881         return LDAP_NOT_SUPPORTED;
1882 #else
1883         if ( ldap_tls_inplace( ld ) ) {
1884                 return LDAP_LOCAL_ERROR;
1885         }
1886
1887         return ldap_int_tls_start( ld, ld->ld_defconn, NULL );
1888 #endif
1889 }
1890
1891 int
1892 ldap_start_tls_s ( LDAP *ld,
1893         LDAPControl **serverctrls,
1894         LDAPControl **clientctrls )
1895 {
1896 #ifndef HAVE_TLS
1897         return LDAP_NOT_SUPPORTED;
1898 #else
1899         int rc;
1900         char *rspoid = NULL;
1901         struct berval *rspdata = NULL;
1902
1903         /* XXYYZ: this initiates operation only on default connection! */
1904
1905         if ( ldap_tls_inplace( ld ) ) {
1906                 return LDAP_LOCAL_ERROR;
1907         }
1908
1909         rc = ldap_extended_operation_s( ld, LDAP_EXOP_START_TLS,
1910                 NULL, serverctrls, clientctrls, &rspoid, &rspdata );
1911
1912         if ( rspoid != NULL ) {
1913                 LDAP_FREE(rspoid);
1914         }
1915
1916         if ( rspdata != NULL ) {
1917                 ber_bvfree( rspdata );
1918         }
1919
1920         if ( rc == LDAP_SUCCESS ) {
1921                 rc = ldap_int_tls_start( ld, ld->ld_defconn, NULL );
1922         }
1923
1924         return rc;
1925 #endif
1926 }
1927