[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: (ITS#4940) libldap doesn't wait for server's TLS close_notify

guenther+ldapdev@sendmail.com wrote:
> Full_Name: Philip Guenther
> Version: 2.3.27
> OS: Linux and Solaris
> URL: ftp://ftp.openldap.org/incoming/
> Submission from: (NULL) (
> [I vaguely recall seeing a report of this issue in the archives of one of the
> mailing lists, but I can no longer find the original.]
> If you trace the packets sent when you use, for example, ldapsearch against a
> server on a different host, using either the -Z option to do TLS or using an
> ldaps URI, you'll discover that the TCP connection is actually reset instead of
> being closed cleanly: the client sends TCP RSTs in response to the server's
> final packets.
> This is because libldap uses the following sequence when unbind a TLS or SSL
> connection:
> 1) send the unbind request (over the TLS or SSL layer)
> 2) call SSL_shutdown(), sending the TLS close_notify alert
> 3) call close()
> After receiving the close_notify alert from step (2), the server sends back its
> own close_notify alert and then calls close().  However, because the client
> didn't wait for the server's response before calling close() on its end, the
> client's TCP stack considers the TCP connection to already be gone and responds
> with the RST packets.  This occurs with Linux and Solaris clients and probably
> most other unices: the response to packets after a close() doesn't vary in my
> experience.
> There are a number of ways this can be handled:
> 1) change the client to wait until it sees the server's close_notify alert by
>    replacing "SSL_shutdown( p->ssl );" in tls.c with the two lines:
>         if (SSL_shutdown( p->ssl ) == 0)
>             SSL_shutdown( p->ssl );
>    (I have confirmed that this works.  As documented, the first call will return
> 1
>    if the server's close_notify has already been received, if not, the second
> call
>    will block until it is received.)

So if the server doesn't send one, the client will be stuck waiting forever?

> 2) change the client to not bother to send a close_notify alert when it's just
>    going to close() the connection; change the server to not send a
> close_notify
>    if it didn't get one.  This probably violates the TLS spec, but the fact
> that
>    TLS/1.1 permits resumption of sessions without close_notify having been sent
>    indicates that the violation is not a major issue, particularly given that
> LDAP's
>    unbind request prevents truncation attacks.  Close_notifies are, of course,
>    required if the client just wants to terminate the TLS layer and resume
>    unprotected LDAP operations.

Sounds like a change in the SSL library, not something for us to worry about.
> 3) ignore the issue: it only causes one or two extra packets to be sent.  While
> it
>    also eliminates the TIME_WAIT state, LDAP's application-level close (the
> unbind
>    request) means it doesn't need reliable full-duplex closure, so the only
> concern
>    would be random connection issues from reincarnations of the TCP tuple,
> which
>    is unlikely for an LDAP connection.

> Personally, I like the simplicity and cleanliness of solution (1).

(1) has the possibility of an indefinite hang. As such, I think it best to 
leave it with the current behavior.
   -- Howard Chu
   Chief Architect, Symas Corp.  http://www.symas.com
   Director, Highland Sun        http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP     http://www.openldap.org/project/