]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
ITS#8047 Fix TLS connection timeout handling
authorOndřej Kuzník <ondra@mistotebe.net>
Mon, 21 Oct 2024 10:50:11 +0000 (11:50 +0100)
committerQuanah Gibson-Mount <quanah@openldap.org>
Sat, 26 Oct 2024 20:51:35 +0000 (20:51 +0000)
The test for async in ldap_int_tls_start was inverted, we already
support calling ldap_int_tls_connect repeatedly. And so long as
LBER_SB_OPT_NEEDS_* are managed correctly, the application should be
able to do the right thing.

Might require a new result code rather than reporposing
LDAP_X_CONNECTING for this.

libraries/libldap/ldap-int.h
libraries/libldap/tls2.c

index 3ef17643b18742618c7d85c462d34c21c4726490..7e754775e8f45b30f9201698f6f104c565aef555 100644 (file)
@@ -368,6 +368,7 @@ typedef struct ldap_conn {
 #define LDAP_CONNST_NEEDSOCKET         1
 #define LDAP_CONNST_CONNECTING         2
 #define LDAP_CONNST_CONNECTED          3
+#define LDAP_CONNST_TLS_INPROGRESS     4
        LDAPURLDesc             *lconn_server;
        BerElement              *lconn_ber;     /* ber receiving on this conn. */
 
index 18950c70506db02ff4519f659154889f834ae71d..0841005a599659637cbb67492fd97db9a93efec9 100644 (file)
@@ -383,6 +383,7 @@ ldap_int_tls_connect( LDAP *ld, LDAPConn *conn, const char *host )
                if ( lo && lo->ldo_tls_connect_cb && lo->ldo_tls_connect_cb !=
                        ld->ld_options.ldo_tls_connect_cb )
                        lo->ldo_tls_connect_cb( ld, ssl, ctx, lo->ldo_tls_connect_arg );
+               conn->lconn_status = LDAP_CONNST_TLS_INPROGRESS;
        }
 
        /* pass hostname for SNI, but only if it's an actual name
@@ -441,12 +442,14 @@ ldap_int_tls_connect( LDAP *ld, LDAPConn *conn, const char *host )
                ber_sockbuf_remove_io( sb, &ber_sockbuf_io_debug,
                        LBER_SBIOD_LEVEL_TRANSPORT );
 #endif
+               conn->lconn_status = LDAP_CONNST_CONNECTED;
                return -1;
        }
 
        Debug2( LDAP_DEBUG_CONNS, "TLS: session established tls_proto=%s tls_cipher=%s\n",
                ldap_pvt_tls_get_version( ssl ), ldap_pvt_tls_get_cipher( ssl ) );
 
+       conn->lconn_status = LDAP_CONNST_CONNECTED;
        return 0;
 }
 
@@ -519,8 +522,9 @@ int
 ldap_tls_inplace( LDAP *ld )
 {
        Sockbuf         *sb = NULL;
+       LDAPConn        *lc = ld->ld_defconn;
 
-       if ( ld->ld_defconn && ld->ld_defconn->lconn_sb ) {
+       if ( lc && lc->lconn_sb ) {
                sb = ld->ld_defconn->lconn_sb;
 
        } else if ( ld->ld_sb ) {
@@ -530,6 +534,10 @@ ldap_tls_inplace( LDAP *ld )
                return 0;
        }
 
+       if ( lc && lc->lconn_status == LDAP_CONNST_TLS_INPROGRESS ) {
+               return 0;
+       }
+
        return ldap_pvt_tls_inplace( sb );
 }
 
@@ -1162,6 +1170,9 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
          */
        while ( ret > 0 ) {
                if ( async ) {
+                       ld->ld_errno = LDAP_X_CONNECTING;
+                       return (ld->ld_errno);
+               } else {
                        struct timeval curr_time_tv, delta_tv;
                        int wr=0;
 
@@ -1220,6 +1231,11 @@ ldap_int_tls_start ( LDAP *ld, LDAPConn *conn, LDAPURLDesc *srv )
                ret = ldap_int_tls_connect( ld, conn, host );
        }
 
+       if ( !async && ld->ld_options.ldo_tm_net.tv_sec >= 0 ) {
+               /* Restore original sb status */
+               ber_sockbuf_ctrl( sb, LBER_SB_OPT_SET_NONBLOCK, (void*)0 );
+       }
+
        if ( ret < 0 ) {
                if ( ld->ld_errno == LDAP_SUCCESS )
                        ld->ld_errno = LDAP_CONNECT_ERROR;