From: Ondřej Kuzník Date: Mon, 21 Oct 2024 10:50:11 +0000 (+0100) Subject: ITS#8047 Fix TLS connection timeout handling X-Git-Url: http://git.ipfire.org/gitweb/gitweb.cgi?a=commitdiff_plain;h=d143f7a2dc82fb66e7741b93a1ae9e874ce2ac46;p=thirdparty%2Fopenldap.git ITS#8047 Fix TLS connection timeout handling 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. --- diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index 3ef17643b1..7e754775e8 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -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. */ diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c index 18950c7050..0841005a59 100644 --- a/libraries/libldap/tls2.c +++ b/libraries/libldap/tls2.c @@ -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;