123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- 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;
- }
-
|