inejge / ldap3

A pure-Rust LDAP library using the Tokio stack
Apache License 2.0
220 stars 38 forks source link

Issue with LDAPS #75

Closed cbass27 closed 2 years ago

cbass27 commented 2 years ago

I'm able to simple bind and search using LDAP but LDAPS fails. I tried both nativetls and rustls which fail. I don't have the errors in front of me currently but can get those if needed. But from what I recall I was seeing an error referencing protocol. I also tested by using the openldap crate and LDAPS works as expected using that. The openldap crate examples show passing options for the protocol version so I'm wondering if there's a way to pass the protocol version using this LDAP3 crate?

inejge commented 2 years ago

I can't say much without detailed error messages. If the problem is with the TLS negotiation, packet traces would also help. What are the platform and version of the LDAP server? What does the connection code look like?

LDAP protocol version is hardcoded to 3 in this crate and can't be changed.

cbass27 commented 2 years ago

I was only able to do a tcpdump from the client as I don't have access to the server. I need to remove company information from the pcap's before uploading here but at a quick glance when comparing the pcap from an unsuccessful connection using LDAP3 crate and a successful connection using the openldap crate, this LDAP3 crate connection seems to be missing the key exchange. For my testing I received the client certificate from my LDAP admin which I copied to /etc/ssl/certs/my-domain-ca.pem.

I modified /etc/ldap/ldap.conf: TLS_REQCERT demand TLS_CACERT /etc/ssl/certs/my-domain-ca.pem

Here's the LDAP server info and I can provide more info if needed: OS: Linux vendorVersion: LDAP Agent for NetIQ eDirectory 8.8 SP8 (20801.42) supporedLDAPVersion: 2/3 supporedSASLMechanisms: NMAS_LOGIN supporedSASLMechanisms: SAML

Connection code is minimal: Cargo.toml: [dependencies.ldap3] version= "0.9.3"

main.rs: let conn_duration = Duration::new(15,0); let (conn, mut ldap) = LdapConnAsync::with_settings( LdapConnSettings::new() .set_no_tls_verify(true) .set_conn_timeout(conn_duration), "ldaps://ldapserver.somedomain.com", ).await?; ldap3::drive!(conn); let _res = ldap.simple_bind("cn=myusername,ou=employees,ou=users,dc=mydomain,dc=com", "mysecretpassword") .await?.success()?; ldap.unbind()...

The error I receive is: Error: NativeTLS { source: Ssl(Error { code: ErrorCode(1), cause: Some(Ssl(ErrorStack([Error { code: 338030850, library: "SSL routines", function: "ssl_choose_client_version", reason: "unsupported protocol", file: "../ssl/statem/statem_lib.c", line: 1941 }]))) }, X509VerifyResult { code: 0, error: "ok" }) }

Second test. Cargo.toml: [dependencies.ldap3] version= "0.9.3" default-features = false features = [ "tls-rustls" ]

main.rs same as above.

Error I receive: Error: Io { source: Custom { kind: InvalidData, error: AlertReceived(HandshakeFailure) } }

Basic connectivity testing: nc -vz ldapserver.somedomain.com 636 Connection to ldapserver.somedomain.com 636 port [tcp/ldaps] succeeded!

echo | openssl s_client -showcerts -connect ldapserver.somedomain.com:636 CONNECTED(00000003) 140622757295424:error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol:../ssl/statem/statem_lib.c:1941:

no peer certificate available

No client certificate CA names sent

SSL handshake has read 79 bytes and written 326 bytes Verification: OK

New, (NONE), Cipher is (NONE) Secure Renegotiation IS NOT supported Compression: NONE Expansion: NONE No ALPN negotiated Early data was not sent Verify return code: 0 (ok)

I'm not sure if this URL helps but I'm providing it just in case. https://www.novell.com/documentation/developer/ldapover/ldap_enu/data/a3wzcl0.html

Thanks in advance for your help.

inejge commented 2 years ago

The s_connect output (thanks for supplying that, it's quite illuminating) contains exactly the same error as the native-tls attempt, down to line number, but it appears that s_connect ignores the error and the connection proceeds in the clear, whereas native-tls bails out.

I suppose that the reason for the TLS negotiation failure could be inferred from the ServerHello packet in the protocol exchange. Whatever it is, I'd consider it the result of server misconfiguration; the server shouldn't disallow connections from an up-to-date TLS library, which both native-tls and rustls are.

If changing the server is impractical, you could try connecting with a custom TlsConnector in LdapConnSettings, set up to ignore TLS negotiation failures. This can only work with native-tls.

cbass27 commented 2 years ago

Thanks for your reply. I was afraid of a server misconfiguration as it's not uncommon in my company. :( But unfortunately I don't think I'll be able to do much about the server config myself. I'm not much of a LDAP guy so could you let me know what I could suggest to our LDAP admin to look at on his side? Does he just need to upgrade the LDAP server itself?

Regarding the TlsConnector, I saw that but wasn't sure how to configure or use it in Rust. Do you have any suggestions or sample code you could give me? I really appreciate your help with all this.

inejge commented 2 years ago

what I could suggest to our LDAP admin to look at on his side?

Let's see the packet trace first.

Regarding the TlsConnector, I saw that but wasn't sure how to configure or use it in Rust. Do you have any suggestions or sample code you could give me?

I did have some old code which turned off cert verification, but it doesn't work with the present version of native-tls. Generally, you can use TlsConnector::builder() to create a TlsConnectorBuilder, then play with its options and call build() when you're done. Place the resulting TlsConnector in LdapConnSettings and create the LDAP connection using with_settings().

cbass27 commented 2 years ago

I was able to make a LDAPS connection using the TlsConnector per your suggestion. Thank you for that. Unfortunately I can only connect successfully using the "danger_accept_invalid_certs(true)" setting which of course is not ideal. I'm awaiting a response from our LDAP admin and confirmation that we are using the correct certificate but other then that, is there anything else you would suggest looking at? Thanks again for your help.

inejge commented 2 years ago

is there anything else you would suggest looking at?

I'm still curious to see the packet trace of an unsuccessful connection attempt, if you have it at hand. Otherwise, I'd suggest closing this issue since it doesn't appear that the problem is with the library itself, and a workaround is available.

inejge commented 2 years ago

As noted in the previous message, this is a usage issue. Also, without further feedback, I can't speculate about the causes of connection errors. I'm closing this; if there are further developments, the issue can be reopened.

cbass27 commented 2 years ago

@inejge Yeah sorry I didn't get back to you. I haven't been able to get the packet trace and since I got it working it got pushed to the back. Thanks again for your support and great work on this crate.