Improve misleading SSL/TLS trace messages. Resolves: #652818 Upstream ITS: #6706 Author: Rich Megginson (rmeggins@redhat.com) --- openldap.old/libraries/libldap/tls_m.c.3 2010-11-11 18:39:48.000000000 -0700 +++ openldap.new/libraries/libldap/tls_m.c 2010-11-11 20:17:35.000000000 -0700 @@ -709,16 +709,22 @@ Debug( LDAP_DEBUG_TRACE, "cache hits: %ld, cache misses: %ld, cache not reusable: %ld\n", ssl3stats->hch_sid_cache_hits, ssl3stats->hch_sid_cache_misses, ssl3stats->hch_sid_cache_not_ok ); return ""; } +static void +tlsm_handshake_complete_cb( PRFileDesc *fd, void *client_data ) +{ + tlsm_dump_security_status( fd ); +} + #ifdef READ_PASSWORD_FROM_FILE static char * tlsm_get_pin_from_file(const char *token_name, tlsm_ctx *ctx) { char *pwdstr = NULL; char *contents = NULL; char *lasts = NULL; char *line = NULL; @@ -894,26 +900,32 @@ } static SECStatus tlsm_auth_cert_handler(void *arg, PRFileDesc *fd, PRBool checksig, PRBool isServer) { SECStatus ret = SSL_AuthCertificate(arg, fd, checksig, isServer); - tlsm_dump_security_status( fd ); - Debug( LDAP_DEBUG_TRACE, - "TLS certificate verification: %s\n", - ret == SECSuccess ? "ok" : "bad", 0, 0 ); - if ( ret != SECSuccess ) { PRErrorCode errcode = PORT_GetError(); - Debug( LDAP_DEBUG_ANY, - "TLS certificate verification: Error, %d: %s\n", - errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ), 0 ) ; + /* we bypass NSS's hostname checks and do our own - tlsm_session_chkhost will handle it */ + if ( errcode == SSL_ERROR_BAD_CERT_DOMAIN ) { + Debug( LDAP_DEBUG_TRACE, + "TLS certificate verification: defer\n", + 0, 0, 0 ); + } else { + Debug( LDAP_DEBUG_ANY, + "TLS certificate verification: Error, %d: %s\n", + errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ), 0 ) ; + } + } else { + Debug( LDAP_DEBUG_TRACE, + "TLS certificate verification: ok\n", + 0, 0, 0 ); } return ret; } static int tlsm_authenticate_to_slot( tlsm_ctx *ctx, PK11SlotInfo *slot ) { @@ -1181,16 +1193,21 @@ static int tlsm_init_ca_certs( tlsm_ctx *ctx, const char *cacertfile, const char *cacertdir ) { PRBool isca = PR_TRUE; PRStatus status = PR_FAILURE; PRErrorCode errcode = PR_SUCCESS; + if ( !cacertfile && !cacertdir ) { + /* no checking - not good, but allowed */ + return 0; + } + if ( cacertfile ) { int rc = tlsm_add_cert_from_file( ctx, cacertfile, isca ); if ( rc ) { errcode = PR_GetError(); Debug( LDAP_DEBUG_ANY, "TLS: %s is not a valid CA certificate file - error %d:%s.\n", cacertfile, errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ) ); @@ -1394,19 +1411,21 @@ rc = (initctx == NULL) ? SECFailure : SECSuccess; #endif #else rc = NSS_Initialize( realcertdir, prefix, prefix, SECMOD_DB, NSS_INIT_READONLY ); #endif if ( rc != SECSuccess ) { errcode = PORT_GetError(); - Debug( LDAP_DEBUG_TRACE, - "TLS: could not initialize moznss using security dir %s prefix %s - error %d.\n", - realcertdir, prefix, errcode ); + if ( securitydirs[ii] != lt->lt_cacertdir) { + Debug( LDAP_DEBUG_TRACE, + "TLS: could not initialize moznss using security dir %s prefix %s - error %d.\n", + realcertdir, prefix, errcode ); + } } else { /* success */ Debug( LDAP_DEBUG_TRACE, "TLS: using moznss security dir %s prefix %s.\n", realcertdir, prefix, 0 ); errcode = 0; done = 1; } if ( realcertdir != securitydir ) { @@ -1453,16 +1472,31 @@ errcode = PORT_GetError(); Debug( LDAP_DEBUG_ANY, "TLS: could not initialize moznss PEM module - error %d:%s.\n", errcode, PR_ErrorToString( errcode, PR_LANGUAGE_I_DEFAULT ), 0 ); return -1; } if ( tlsm_init_ca_certs( ctx, lt->lt_cacertfile, lt->lt_cacertdir ) ) { + /* if we tried to use lt->lt_cacertdir as an NSS key/cert db, errcode + will be a value other than 1 - print an error message so that the + user will know that failed too */ + if ( ( errcode != 1 ) && ( lt->lt_cacertdir ) ) { + char *realcertdir = NULL; + char *prefix = NULL; + tlsm_get_certdb_prefix( lt->lt_cacertdir, &realcertdir, &prefix ); + Debug( LDAP_DEBUG_TRACE, + "TLS: could not initialize moznss using security dir %s prefix %s - error %d.\n", + realcertdir, prefix ? prefix : "", errcode ); + if ( realcertdir != lt->lt_cacertdir ) { + PL_strfree( realcertdir ); + } + PL_strfree( prefix ); + } return -1; } ctx->tc_using_pem = PR_TRUE; } #ifdef HAVE_NSS_INITCONTEXT if ( !ctx->tc_initctx ) { @@ -2040,16 +2074,24 @@ ctx->tc_certdb ) != SECSuccess ) { PRErrorCode err = PR_GetError(); Debug( LDAP_DEBUG_ANY, "TLS: error: could not set auth cert handler for moznss - error %d:%s\n", err, PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ), NULL ); return -1; } + if ( SSL_HandshakeCallback( ctx->tc_model, tlsm_handshake_complete_cb, ctx ) ) { + PRErrorCode err = PR_GetError(); + Debug( LDAP_DEBUG_ANY, + "TLS: error: could not set handshake callback for moznss - error %d:%s\n", + err, PR_ErrorToString( err, PR_LANGUAGE_I_DEFAULT ), NULL ); + return -1; + } + return 0; } struct tls_data { tlsm_session *session; Sockbuf_IO_Desc *sbiod; /* there seems to be no portable way to determine if the sockbuf sd has been set to nonblocking mode - the