Commit 73d48324 authored by Jan Vcelak's avatar Jan Vcelak Committed by Quanah Gibson-Mount
Browse files

ITS#7373 - 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.
parent 9733303d
......@@ -320,7 +320,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;
......@@ -365,6 +365,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;
......@@ -495,7 +499,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
......@@ -857,7 +869,7 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
#endif /* LDAP_USE_NON_BLOCKING_TLS */
ld->ld_errno = LDAP_SUCCESS;
ret = ldap_int_tls_connect( ld, conn );
ret = ldap_int_tls_connect( ld, conn, host );
#ifdef LDAP_USE_NON_BLOCKING_TLS
while ( ret > 0 ) { /* this should only happen for non-blocking io */
......@@ -878,7 +890,7 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
} else {
/* ldap_int_poll called ldap_pvt_ndelay_off */
ber_sockbuf_ctrl( ld->ld_sb, LBER_SB_OPT_SET_NONBLOCK, sb );
ret = ldap_int_tls_connect( ld, conn );
ret = ldap_int_tls_connect( ld, conn, host );
if ( ret > 0 ) { /* need to call tls_connect once more */
struct timeval curr_time_tv, delta_tv;
......@@ -935,20 +947,6 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
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;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment