]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#9157 save TLS errmsg in ld->ld_error
authorHoward Chu <hyc@openldap.org>
Thu, 22 Jul 2021 14:26:29 +0000 (15:26 +0100)
committerHoward Chu <hyc@openldap.org>
Thu, 22 Jul 2021 14:27:31 +0000 (15:27 +0100)
libraries/libldap/ldap-tls.h
libraries/libldap/tls2.c
libraries/libldap/tls_g.c
libraries/libldap/tls_o.c
servers/slapd/config.c
servers/slapd/main.c

index 378d08b6b0220eeed18d1aa50063ca7ffc38c094..423d18195f5f16831c492e9ff2d1b7588676fe1b 100644 (file)
@@ -31,7 +31,8 @@ typedef void (TI_tls_destroy)(void);
 typedef tls_ctx *(TI_ctx_new)(struct ldapoptions *lo);
 typedef void (TI_ctx_ref)(tls_ctx *ctx);
 typedef void (TI_ctx_free)(tls_ctx *ctx);
-typedef int (TI_ctx_init)(struct ldapoptions *lo, struct ldaptls *lt, int is_server);
+#define ERRBUFSIZE     256
+typedef int (TI_ctx_init)(struct ldapoptions *lo, struct ldaptls *lt, int is_server, char *errmsg);
 
 typedef tls_session *(TI_session_new)(tls_ctx *ctx, int is_server);
 typedef int (TI_session_connect)(LDAP *ld, tls_session *s, const char *name_in);
index d76ac6adfc28cd72518613e4759d64eca6f7b34f..a3a8399bf598921b7ba937b6747e3a3962fe1389 100644 (file)
@@ -199,7 +199,7 @@ ldap_pvt_tls_init( int do_threads )
  * initialize a new TLS context
  */
 static int
-ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server )
+ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server, char *errmsg )
 {
        int rc = 0;
        tls_impl *ti = tls_imp;
@@ -261,7 +261,7 @@ ldap_int_tls_init_ctx( struct ldapoptions *lo, int is_server )
                goto error_exit;
        }
 
-       rc = ti->ti_ctx_init( lo, &lts, is_server );
+       rc = ti->ti_ctx_init( lo, &lts, is_server, errmsg );
 
 error_exit:
        if ( rc < 0 && lo->ldo_tls_ctx != NULL ) {
@@ -288,10 +288,15 @@ int
 ldap_pvt_tls_init_def_ctx( int is_server )
 {
        struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();   
+       char errmsg[ERRBUFSIZE];
        int rc;
+       errmsg[0] = 0;
        LDAP_MUTEX_LOCK( &tls_def_ctx_mutex );
-       rc = ldap_int_tls_init_ctx( lo, is_server );
+       rc = ldap_int_tls_init_ctx( lo, is_server, errmsg );
        LDAP_MUTEX_UNLOCK( &tls_def_ctx_mutex );
+       if ( rc ) {
+               Debug1( LDAP_DEBUG_ANY,"TLS: init_def_ctx: %s.\n", errmsg );
+       }
        return rc;
 }
 
@@ -975,12 +980,22 @@ ldap_pvt_tls_set_option( LDAP *ld, int option, void *arg )
                if ( lo->ldo_tls_randfile ) LDAP_FREE (lo->ldo_tls_randfile );
                lo->ldo_tls_randfile = (arg && *(char *)arg) ? LDAP_STRDUP( (char *) arg ) : NULL;
                break;
-       case LDAP_OPT_X_TLS_NEWCTX:
+       case LDAP_OPT_X_TLS_NEWCTX: {
+               int rc;
+               char errmsg[ERRBUFSIZE];
                if ( !arg ) return -1;
                if ( lo->ldo_tls_ctx )
                        ldap_pvt_tls_ctx_free( lo->ldo_tls_ctx );
                lo->ldo_tls_ctx = NULL;
-               return ldap_int_tls_init_ctx( lo, *(int *)arg );
+               errmsg[0] = 0;
+               rc = ldap_int_tls_init_ctx( lo, *(int *)arg, errmsg );
+               if ( rc && errmsg[0] ) {
+                       if ( ld->ld_error )
+                               LDAP_FREE( ld->ld_error );
+                       ld->ld_error = LDAP_STRDUP( errmsg );
+               }
+               return rc;
+               }
        case LDAP_OPT_X_TLS_CACERT:
                if ( lo->ldo_tls_cacert.bv_val )
                        LDAP_FREE( lo->ldo_tls_cacert.bv_val );
index f45c33a672beabd744f7702e7915c01aabf9ea0a..17bcc69f153bf3a5af4c912902c131004b9a476b 100644 (file)
@@ -181,7 +181,7 @@ tlsg_getfile( const char *path, gnutls_datum_t *buf )
  * initialize a new TLS context
  */
 static int
-tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
+tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server, char *errmsg )
 {
        tlsg_ctx *ctx = lo->ldo_tls_ctx;
        int rc;
@@ -208,6 +208,7 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                                "TLS: warning: no certificate found in CA certificate directory `%s'.\n",
                                lt->lt_cacertdir );
                        /* only warn, no return */
+                       strncpy( errmsg, gnutls_strerror( rc ), ERRBUFSIZE );
                }
        }
 
@@ -228,6 +229,7 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                                "TLS: warning: no certificate loaded from CA certificate file `%s'.\n",
                                lo->ldo_tls_cacertfile );
                        /* only warn, no return */
+                       strncpy( errmsg, gnutls_strerror( rc ), ERRBUFSIZE );
                }
        }
 
@@ -244,6 +246,7 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                                "TLS: could not use CA certificate: %s (%d)\n",
                                gnutls_strerror( rc ),
                                rc );
+                       strncpy( errmsg, gnutls_strerror( rc ), ERRBUFSIZE );
                        return -1;
                }
        }
@@ -256,7 +259,10 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                unsigned int max = VERIFY_DEPTH;
 
                rc = gnutls_x509_privkey_init( &key );
-               if ( rc ) return -1;
+               if ( rc ) {
+                       strncpy( errmsg, gnutls_strerror( rc ), ERRBUFSIZE );
+                       return -1;
+               }
 
                /* OpenSSL builds the cert chain for us, but GnuTLS
                 * expects it to be present in the certfile. If it's
@@ -285,6 +291,7 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                                "TLS: could not use private key: %s (%d)\n",
                                gnutls_strerror( rc ),
                                rc );
+                       strncpy( errmsg, gnutls_strerror( rc ), ERRBUFSIZE );
                        return rc;
                }
 
@@ -310,6 +317,7 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                                "TLS: could not use certificate: %s (%d)\n",
                                gnutls_strerror( rc ),
                                rc );
+                       strncpy( errmsg, gnutls_strerror( rc ), ERRBUFSIZE );
                        return rc;
                }
 
@@ -333,6 +341,7 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                                "TLS: could not use certificate with key: %s (%d)\n",
                                gnutls_strerror( rc ),
                                rc );
+                       strncpy( errmsg, gnutls_strerror( rc ), ERRBUFSIZE );
                        return -1;
                }
        } else if (( lo->ldo_tls_certfile || lo->ldo_tls_keyfile )) {
@@ -350,7 +359,10 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                        ctx->cred,
                        lt->lt_crlfile,
                        GNUTLS_X509_FMT_PEM );
-               if ( rc < 0 ) return -1;
+               if ( rc < 0 ) {
+                       strncpy( errmsg, gnutls_strerror( rc ), ERRBUFSIZE );
+                       return -1;
+               }
                rc = 0;
        }
 
@@ -369,7 +381,10 @@ tlsg_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                        rc = gnutls_dh_params_import_pkcs3( ctx->dh_params, &buf,
                                GNUTLS_X509_FMT_PEM );
                LDAP_FREE( buf.data );
-               if ( rc ) return -1;
+               if ( rc ) {
+                       strncpy( errmsg, gnutls_strerror( rc ), ERRBUFSIZE );
+                       return -1;
+               }
                gnutls_certificate_set_dh_params( ctx->cred, ctx->dh_params );
        }
 
index 92f70afc64db312e3dbe853da56c1db45817c405..175bb141815a42aba15c11cc781979ee62ef810e 100644 (file)
@@ -60,7 +60,7 @@ static BIO_METHOD * tlso_bio_setup( void );
 
 static int  tlso_opt_trace = 1;
 
-static void tlso_report_error( void );
+static void tlso_report_error( char *errmsg );
 
 static void tlso_info_cb( const SSL *ssl, int where, int ret );
 static int tlso_verify_cb( int ok, X509_STORE_CTX *ctx );
@@ -349,7 +349,7 @@ tlso_ctx_cipher13( tlso_ctx *ctx, char *suites )
  * initialize a new TLS context
  */
 static int
-tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
+tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server, char *errmsg )
 {
        tlso_ctx *ctx = (tlso_ctx *)lo->ldo_tls_ctx;
        int i;
@@ -419,7 +419,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                        Debug1( LDAP_DEBUG_ANY,
                                   "TLS: could not set cipher list %s.\n",
                                   lo->ldo_tls_ciphersuite );
-                       tlso_report_error();
+                       tlso_report_error( errmsg );
                        return -1;
                }
        }
@@ -429,7 +429,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                if ( !SSL_CTX_set_default_verify_paths( ctx ) ) {
                        Debug0( LDAP_DEBUG_ANY, "TLS: "
                                "could not use default certificate paths" );
-                       tlso_report_error();
+                       tlso_report_error( errmsg );
                        return -1;
                }
        } else {
@@ -441,7 +441,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                        if ( !X509_STORE_add_cert( store, cert )) {
                                Debug0( LDAP_DEBUG_ANY, "TLS: "
                                        "could not use CA certificate" );
-                               tlso_report_error();
+                               tlso_report_error( errmsg );
                                return -1;
                        }
                }
@@ -452,7 +452,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                                "could not load verify locations (file:`%s',dir:`%s').\n",
                                lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
                                lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "" );
-                       tlso_report_error();
+                       tlso_report_error( errmsg );
                        return -1;
                }
 
@@ -465,7 +465,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                                        "could not load client CA list (file:`%s',dir:`%s').\n",
                                        lo->ldo_tls_cacertfile ? lo->ldo_tls_cacertfile : "",
                                        lo->ldo_tls_cacertdir ? lo->ldo_tls_cacertdir : "" );
-                               tlso_report_error();
+                               tlso_report_error( errmsg );
                                return -1;
                        }
 
@@ -482,7 +482,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                if ( !SSL_CTX_use_certificate( ctx, cert )) {
                        Debug0( LDAP_DEBUG_ANY,
                                "TLS: could not use certificate.\n" );
-                       tlso_report_error();
+                       tlso_report_error( errmsg );
                        return -1;
                }
                X509_free( cert );
@@ -493,7 +493,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                Debug1( LDAP_DEBUG_ANY,
                        "TLS: could not use certificate file `%s'.\n",
                        lo->ldo_tls_certfile );
-               tlso_report_error();
+               tlso_report_error( errmsg );
                return -1;
        }
 
@@ -506,7 +506,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                {
                        Debug0( LDAP_DEBUG_ANY,
                                "TLS: could not use private key.\n" );
-                       tlso_report_error();
+                       tlso_report_error( errmsg );
                        return -1;
                }
                EVP_PKEY_free( pkey );
@@ -518,7 +518,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                Debug1( LDAP_DEBUG_ANY,
                        "TLS: could not use key file `%s'.\n",
                        lo->ldo_tls_keyfile );
-               tlso_report_error();
+               tlso_report_error( errmsg );
                return -1;
        }
 
@@ -530,14 +530,14 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                        Debug1( LDAP_DEBUG_ANY,
                                "TLS: could not use DH parameters file `%s'.\n",
                                lo->ldo_tls_dhfile );
-                       tlso_report_error();
+                       tlso_report_error( errmsg );
                        return -1;
                }
                if (!( dh=PEM_read_bio_DHparams( bio, NULL, NULL, NULL ))) {
                        Debug1( LDAP_DEBUG_ANY,
                                "TLS: could not read DH parameters file `%s'.\n",
                                lo->ldo_tls_dhfile );
-                       tlso_report_error();
+                       tlso_report_error( errmsg );
                        BIO_free( bio );
                        return -1;
                }
@@ -557,7 +557,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
                        Debug1( LDAP_DEBUG_ANY,
                                "TLS: could not set EC name `%s'.\n",
                                lo->ldo_tls_ecname );
-                       tlso_report_error();
+                       tlso_report_error( errmsg );
                        return -1;
                }
        /*
@@ -1531,15 +1531,17 @@ tlso_verify_ok( int ok, X509_STORE_CTX *ctx )
 
 /* Inspired by ERR_print_errors in OpenSSL */
 static void
-tlso_report_error( void )
+tlso_report_error( char *errmsg )
 {
        unsigned long l;
-       char buf[200];
+       char buf[ERRBUFSIZE];
        const char *file;
        int line;
 
        while ( ( l = ERR_get_error_line( &file, &line ) ) != 0 ) {
-               ERR_error_string_n( l, buf, sizeof( buf ) );
+               ERR_error_string_n( l, buf, ERRBUFSIZE );
+               if ( !*errmsg )
+                       strcpy(errmsg, buf );
 #ifdef HAVE_EBCDIC
                if ( file ) {
                        file = LDAP_STRDUP( file );
index 64c8951b5f1f32560ab45d7f60ba27c74f2d2534..8b9ec0f5f09d326223a9e134bc0b0e6d2ccf0c0e 100644 (file)
@@ -2160,10 +2160,13 @@ slap_client_connect( LDAP **ldp, slap_bindconf *sb )
 #ifdef HAVE_TLS
        rc = bindconf_tls_set( sb, ld );
        if ( rc ) {
+               char *errmsg = NULL;
+               ldap_get_option( ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, &errmsg );
                Debug( LDAP_DEBUG_ANY,
                        "slap_client_connect: "
-                       "URI=%s TLS context initialization failed (%d)\n",
-                       sb->sb_uri.bv_val, rc );
+                       "URI=%s TLS context initialization failed (%d) %s\n",
+                       sb->sb_uri.bv_val, rc, errmsg ? errmsg : "" );
+               ldap_memfree( errmsg );
                goto done;
        }
 #endif
index d8be4082b91f2672abec0a6627471fca9e188396..d92f978dd088711aa70742e8abbef68bf1fe45f4 100644 (file)
@@ -928,9 +928,12 @@ unhandled_option:;
                        ldap_pvt_tls_get_option( slap_tls_ld, LDAP_OPT_X_TLS_CTX, &slap_tls_ctx );
                        load_extop( &slap_EXOP_START_TLS, 0, starttls_extop );
                } else if ( rc != LDAP_NOT_SUPPORTED ) {
+                       char *errmsg = NULL;
+                       ldap_get_option( slap_tls_ld, LDAP_OPT_DIAGNOSTIC_MESSAGE, &errmsg );
                        Debug( LDAP_DEBUG_ANY,
-                           "main: TLS init def ctx failed: %d\n",
-                           rc );
+                           "main: TLS init def ctx failed: %d %s\n",
+                           rc, errmsg ? errmsg : "" );
+                       ldap_memfree( errmsg );
                        rc = 1;
                        SERVICE_EXIT( ERROR_SERVICE_SPECIFIC_ERROR, 20 );
                        goto destroy;