pingidentity / ldapsdk

UnboundID LDAP SDK for Java
Other
327 stars 79 forks source link

NullPointerException InternalSDKHelper for StartTLS connection #117

Open sherry442 opened 2 years ago

sherry442 commented 2 years ago

Hi, While starting TLS connection with this framework, we have encountered the NPE.
First try failed with below reason:

StartTLS error.ResultCode= 82 (local error) message= The connection reader was unable to successfully complete TLS negotiation: SocketException(Broken pipe (Write failed)),**** ldapSDKVersion=5.1.3, revision=028e004da97e22a274a4116316a73d0a90526e4b cause=java.net.SocketException: Broken pipe (Write failed)

Retry also failed: ThreadID:32 - StartTLS error.ResultCode= 82 (local error) message= An error occurred while attempting to set the value of the SO_TIMEOUT socket option for connection LDAPConnection(not connected) to 50ms: NullPointerException(setSoTimeout(InternalSDKHelper.java:159) / doStartTLS(LDAPConnectionReader.java:1008) / convertToTLS(LDAPConnectionInternals.java:431) / convertToTLS(LDAPConnection.java:1100) / convertToTLS(InternalSDKHelper.java:195) / process(StartTLSExtendedRequest.java:343) / processExtendedOperation(LDAPConnection.java:2852) / startTLSRequest(LdapStorage.java:136) / makeLdapConnectionBasedOnMtlsFlag(LdapStorage.java:103) / reconnectWithAction(LdapStorage.java:261) / ...), ldapSDKVersion=5.1.3, revision=028e004da97e22a274a4116316a73d0a90526e4b cause=java.lang.NullPointerException

This is sporadic issue. Could you please help us here?

dirmgr commented 2 years ago

The first failure probably indicates that the connection was closed by the server during the course of TLS negotiation. In particular, "Broken pipe (Write failed)" indicates that the client tried to send data to the server but found that the connection was no longer valid. I've been able to reproduce this in a test environment by configuring a directory server to the client to present its own certificate during TLS negotiation, and not providing the client with access to a key store so that it can obtain any client certificate. I expect that there would also be a similar failure if the client did present a certificate that the server didn't trust, but I haven't tested that. There may also be other reasons that the server could close a connection during TLS negotiation (for example, if the server isn't willing to use any of the protocol versions or cipher suites that the client listed in its hello request). The cause of that failure is ultimately something that you'll need to investigate on the server side because the client doesn't have access to the reason that the server chose to close the connection.

The second failure occurred because the client attempted to send a request on a connection that was not established. This one is weird because you should get a different error response. In my testing after reproducing the "broken pipe" exception as described above, I always get a server down result (result code 81) with a message of "The connection is not established.". This is generated by the LDAP SDK itself because it doesn't even attempt to send a request to the server. I haven't been able to reproduce the NullPointerException that you're reporting, although you might find that it's fixed if you test with the 6.0.0 release of the LDAP SDK because there was a race condition fixed in LDAPConnectionInternals between the 5.1.3 and 6.0.0 releases, and it comes into play when trying to send a request on a connection that isn't valid.

However, you should not attempt to do anything on a connection after a StartTLS failure. For security reasons, any time a StartTLS attempt fails, the LDAP SDK will intentionally close the connection so that it's not possible to inadvertently proceed on an insecure connection. If a StartTLS attempt fails, then you will need to discard that connection and try establishing a new one (or at least call connect on the connection to try to re-establish it).