705b2a5032
Resolves: #917603 #872784
93 lines
3.0 KiB
Diff
93 lines
3.0 KiB
Diff
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 <jvcelak@redhat.com>
|
|
Upstream ITS: #7373
|
|
Resolves: #852476
|
|
|
|
diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
|
|
index 10b993b..a3cd590 100644
|
|
--- a/libraries/libldap/tls2.c
|
|
+++ b/libraries/libldap/tls2.c
|
|
@@ -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;
|
|
}
|
|
|