TLS: do not reuse tls_session if hostname check fails If multiple servers are specified, the connection to the first one succeeds, and the hostname verification fails, *tls_session is not dropped, but reused when connecting to the second server. This is a problem with Mozilla NSS backend because another handshake cannot be performed on the same file descriptor. From this reason, hostname checking was moved into ldap_int_tls_connect() before connection error handling. Author: Jan Vcelak Upstream ITS: #7373 Resolves: #852476 diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c index f0b5bef..b13cb6d 100644 --- a/libraries/libldap/tls2.c +++ b/libraries/libldap/tls2.c @@ -316,7 +316,7 @@ update_flags( Sockbuf *sb, tls_session * ssl, int rc ) */ static int -ldap_int_tls_connect( LDAP *ld, LDAPConn *conn ) +ldap_int_tls_connect( LDAP *ld, LDAPConn *conn, const char *host ) { Sockbuf *sb = conn->lconn_sb; int err; @@ -361,6 +361,10 @@ ldap_int_tls_connect( LDAP *ld, LDAPConn *conn ) errno = WSAGetLastError(); #endif + if ( err == 0 ) { + err = ldap_pvt_tls_check_hostname( ld, ssl, host ); + } + if ( err < 0 ) { char buf[256], *msg; @@ -491,7 +495,15 @@ ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in ) { tls_session *session = s; - return tls_imp->ti_session_chkhost( ld, session, name_in ); + if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER && + ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_ALLOW) { + ld->ld_errno = tls_imp->ti_session_chkhost( ld, session, name_in ); + if (ld->ld_errno != LDAP_SUCCESS) { + return ld->ld_errno; + } + } + + return LDAP_SUCCESS; } int @@ -831,25 +843,11 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv ) /* * Fortunately, the lib uses blocking io... */ - if ( ldap_int_tls_connect( ld, conn ) < 0 ) { + if ( ldap_int_tls_connect( ld, conn, host ) < 0 ) { ld->ld_errno = LDAP_CONNECT_ERROR; return (ld->ld_errno); } - ssl = ldap_pvt_tls_sb_ctx( sb ); - assert( ssl != NULL ); - - /* - * compare host with name(s) in certificate - */ - if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER && - ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_ALLOW) { - ld->ld_errno = ldap_pvt_tls_check_hostname( ld, ssl, host ); - if (ld->ld_errno != LDAP_SUCCESS) { - return ld->ld_errno; - } - } - return LDAP_SUCCESS; } -- 1.7.11.4