]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#8980 fix async connections with non-blocking TLS
authorVernon Smith <vsmith@interlinknetworks.com>
Tue, 19 Feb 2019 05:57:00 +0000 (05:57 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 28 Feb 2019 17:02:40 +0000 (17:02 +0000)
libraries/libldap/os-ip.c
libraries/libldap/tls2.c
libraries/libldap/tls_o.c

index 76d21fae63a979298e8d3d0e60aabd26ba99a25d..8f6ff93f69b03d53a21a5a570600f14da0f0f2e2 100644 (file)
@@ -431,7 +431,7 @@ ldap_pvt_connect(LDAP *ld, ber_socket_t s,
                if ( connect(s, sin, addrlen) != AC_SOCKET_ERROR ) {
                        Debug0(LDAP_DEBUG_TRACE, "connect success\n" );
 
-                       if ( opt_tv && ldap_pvt_ndelay_off(ld, s) == -1 )
+                       if ( !async && opt_tv && ldap_pvt_ndelay_off(ld, s) == -1 )
                                return ( -1 );
                        return ( 0 );
                }
index 869de2eb50920e1498063543f682da27c2531bd1..b887e7fecdb3fae783b601c6a3011950f7a5932a 100644 (file)
@@ -1050,7 +1050,7 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
        Sockbuf *sb;
        char *host;
        void *ssl;
-       int ret;
+       int ret, async;
 #ifdef LDAP_USE_NON_BLOCKING_TLS
        struct timeval start_time_tv, tv, tv0;
        ber_socket_t    sd = AC_SOCKET_ERROR;
@@ -1077,8 +1077,12 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
        /*
         * Use non-blocking io during SSL Handshake when a timeout is configured
         */
+       async = LDAP_BOOL_GET( &ld->ld_options, LDAP_BOOL_CONNECT_ASYNC );
        if ( ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
-               ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)1 );
+               if ( !async ) {
+                       /* if async, this has already been set */
+                       ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)1 );
+               }
                ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
                tv = ld->ld_options.ldo_tm_net;
                tv0 = tv;
@@ -1112,8 +1116,10 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
                        ld->ld_errno = LDAP_TIMEOUT;
                        break;
                } else {
-                       /* ldap_int_poll called ldap_pvt_ndelay_off */
-                       ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)1 );
+                       /* ldap_int_poll called ldap_pvt_ndelay_off if not async */
+                       if ( !async ) {
+                               ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)1 );
+                       }
                        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;
@@ -1160,7 +1166,8 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
                        }
                }
        }
-       if ( ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
+       /* Leave it nonblocking if async */
+       if ( !async && ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
                ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, NULL );
        }
 #endif /* LDAP_USE_NON_BLOCKING_TLS */
index 1f26a3deeda6365662ff2d7fd9d5b3df75b7dca3..de01465036d89764d3e63c3ea092c86712b89679 100644 (file)
@@ -529,7 +529,19 @@ tlso_session_connect( LDAP *ld, tls_session *sess )
        tlso_session *s = (tlso_session *)sess;
 
        /* Caller expects 0 = success, OpenSSL returns 1 = success */
-       return SSL_connect( s ) - 1;
+       int rc = SSL_connect( s ) - 1;
+#ifdef LDAP_USE_NON_BLOCKING_TLS
+       if ( rc < 0 ) {
+               int sockerr = sock_errno();
+               int sslerr = SSL_get_error( s, rc+1 );
+               if ( sslerr == SSL_ERROR_WANT_READ || sslerr == SSL_ERROR_WANT_WRITE ) {
+                       rc = 0;
+               } else if ( sslerr == SSL_ERROR_SYSCALL &&
+                       ( sockerr == EAGAIN || sockerr == ENOTCONN )) {
+                       rc = 0;
+               }
+       }
+#endif /* LDAP_USE_NON_BLOCKING_TLS */
 }
 
 static int