0
string username = "username";
var con = new LdapConnection(new LdapDirectoryIdentifier(ADUtilities.LDAPServer, Convert.ToInt32(ADUtilities.LDAPPort), false, false));
con.SessionOptions.SecureSocketLayer = true;
con.SessionOptions.ProtocolVersion = 3;
var clientCertificateFile = new X509Certificate();
clientCertificateFile.Import(ADUtilities.LDAPSSLCertificatePath);
con.ClientCertificates.Add(clientCertificateFile);
con.SessionOptions.VerifyServerCertificate = new VerifyServerCertificateCallback(VerifyServerCertificate); }

con.Credential = new NetworkCredential(username, ADPassword);
con.AuthType = AuthType.Negotiate;
con.Timeout = new TimeSpan(0, 1, 0);
con.Bind();
private bool VerifyServerCertificate(LdapConnection ldapConnection, X509Certificate certificate) {
    X509Certificate2 certificate2 = new X509Certificate2(certificate);
    return certificate2.Verify();
}

Error is coming in the line con.bind() that LDAP server is not available. Same code is working fine with port 389 but not with 636 i.e. LDAPS

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
tanuj shrivastava
  • 722
  • 3
  • 9
  • 21
  • The 636 is using TLS/SSL for encryption with certificate while 389 is not using certificate. There are many versions of TLS so maybe the server is using TLS Mode. See : https://en.wikipedia.org/wiki/Transport_Layer_Security. The Port number 636 could also be blocked. – jdweng Feb 19 '20 at 10:32
  • @jdweng - I also found one important thing, in the code line: con.SessionOptions.SecureSocketLayer = true; It is not setting to true, the value is kept "false" in anyway. Also, I tried connecting using ADExplorer the LDAP is connecting over port 636 easily but not with my dotnet code. – tanuj shrivastava Feb 19 '20 at 11:44
  • The non secure 389 service may not be looking at the SessionOptions.SecureSocketLayer = true; – jdweng Feb 19 '20 at 11:49
  • But I am not having problem over 389 port, I'm having issue with LDAP over 636. For this to work SessionOptions.SecureSocketLayer = true; must be valid. Is there any way to investigate deeper instead of getting generic error "LDAP server is not operational" – tanuj shrivastava Feb 19 '20 at 11:54
  • I do not know the internals of the Net Library for this method to know how the option "SessionOptions.SecureSocketLayer = true;" is used. Nor do I know the service options. One way of debugging is to use a sniffer like wireshark or fiddler and check the response and see what the status being returned. The Net Library is not forwarding the status number and instead is giving a generic error message which is not helping. If the TLS is not succeeding, I would expect the connection to close. – jdweng Feb 19 '20 at 12:00
  • What is your `VerifyServerCertificate` method doing? – Gabriel Luci Feb 19 '20 at 12:52
  • Any reason you're using `LdapConnection` instead of `DirectoryEntry`/`DirectorySearcher`? – Gabriel Luci Feb 19 '20 at 12:54
  • @GabrielLuci - I have to import self signed certificate manually to verify with LDAP server for establishing the connection. I tried with DirectoryEntry class but I did not find out any way to validate certificate. My VerifyServerCertificate() method is as below:- `private bool VerifyServerCertificate(LdapConnection ldapConnection, X509Certificate certificate) { X509Certificate2 certificate2 = new X509Certificate2(certificate); return certificate2.Verify(); }` This is my callback method to LDAPConnection bind – tanuj shrivastava Feb 19 '20 at 13:40
  • @tanujshrivastava Thanks. I updated your question with that code. Have you set a breakpoint at `certificate2.Verify()` to see what the result of that is? Is it returning `false`? – Gabriel Luci Feb 19 '20 at 13:49
  • con.Bind() invokes the callback method VerifyServerCertificate(). But before reaching this method error is thrown at con.Bind() only and this method is not called. I have tried the above piece of code with some open source LDAP server with SSL and it works fine. I'm not sure username has to be in this format 'uid=username,ou=account,dc=aeu,dc=edu' or simply 'username' while passing in network credentials. – tanuj shrivastava Feb 19 '20 at 14:01
  • If `VerifyServerCertificate()` is not being called, then the connection isn't being opened properly. The very first thing that should happen (even before authentication) is the SSL handshake, which includes verifying the certificate. – Gabriel Luci Feb 19 '20 at 16:40
  • 1
    Use [this PowerShell code](https://stackoverflow.com/a/22251597/1202807) to download the certificate that the server is sending. Use `https://example.com:636` as the URL (where `example.com` is your domain name). It will save the certificate as a .cer file that you can just double-click on and inspect. – Gabriel Luci Feb 19 '20 at 16:43
  • @GabrielLuci thanks for this. I am able to get the certificate from the LDAPS server. But I'm confused about one thing that whether it is mandatory to keep certificate on client machine which is accessing the LDAPS server through dotnet application. When I moved this certificate to Trusted root certificate store of client machine the error 'LDAP server is not available' got resolved. – tanuj shrivastava Feb 20 '20 at 10:46
  • Interesting. I'm still confused why your `VerifyServerCertificate` method didn't run. Maybe the issue was that you're setting `ClientCertificates` too. That's not normally required. But also, `VerifyServerCertificate()` is just calling `Verify()`, which is basically no different than what it would do by default, meaning that the root certificate would need to be in the certificate store of the machine. – Gabriel Luci Feb 20 '20 at 13:36
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/208205/discussion-between-tanuj-shrivastava-and-gabriel-luci). – tanuj shrivastava Feb 20 '20 at 18:34
  • I'm still getting error at client side that LDAP server is unavailable. I'm also concerned that network credentials can also play important part here. For other ldap servers uid is present and I'm using username as this format "uid=uidname,ou=users,dc=example,dc=com" and password, but in case of client's LDAP server the uid is not present, they are using SAMAccountName. How can I format username using SAMAccountName And does simple username doesn't work in case of port 636 – tanuj shrivastava Feb 24 '20 at 06:11

0 Answers0