Reputation: 337
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
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
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:
Install wget(If it is not installed):
Download the latest version using wget:
Decompress the file:
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