@SidharthNabar Hey ... ran into an issue following the updates to System.Net.Sockets. Under 4.0.10-beta-*, I was using this to hit up a GoDaddy (yuck!) mail server ...
using (var client = new TcpClient(server, port))
{
using (var stream = new SslStream(client.GetStream(), false))
{
stream.AuthenticateAsClient(server);
... USE THE STREAM ...
... after the revision to System.Net.Sockets using 4.1.0-beta-*, I converted that over to ...
using (var client = new TcpClient())
{
await client.ConnectAsync(server, port);
using (var stream = new SslStream(client.GetStream(), true))
{
stream.AuthenticateAsClient(server);
... USE THE STREAM ...
... it runs locally (note that I had to change the leaveInnerStreamOpen to true to even get it to run on IIS Express), but it throws on the server ...
System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost)
at MyApp.ContactController.<Index>d__5.MoveNext()
If I immediately re-submit the form, it throws slightly differently ...
System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost)
at MyApp.ContactController.<Index>d__5.MoveNext()
Am I coding that change correctly?
Still troubleshooting this. Here's the stacktrace from the developer exception page when the app is run in the server environment.
System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost)
at MyApp.ContactController.<Index>d__5.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Controllers.ControllerActionExecutor.<CastToObject>d__8`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Controllers.ControllerActionInvoker.<InvokeActionAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeActionFilterAsync>d__53.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNet.Mvc.Controllers.FilterActionInvoker.<InvokeAsync>d__44.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Infrastructure.MvcRouteHandler.<RouteAsync>d__6.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Mvc.Routing.InnerAttributeRoute.<RouteAsync>d__10.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Routing.RouteCollection.<RouteAsync>d__9.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at Microsoft.AspNet.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__7.MoveNext()
Also note ... I have a much smaller test app with exactly the same code, and it runs both locally and on the server. I'm trying to untangle what the difference might be between the two apps. You might want to hold off looking at this until I can isolate why the small app works and the large app fails.
E.g., These two apps are on different VM's ... and with two different flavors of OS: WS2012 vs. WS2012R2. I want to move the small app to the 2012R2 VM and confirm it works there ... if it does, we factor out the diff in VM's. If it fails there, then there is something hokey with that VM or IIS.
I'll get back with an update this afternoon.
@CIPop - PTAL. I am not as familiar with the Sockets codebase.
@SidharthNabar Oh, sorry about that.
@davidsh Interesting ... It breaks on the WS2012R2 box but not on the WS2012 box.
[EDIT] Note that both servers are getting the same bits AFAIK. I'm publishing to the filesystem with VS Publish, then using MSDeploy to shoot the bits up to the VM's.
It's throwing on this line ...
stream.AuthenticateAsClient(server);
Unfortunately, I'm seeing a third version of the exception now (on this latest WS2012R2 test) ...
System.IO.IOException: Unable to read data from the transport connection: An established connection was aborted by the software in your host machine. ---> System.Net.Sockets.SocketException: An established connection was aborted by the software in your host machine
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost)
at PlatformIssue.ContactController.<Message>d__4.MoveNext()
Should I try to see what's going in and out on the wire? ... or is there a way I can drill down in managed code to see what's happening under the stream.AuthenticateAsClient(server); method? I don't do too much work in LOB dev with low-level socket stuff, so you may need to be specific about what and how to check things out.
Thanks for reporting this @GuardRex!
I've just finished work on removing System.Private.Networking which means that future packages flowing to MyGet will be containing binaries built from the GitHub source-code for Windows. I recommend retrying the scenario with these packages.
To gain some more insight in what is happening:
Schannel traces:
logman start schannel_trace -p "{37D2C3CD-C5D4-4587-8531-4696C44244C8}" 0x4000ffff -o schannel.etl -ets -ln schannel
Run the repro. Then stop and collect the trace:
logman stop schannel_trace -ets
Important: The traces may contain sensitive data (such as personal identifiable information). Please consider using test accounts if you are sharing the logs with us.
@CIPop Cool. Will do. Thanks for getting back so quickly. I was hoping to dig into it tomorrow AM, and now I have something fun to work on tomorrow morning. I'll get back to you with the results.
@CIPop I thought I'd give RC2 a shot dnx-coreclr-win-x64.1.0.0-rc2-16249 and -rc2-* packages in the hopes that your recent work would clear it up. No dice ...
System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost)
at PlatformIssue.ContactController.<Message>d__4.MoveNext()
... I'm moving to your instructions now to see if I can see a diff between the app in these two environments.
@GuardRex The System.Private.Networking.dll removal re-factoring work that @CIPop has mentioned is NOT yet in the binaries. Only the sources are present in GitHub.
It will a few days before the CoreFx repo MYGET dev feed has the newer RC2 binaries with these changes. And I'm not sure when the dnx* feed will contain those binaries since those feeds lag a few more days behind.
@davidsh Oh, ok, thanks.
I'm putting WireShark on those VM's now. Hopefully, something interesting will turn up.
@CIPop Ok, so right off the bat I can see the connection getting reset. The top is from WS2012. The bottom is from the WS2012R2.
When I look at the Client Hello, I'm reminded that I have rather different cipher suites on these boxes. Does the reset packet from their mail server tell me if the cause of the reset connection is due to a misalignment of cipher suites? ... or what can I look at? I am afraid to post the contents of the packets in case I would post something private.
@CIPop I went with an IISCrypto > Best Practices set of suites on the R2 box to get it to match the non-R2 box. It only supports TLS 1.0, 1.1, 1.2. It still looks like its trying to connect SSL protocol ... is that what I'm seeing there?
[EDIT] btw- I did restart after changing the suites, and the Client Hello packet is showing the updated set of suites.
@CIPop Maybe I'll get a "nice try" for attempting to force TLS 1.2 ...
c#
string certThumbPrint = "...<thumbprint>...";
X509Store certStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
certStore.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certCollection = certStore.Certificates.Find(X509FindType.FindByThumbprint, certThumbPrint, false);
certStore.Dispose();
await stream.AuthenticateAsClientAsync(server, certCollection, System.Security.Authentication.SslProtocols.Tls12, false);
A "nice try" is all I'm gonna get. I'm going to see what happens with the ETW traces in the morning. Drinking too many :beers: now to continue and gotta catch up on The Walking Dead.
@davidsh Looks like myget has the binaries for the packages. Question: They won't be available to the app until the DNX updates, as you said, a few days later?
@GuardRex The changes that @CIPop did to remove System.Private.Networking will be in builds rc2-23606 or later.
Currently the CoreFx Dev Feed:
https://www.myget.org/gallery/dotnet-core
only has rc2-23604 version which was built from Thursday nights build. That build doesn't have the refactoring work.
@davidsh Ok, thanks for the build number. I'll keep an eye out for that.
It seems reasonable to wait a bit longer before getting into the ETW traces. I'm not setup for that on these VM's. I'd like to get past the upcoming RC2 bits just to make sure that the changes don't fix this easily and quickly.
What I am trying now is a few workarounds, including hitting up a Gmail server [instead of a GoDaddy (orf!) server] for SMTP mail forwarding.
@davidsh @CIPop New packages went live tonight. With dnx-coreclr-win-x64.1.0.0-rc2-16294 and packages ...
"System.Net.Security": "4.0.0-rc2-23611",
"System.Net.Sockets": "4.1.0-rc2-23611",
Oh, Sneezerweed! It's still broken on the 2012R2 box (and still working fine on the 2012-Not R2 box). I'll check in the morning on the server to see if the Wireshark output looks the same, and my next push will be to get ETW traces.
@CIPop Wireshark shows same: Non-R2 box (working) shows the Client Hello packet is on protocol "TLSv1.2," while Client Hello on R2 box (failing) shows "SSL."
I'll see about getting a pair of ETW traces now.
@CIPop I ran the ETW commands (the first before triggering the code on the server, the second after the code ran), and they seemed to work ... I did get an schannel.etl file at the end. However, the events are full of ...
Unknown( 23): GUID=xxxxxxxx-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx (No Format Information found).
What am I doing wrong?
I'm not sure if the symbols required to view the ETW trace event names are available to the public.
To make progress with the investigation, please point us to the location of the traces from both systems, client and server if possible (total of 4 ETW traces).
@CIPop Sure thing. I have time this evening. How can I post them securely? I can share a OneDrive folder with you ... or E-mail (maybe ... if not too large, of course).
RE: The traces I can provide. This is a .NET 5 (dnxcore50) app back-end on an Azure VM (the "client") talking to a GoDaddy (orf!) mail server. I can provide a trace for the app working in the IIS 8 environment (2012) and one from the IIS 8.5 non-working environment (2012R2). The only obvious thing thus far is that Wireshark is showing the protocol for the working IIS 8 box as TLSv1.2, while the IIS 8.5 shows as SSL ... and this is in spite of that VM not even having a SSL cipher suite available on it. Of course, I don't have the GoDaddy side of things.
If you think there is no real way to repro without the server side of this communication failure, I could put a cert on my mail server and see if I can repro against that server, but that will take a little time ... I'm not sure when I can get to it.
@CIPop ... and I guess it's worth discussing that I seem to be the only one with this issue. My VM's might be funky somehow. The workaround for me is to use a mail server on port 25 behind my firewall (i.e., 25 is closed to the Net ... only open to the app). This works ... just relaying the messages out. If you think this is too time consuming until someone else hits the same issue, we can close and wait and see what happens. Either way is fine with me.
How can I post them securely? I can share a OneDrive folder with you ... or E-mail (maybe ... if not too large, of course)
You're raising a very good point. One way to try is //msconnect although I'm not sure it'll allow you to upload private data.
@terrajobst @joshfree /cc: @SidharthNabar any ideas on methods of how to receive sensitive traces?
If you think there is no real way to repro without the server side of this communication failure, I could put a cert on my mail server and see if I can repro against that server, but that will take a little time ... I'm not sure when I can get to it.
We could try with client-side only traces. I'm not an expert on Schannel so I'd have to forward them to the owning team.
@GuardRex Any updates on this?
@CIPop I'm going to try again tonight with the latest packages and runtime and see if anything has changed. I'll get back to you tonight.
Thanks @GuardRex! If it does repro, please share the ETW traces.
@CIPop Will do, but we never came up with a good way to hand them off to you safely (privately). Was that ever worked out?
@CIPop Yes, it's still happening ...
System.IO.IOException: Authentication failed because the remote party has closed the transport stream.
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at PlatformIssue.ContactController.<SendMailOnPort465>d__9.MoveNext()]
This is the same code trying to shoot a message to GoDaddy (yuck!) mail server on port 465 in this format ...
``` c#
using (var client = new TcpClient())
{
await client.ConnectAsync(server, port);
using (var stream = new SslStream(client.GetStream(), true))
{
await stream.AuthenticateAsClientAsync(server);
using (var reader = new StreamReader(stream))
using (var writer = new StreamWriter(stream) { AutoFlush = true })
{
writer.WriteLine("
reader.ReadLine() // <---- READ SOMETHING
writer.WriteLine("
reader.ReadLine() // <---- READ SOMETHING
...
}
}
}
Using ...
dnx-coreclr-win-x64.1.0.0-rc2-16357
System.Net.Security: 4.0.0-rc2-23623
System.Net.Sockets: 4.1.0-rc2-23623
```
The code runs fine and the mail is delivered on WS 2012 (not R2). The code throws (connection reset) on WS 2012 R2 at the HELO.
The Wireshark traces show that on WS 2012 (working) the HELLO packet is on protocol TLSv1.2 ...

... while on WS 2012 R2 (not working) the HELLO packet is on protocol SSL and that's where the connection gets reset ...

These two machines have identical cipher suites (and SSL isn't among them; TLS 1.0, 1.1, 1.2 only).
I have an schannel.etl from the working server (but not from the failing one for some reason ... maybe I couldn't get one ... can't recall), but it's indecipherable because the symbols in the file aren't resolved to plain English log entries.
I just need a safe (private) way to get these to you (payload is only 408KB), and I'm not sure what "//msconnect" is or how I would use it to get the files to you.
... unless you can think of something I might just try for a :sparkles: magical :sparkles: solution.
@GuardRex Please use https://connect.microsoft.com/VisualStudio and open a new bug for ".Net Framework". In the title, specify that the bug is for dotnet/corefx and within the description add a link to this GitHub issue. For faster routing you can include my full name and @SidharthNabar's full name.
You can configure the issue to be private to Microsoft and can attach the ETL and Wireshark traces from _both_ the working and failure cases.
Thanks again for helping out with this issue!
@CIPop Done ... Title: "Bug for dotnet/corefx team"
Let me know if you ultimately need the schannel trace for the failing app/server. I think I had trouble getting that one, but I can't recall the exact behavior when I tried. I can go back and try again if the Wireshark traces aren't enough.
@CIPop Well ... my problems are more interesting as I go. I have another 2012R2 Azure VM that I put this app on. The exact app still throws the exception I've reported above on the one 2012R2 server I was working with ... and it still runs fine on the old 2012 (not R2) server ... and it still runs fine locally IIS Express Win10. Now, I'm actually getting a NEW exception on this other 2012R2 server ...
System.Security.Authentication.AuthenticationException: A call to SSPI failed, see inner
exception. ---> System.ComponentModel.Win32Exception: The message received was
unexpected or badly formatted
--- End of inner exception stack trace ---
at System.Net.Security.SslState.InternalEndProcessAuthentication(LazyAsyncResult lazyResult)
at System.Net.Security.SslState.EndProcessAuthentication(IAsyncResult result)
at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2
endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(
Task task)
at PlatformIssue.ContactController.<SendMailOnPort465>d__9.MoveNext()]
I'll investigate a bit further and report back.
@CIPop Can close this now. I know what the issue is. It's cipher suites. There is some kind of mismatch. All I did on this latest exception ... on this latest server test ... was set the IISCrypto suites to "Best Practices," because I had a very restrictive set of TLS1.2-only suites on there originally.
As soon as I loosened things up a bit, the connection was made and the servers were all talking to together :smile:
I'm probably not going to bother to check and see which cipher suite was actually agreed on between my 2012R2 and the GoDaddy server, but I think we know what this whole exception is about now.
I would suggest though that the exception itself isn't particularly helpful, since all it says is that the connection was unexpectedly dropped. It would be nice if there were a cipher suite mismatch that the exception could say so.
Anyway... thanks for your help, and I'm glad we came to a happy end on this one. I really, really needed this mail code to tide me over to the upcoming release of System.Net.Mail.
Thanks @GuardRex for the investigation!
I would suggest though that the exception itself isn't particularly helpful, since all it says is that the connection was unexpectedly dropped. It would be nice if there were a cipher suite mismatch that the exception could say so.
Unfortunately, as you can see from the traces, we can't find out that the issue was caused by a cyphersuite mismatch. The TLS protocol expects that the client submits a list of acceptable suites to the server. The server then intersects this with its own list and decides on the next action. In this case, IIS decided to terminate the TCP connection without sending any other information.
One interesting thing to note is that in CoreFX and .Net 4.6 (and above) applications we've enabled SCH_USE_STRONG_CRYPTO which eliminated a few of the crypto and hashing algorithms that are known to have security problems.
@CIPop ... which ties in well with this report at Qualys: https://community.qualys.com/thread/15498
Now, I've come to learn that I can't even get stable behavior across WS 2012 R2 machines. I have another server, also WS 2012 R2, that IS negotiating the GoDaddy mail server connection. This server has the exact same suites in place and in the same order. They are both MD5 capable. These are configured via IISCrypto "Best Practices," so AFAIK they would be the same except for the actual certificates being used by each server.
[EDIT] I want to add that the cipher suite being used on the working machines is available on the non-working machines. It's TLS_RSA_WITH_AES_256_CBC_SHA in this case.
None of these servers have a registry key for the schannel_cred key you mentioned.
The author of the Qualys post made this remark ...
When running the same application on a Windows Server 2016 Technical Preview 2 server with SchUseStrongCrypto also enabled, the connection was made using TLS 1.2 just fine
I'm going to spin-up a Nano shortly. I want to check its behavior and report back. I'm going to reopen for a bit, while I investigate this a little more.
@CIPop Done ... Title: "Bug for dotnet/corefx team"
@GuardRex Can you please send us the link / ID to the issue you've opened? Also please change the title to match this issue's title.
@CIPop I just reopened this issue (I didn't open a new one). I will close this out shortly ... I just want to see how my good bud, Mr. Nano, feels about all this. I'll add a final note and close this tonight.
@CIPop Great news! Mr. Nano is all :smile: talking to the GoDaddy (yuck!) mail server out-of-the-box. I'm good.
Hi,
In case any one else encounters this problem, here was the solution I employed to fix it in my case
var ssl = new SslStream(stream);
ssl.AuthenticateAsClient("www.domain.com");
to
var ssl = new SslStream(stream,true);
ssl.AuthenticateAsClient("www.domain.com",null,SslProtocols.Tls12,false);
I guess the handshake was going through as an earlier TLS protocol, and you have to force it to TLS1.2
Most helpful comment
@CIPop Can close this now. I know what the issue is. It's cipher suites. There is some kind of mismatch. All I did on this latest exception ... on this latest server test ... was set the IISCrypto suites to "Best Practices," because I had a very restrictive set of TLS1.2-only suites on there originally.
As soon as I loosened things up a bit, the connection was made and the servers were all talking to together :smile:
I'm probably not going to bother to check and see which cipher suite was actually agreed on between my 2012R2 and the GoDaddy server, but I think we know what this whole exception is about now.
I would suggest though that the exception itself isn't particularly helpful, since all it says is that the connection was unexpectedly dropped. It would be nice if there were a cipher suite mismatch that the exception could say so.
Anyway... thanks for your help, and I'm glad we came to a happy end on this one. I really, really needed this mail code to tide me over to the upcoming release of
System.Net.Mail.