Blame SOURCES/openldap-tls-no-reuse-of-tls_session.patch

767ab2
TLS: do not reuse tls_session if hostname check fails
767ab2
767ab2
If multiple servers are specified, the connection to the first one succeeds, and the hostname verification fails,
767ab2
*tls_session is not dropped, but reused when connecting to the second server.
767ab2
767ab2
This is a problem with Mozilla NSS backend because another handshake cannot be performed on the same file descriptor.
767ab2
From this reason, hostname checking was moved into ldap_int_tls_connect() before connection error handling.
767ab2
767ab2
Author: Jan Vcelak <jvcelak@redhat.com>
767ab2
Upstream ITS: #7373
767ab2
Resolves: #852476 
767ab2
767ab2
diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
767ab2
index 10b993b..a3cd590 100644
767ab2
--- a/libraries/libldap/tls2.c
767ab2
+++ b/libraries/libldap/tls2.c
767ab2
@@ -320,7 +320,7 @@ update_flags( Sockbuf *sb, tls_session * ssl, int rc )
767ab2
  */
767ab2
 
767ab2
 static int
767ab2
-ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
767ab2
+ldap_int_tls_connect( LDAP *ld, LDAPConn *conn, const char *host )
767ab2
 {
767ab2
 	Sockbuf *sb = conn->lconn_sb;
767ab2
 	int	err;
767ab2
@@ -365,6 +365,10 @@ ldap_int_tls_connect( LDAP *ld, LDAPConn *conn )
767ab2
 	errno = WSAGetLastError();
767ab2
 #endif
767ab2
 
767ab2
+	if ( err == 0 ) {
767ab2
+		err = ldap_pvt_tls_check_hostname( ld, ssl, host );
767ab2
+	}
767ab2
+
767ab2
 	if ( err < 0 )
767ab2
 	{
767ab2
 		char buf[256], *msg;
767ab2
@@ -495,7 +499,15 @@ ldap_pvt_tls_check_hostname( LDAP *ld, void *s, const char *name_in )
767ab2
 {
767ab2
 	tls_session *session = s;
767ab2
 
767ab2
-	return tls_imp->ti_session_chkhost( ld, session, name_in );
767ab2
+	if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER &&
767ab2
+	    ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_ALLOW) {
767ab2
+		ld->ld_errno = tls_imp->ti_session_chkhost( ld, session, name_in );
767ab2
+		if (ld->ld_errno != LDAP_SUCCESS) {
767ab2
+			return ld->ld_errno;
767ab2
+		}
767ab2
+	}
767ab2
+
767ab2
+	return LDAP_SUCCESS;
767ab2
 }
767ab2
 
767ab2
 int
767ab2
@@ -857,7 +869,7 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
767ab2
 #endif /* LDAP_USE_NON_BLOCKING_TLS */
767ab2
 
767ab2
 	ld->ld_errno = LDAP_SUCCESS;
767ab2
-	ret = ldap_int_tls_connect( ld, conn );
767ab2
+	ret = ldap_int_tls_connect( ld, conn, host );
767ab2
 
767ab2
 #ifdef LDAP_USE_NON_BLOCKING_TLS
767ab2
 	while ( ret > 0 ) { /* this should only happen for non-blocking io */
767ab2
@@ -878,7 +890,7 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
767ab2
 		} else {
767ab2
 			/* ldap_int_poll called ldap_pvt_ndelay_off */
767ab2
 			ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_SET_NONBLOCK, sb );
767ab2
-			ret = ldap_int_tls_connect( ld, conn );
767ab2
+			ret = ldap_int_tls_connect( ld, conn, host );
767ab2
 			if ( ret > 0 ) { /* need to call tls_connect once more */
767ab2
 				struct timeval curr_time_tv, delta_tv;
767ab2
 
767ab2
@@ -935,20 +947,6 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
767ab2
 		return (ld->ld_errno);
767ab2
 	}
767ab2
 
767ab2
-	ssl = ldap_pvt_tls_sb_ctx( sb );
767ab2
-	assert( ssl != NULL );
767ab2
-
767ab2
-	/* 
767ab2
-	 * compare host with name(s) in certificate
767ab2
-	 */
767ab2
-	if (ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_NEVER &&
767ab2
-	    ld->ld_options.ldo_tls_require_cert != LDAP_OPT_X_TLS_ALLOW) {
767ab2
-		ld->ld_errno = ldap_pvt_tls_check_hostname( ld, ssl, host );
767ab2
-		if (ld->ld_errno != LDAP_SUCCESS) {
767ab2
-			return ld->ld_errno;
767ab2
-		}
767ab2
-	}
767ab2
-
767ab2
 	return LDAP_SUCCESS;
767ab2
 }
767ab2