sosNiLa
sosNiLa

Reputation: 337

EWS api - Unable to connect ExchangeServer on-prem

I am implementing the Microsoft EWS api in order to get emails from the on-prem Exchange Server. Considering that the Microsoft has abandoned the development, I am using the sherlock1982 fork from ews api. My app is written in .net core 2.1 and when running on my local PC (win10), everything is working well. Considering that its a Linux, it is not possible to automatically get the Autodiscover url, so I am manually setting it in the code, as suggested on the github page.

public async void GetInbox()
        {
            string ewsUrl = "https://mail.domain.com/EWS/Exchange.asmx";

            try
            {
                var service = new ExchangeService(ExchangeVersion.Exchange2013_SP1);

                service.UseDefaultCredentials = false;
                // service.Credentials = new NetworkCredential("domainUsername", "password", "domain");
                service.Url = new Uri(ewsUrl);

                Mailbox mb = new Mailbox("emailAddress");

                var cache = new System.Net.CredentialCache();
                cache.Add(service.Url, "NTLM", new 
                System.Net.NetworkCredential("domainUsername", "password", 
                "domain"));
                service.Credentials = cache;

                FolderId fid = new FolderId(WellKnownFolderName.Inbox, mb);

                Folder inbox = await Folder.Bind(service, fid);
                if (inbox != null)
                {
                    _database.LogEvent("LOG", "GetInbox", $"InboxCount: {inbox.TotalCount}");
                }
            }
            catch (Exception e)
            {
                _database.LogEvent("Error", "GetInbox", $"{e.Message}");
            }

        }

When deployed to the test server running CentOS7, I am getting following message:

The request failed. The SSL connection could not be established, see inner exception.

   at Microsoft.Exchange.WebServices.Data.EwsHttpWebRequest.GetResponse(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\EwsHttpWebRequest.cs:line 147
   at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 798
   --- End of inner exception stack trace ---
   at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 808
   at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\ServiceRequestBase.cs:line 688
   at Microsoft.Exchange.WebServices.Data.SimpleServiceRequestBase.InternalExecuteAsync(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\SimpleServiceRequestBase.cs:line 57
   at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.ExecuteAsync(CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\Requests\MultiResponseServiceRequest.cs:line 134
   at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder(FolderId folderId, PropertySet propertySet, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\ExchangeService.cs:line 325
   at Microsoft.Exchange.WebServices.Data.ExchangeService.BindToFolder[TFolder](FolderId folderId, PropertySet propertySet, CancellationToken token) in D:\dev_in_progress\ews-managed-api-master\Core\ExchangeService.cs:line 345
   at ExchangeFiles.Email.Download_PI_Files_Email() in D:\dev_in_progress\get_emails_v1\ExchangeFiles\Email.cs:line 199 

I have tried ignoring the certificate with ServicePointManager .ServerCertificateValidationCallback += (sender, cert, chain, sslPolicyErrors) => true;

but without luck (I am getting the same error).

UPDATE: I have added a following piece of code

                ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) =>
                {
                    if (cert.GetCertHashString().ToLower() == "someHashCert")
                    {
                       return true;
                    }

                    if (sslPolicyErrors == SslPolicyErrors.None)
                    {
                      
                        return true;   //Is valid
                    }

                    return false;
                }

inside the code for creating HttpClientHandler. Its entering inside the if "cert.GetCertHashString().ToLower()" which is good. I have copied the value of someHashCert from the browser. I also tried setting the

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", false);

But error with this code (and above when checking the cert) is: The request failed. The handler does not support custom handling of certificates with this combination of libcurl (7.29.0) and its SSL backend ("NSS/3.44"). An SSL backend based on "OpenSSL/1.0.2k-fips" is required. Consider using System.Net.Http.SocketsHttpHandler.

If I set

AppContext.SetSwitch("System.Net.Http.UseSocketsHttpHandler", true);

I am getting: The request failed. GSSAPI operation failed with error - An unsupported mechanism was requested (Unknown error).

I have also tried to setup the callback for certificate from MS doc cert for ews api but then I am getting "Unable to get local issuer certificate" msg.

Not sure is this is step forward or backward... I have a feeling that I have tried everything...

UPDATE2 The ExchangeSever version is 2016, its using NTLM authentification and TLS1.0/1.1

I tried curl -v -k -i --anyauth -u : mail.server.domain:443 and it says

* About to connect() to mail.server.domain: port 443 (#0)
*   Trying xx.xx.xx.xxx...
* Connected to mail.server.domain (xx.xx.xx.xxx) port 443 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: mail.server.domain::443
> Accept: */*

Any idea is welcome... Thanks

Upvotes: 0

Views: 3463

Answers (2)

sosNiLa
sosNiLa

Reputation: 337

Unfortunately, nothing suggested from here worked.

I found some comment about similar issue on github and how updating the project to .NET core 3.1 fixed the error, so I decided to give it a try...

It was not a small work, I had several projects inside the solution, but I can confirm that after updating from .NET core 2.1 to .NET core 3.1, everything is working as it should.

Upvotes: 1

Jin Thakur
Jin Thakur

Reputation: 2773

Update your TLS on Cent OS. TLSv1.2 should be available on CentOS 7.

Some documentation.

Linux OpenSSL 1.1.1 supports TLS v1.3 in different Linux OS.

RHEL 8 - Red Hat Enterprise Linux 8 is the first Enterprise Linux distribution that ships with the TLS v1.3 protocol fully integrated into the operating system.

Older CentOS and RHEL OS versions have OpenSSL v1.0.2 installed by default, so TLS v1.3 is not supported natively. OpenSSL can be yum updated to OpenSSL v1.1.1 to support TLS v1.3.

Blockquote

How to install OpenSSL v1.1.1 on CentOS RedHat Linux: Use the OpenSSL Version Command to verify the OpenSSL Version:

openssl version

Install wget(If it is not installed):

yum install wget

Download the latest version using wget:

wget https://ftp.openssl.org/source/old/1.1.1/openssl-1.1.1.tar.gz

Decompress the file:

tar xvf openssl-1.1.1.tar.gz

Further configuration is necessary, Please consult your System Administrators prior to making any changes.

disabled by default system wide. If you enable TLS v1.3 on a system for testing, then

TLS should be supported by OS and .net framework. Check OS and upgrade it if it does not support TLS 1.2 then use Right .net framework which supports TLS 1.2 /1.3 Install Self signed cert on Cent OS also.

Will TLS 1.3 be supported on .NET?

For .NET, the official guidance at this point (via the best practices page above) is to rely on the underlying OS to provide the TLS version (which will automatically default to the strongest available version of the TLS protocol), and avoid hardcoding/specifying an explicit TLS version in application code.

Starting with .NET Framework 4.7, the default configuration is to use the OS TLS version.

Other links which may be helpful: https://github.com/dotnet/docs/issues/4675 and https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls

Upvotes: 0

Related Questions