dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.26k stars 4.73k forks source link

System.Net.Security & SslStream choking in upgrading beta7 to beta8 app #15475

Closed guardrex closed 4 years ago

guardrex commented 9 years ago

Moving here from https://github.com/aspnet/IISIntegration/issues/18

Upgraded an app to beta8. SslStream is choking. As soon as it hits the line ...

using (var client = new TcpClient(server, port))
{
    using (var stream = new SslStream(client.GetStream(), false)) { ... }
}

... it throws a ...

FileNotFoundException: Could not load file or assembly 'System.Net.Security, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system 
cannot find the file specified.

The package is ...

"System.Net.Security": "4.0.0-beta-*"

... which turns out to be 4.0.0-beta-23409 when loaded. This worked in beta7 (dnxcore50). There were no changes to this code (or even to the package reference, since it is not tied to beta7 or beta8 directly AFAIK).

The package is on the server and looks right. Just to be sure the package was ok, I deleted it on the server, re-published the app (and package), and tried again. Same result.

joshfree commented 9 years ago

/cc @chcosta @ericstj

bartonjs commented 9 years ago

@GuardRex Interesting. I can repro your problem, but only after switching down to 1.0.0-beta7 from 1.0.0-beta8. When I go back to 1.0.0-beta8 it works fine. Are you using the released/final beta8, or a beta8 daily build? I assume from your bug that you're using Windows, so that's what I used, too.

D:\dnxperiment\SslCertPrinter>dnx run www.microsoft.com
EXCEPTION: System.IO.FileNotFoundException: Could not load file or assembly
    'System.Net.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'
    or one of its dependencies. The system cannot find the file specified.
File name: 'System.Net.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' --->
    System.IO.FileNotFoundException: Could not load the specified file.
File name: 'System.Net.Security'
   at System.Runtime.Loader.AssemblyLoadContext.LoadFromAssemblyName(AssemblyName assemblyName)
   at System.Runtime.Loader.AssemblyLoadContext.Resolve(IntPtr gchManagedAssemblyLoadContext, AssemblyName assemblyName)
   at SslCertPrinter.Program.ShowSslCertInfo(String dest)
   at SslCertPrinter.Program.Main(String[] args) in D:\dnxperiment\SslCertPrinter\Program.cs:line 21

D:\dd\Blue\dnxperiment\SslCertPrinter>dnvm use 1.0.0-beta8 -r coreclr
Adding C:\Users\jbarton\.dnx\runtimes\dnx-coreclr-win-x64.1.0.0-beta8\bin to process PATH

D:\dd\Blue\dnxperiment\SslCertPrinter>dnu restore
Microsoft .NET Development Utility CoreClr-x64-1.0.0-beta8-15858

  CACHE https://www.nuget.org/api/v2/
Restoring packages for D:\dnxperiment\SslCertPrinter\project.json
  CACHE https://www.nuget.org/api/v2/FindPackagesById()?id='System.Net.Sockets'
Writing lock file D:\dnxperiment\SslCertPrinter\project.lock.json
Restore complete, 846ms elapsed

NuGet Config files used:
    C:\Users\jbarton\AppData\Roaming\NuGet\nuget.config

Feeds used:
    https://www.nuget.org/api/v2/

D:\dnxperiment\SslCertPrinter>dnx run www.microsoft.com
Connecting to www.microsoft.com...
Remote Certificate Information:
    Subject:
        CN=www.microsoft.com
        OU=MSCOM
        O=Microsoft Corporation
        STREET=1 Microsoft Way
        L=Redmond
        S=Washington
        PostalCode=98052
        C=US
        SERIALNUMBER=600413485
        OID.2.5.4.15=Private Organization
        OID.1.3.6.1.4.1.311.60.2.1.2=Washington
        OID.1.3.6.1.4.1.311.60.2.1.3=US

    Issuer:
        CN=Symantec Class 3 EV SSL CA - G3
        OU=Symantec Trust Network
        O=Symantec Corporation
        C=US

    Subject Alternative Names:
        DNS Name=www.microsoft.com
        DNS Name=wwwqa.microsoft.com

There's a lot of pretty-printing stuff in my utility, but the bulk of the code is the same as yours:

        public static void ShowSslCertInfo(string dest)
        {
            Console.WriteLine("Connecting to {0}...", dest);

            using (TcpClient tcpClient = new TcpClient(dest, 443))
            using (SslStream sslStream = new SslStream(tcpClient.GetStream(), true, ShowCertificateValidationCallback))
            {
                sslStream.AuthenticateAsClient(dest);
            }
        }

And, good old project.json:

{
    "version": "1.0.0-*",
    "dependencies": {
        "System.Console": "4.0.0-beta-23409",
        "System.Linq": "4.0.0",
        "System.Net.Security": "4.0.0-beta-23409",
        "System.Net.Sockets": "4.0.10-beta-23409"
    },
    "frameworks" : {
        "dnxcore50" : {}
    }
}
guardrex commented 9 years ago

[DELETE] Rubber duck content

guardrex commented 9 years ago

[DELETE] Rubber duck content

guardrex commented 9 years ago

[DELETE] Rubber duck content

guardrex commented 9 years ago

[DELETE] Rubber duck content

guardrex commented 9 years ago

@bartonjs It's a package problem. Going back to -23405 works.

Here's the nuspec for -23405 ...

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/01/nuspec.xsd">
  <metadata minClientVersion="3.0">
    <id>System.Net.Security</id>
    <version>4.0.0-beta-23405</version>
    <title>System.Net.Security</title>
    <authors>Microsoft</authors>
    <owners>microsoft,dotnetframework</owners>
    <licenseUrl>http://go.microsoft.com/fwlink/?LinkId=329770</licenseUrl>
    <iconUrl>http://go.microsoft.com/fwlink/?LinkID=288859</iconUrl>
    <requireLicenseAcceptance>true</requireLicenseAcceptance>
    <description>Provides types, such as System.Net.Security.SslStream, that enable secure network communication between applications and hosts.

Commonly Used Types:
System.Net.Security.SslStream
System.Net.Security.ExtendedProtectionPolicy</description>
    <copyright>© Microsoft Corporation.  All rights reserved.</copyright>
    <dependencies>
      <group targetFramework="MonoAndroid1.0" />
      <group targetFramework="MonoTouch1.0" />
      <group targetFramework="Xamarin.iOS1.0" />
      <group targetFramework="Xamarin.Mac2.0" />
      <group targetFramework=".NETPlatform5.0">
        <dependency id="System.Runtime" version="4.0.0" />
        <dependency id="System.Security.Cryptography.X509Certificates" version="4.0.0-beta-23405" />
        <dependency id="System.IO" version="4.0.0" />
        <dependency id="System.Threading.Tasks" version="4.0.0" />
        <dependency id="System.Net.Primitives" version="4.0.10" />
      </group>
      <group targetFramework="DNXCore5.0">
        <dependency id="System.Private.Networking" version="4.0.1-beta-23405" />
      </group>
    </dependencies>
    <frameworkAssemblies>
      <frameworkAssembly assemblyName="mscorlib" targetFramework=".NETFramework4.6" />
      <frameworkAssembly assemblyName="System" targetFramework=".NETFramework4.6" />
    </frameworkAssemblies>
  </metadata>
</package>

Here's the nuspec for -23409 ...

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/01/nuspec.xsd">
  <metadata minClientVersion="3.0">
    <id>System.Net.Security</id>
    <version>4.0.0-beta-23409</version>
    <title>System.Net.Security</title>
    <authors>Microsoft</authors>
    <owners>microsoft,dotnetframework</owners>
    <licenseUrl>http://go.microsoft.com/fwlink/?LinkId=329770</licenseUrl>
    <iconUrl>http://go.microsoft.com/fwlink/?LinkID=288859</iconUrl>
    <requireLicenseAcceptance>true</requireLicenseAcceptance>
    <description>Provides types, such as System.Net.Security.SslStream, that enable secure network communication between applications and hosts.

Commonly Used Types:
System.Net.Security.SslStream
System.Net.Security.ExtendedProtectionPolicy</description>
    <copyright>© Microsoft Corporation.  All rights reserved.</copyright>
    <dependencies>
      <group targetFramework="MonoAndroid1.0" />
      <group targetFramework="MonoTouch1.0" />
      <group targetFramework="Xamarin.iOS1.0" />
      <group targetFramework="Xamarin.Mac2.0" />
      <group targetFramework=".NETPlatform5.0">
        <dependency id="System.Runtime" version="4.0.0" />
        <dependency id="System.Security.Cryptography.X509Certificates" version="4.0.0-beta-23409" />
        <dependency id="System.IO" version="4.0.0" />
        <dependency id="System.Threading.Tasks" version="4.0.0" />
        <dependency id="System.Net.Primitives" version="4.0.10" />
      </group>
    </dependencies>
    <frameworkAssemblies>
      <frameworkAssembly assemblyName="mscorlib" targetFramework=".NETFramework4.6" />
      <frameworkAssembly assemblyName="System" targetFramework=".NETFramework4.6" />
    </frameworkAssemblies>
  </metadata>
</package>

The -23409 package is missing this target group ...

<group targetFramework="DNXCore5.0">
  <dependency id="System.Private.Networking" version="4.0.1-beta-23405" />
</group>

... and a nit there, too, the <description> is broken across multiple lines.

ericstj commented 9 years ago

@GuardRex that's expected. If you look at the file content you'll see we added a runtime.json that splits the implementations out per-platform.

{
  "runtimes": {
    "win7": {
      "System.Net.Security": {
        "runtime.win7.System.Net.Security": "4.0.0-beta-23419"
      }
    },
    "unix": {
      "System.Net.Security": {
        "runtime.unix.System.Net.Security": "4.0.0-beta-23419"
      }
    }
  }
}

Did you specify a runtime in your project.json? Is your project also including Microsoft.NETCore.Platforms (which defines the runtime ID hierarchy)?

guardrex commented 9 years ago

@ericstj I'm very confused now.

Did you specify a runtime in your project.json?

I have the framework (dnxcore50). I have the runtime in global.json

{
  "projects": [
    "src", "Microsoft.AspNet.Razor"
  ],
  "sdk": {
    "architecture": "x64",
    "runtime": "coreclr",
    "version": "1.0.0-beta8"
  }
}

... and specified in the VS Publish dialog and in VS project properties.

Is your project also including Microsoft.NETCore.Platforms (which defines the runtime ID hierarchy)?

No. I haven't seen that documented anywhere yet and didn't know that I needed that (I didn't need it up to this point, when this was beta7).

{
  "authors": [ "XXX XXX" ],
  "commands": {
    "web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Kestrel"
  },
  "copyright": "Copyright 2015 XXXXXX. All Rights Reserved.",
  "dependencies": {
    "Microsoft.AspNet.Diagnostics": "1.0.0-beta8",
    "Microsoft.AspNet.Diagnostics.Entity": "7.0.0-beta8",
    "Microsoft.AspNet.Hosting": "1.0.0-beta8",
    "Microsoft.AspNet.Mvc": "6.0.0-beta8",
    "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-beta8",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-beta8",
    "Microsoft.AspNet.StaticFiles": "1.0.0-beta8",
    "System.ComponentModel.TypeConverter": "4.0.1-beta-*",
    "System.Net.Http": "4.0.0-beta-*",
    "System.Net.Security": "4.0.0-beta-23405",
    "System.Net.Sockets": "4.0.10-beta-*",
    "Microsoft.AspNet.Antiforgery": "1.0.0-beta8",
    "System.Runtime.Serialization.Primitives": "4.0.10-beta-*",
    "WindowsAzure.Storage": "5.0.3-preview",
    "Microsoft.Framework.Configuration": "1.0.0-beta8",
    "Microsoft.Dnx.Compilation.CSharp.Abstractions": "1.0.0-beta8",
    "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta8",
    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-beta8"
  },
  "description": "XXX XXX",
  "exclude": [
    "wwwroot",
    "node_modules"
  ],
  "frameworks": {
    "dnxcore50": { }
  },
  "publishExclude": [
    "node_modules",
    "gulpfile.js",
    "notes.txt",
    "NuGet.Config",
    "package.json",
    "stylesheets",
    "scripts",
    "obj",
    "*.vs",
    "Views_debug",
    "fonts",
    "Properties",
    "**.user",
    "msdeploy.bat"
  ],
  "version": "1.0.0",
  "webroot": "wwwroot"
}
ericstj commented 9 years ago

That's because beta7 didn't support cross-plat. I believe DNX is supposed to be doing this automatically for you but @anurse or @davidfowl would know for sure. If you send me your project.lock.json I can take a look and see what's happening. Also let me know which version of DNX you are using so we can understand if it is a bug or just an old version.

Barring that, just add:

  "runtimes": {
    "win7-x86": { },
    "win7-x64": { },
  }

And add "Microsoft.NETCore.Platforms": "1.0.1-beta-*" to your dependencies.

guardrex commented 9 years ago

@ericstj I switched back to "System.Net.Security": "4.0.0-beta-*", so it would pull down -23409, and without making any other changes, I let it create a new project.lock.json and put it here.

This is a web app hosted on WS 2012 IIS 8, dnxcore50-only project, so the only runtime I'm going for is dnx-coreclr-win-x64.1.0.0-beta8. Are you saying that runtimes for win7 must be mentioned now (with a blank runtime listed) even if those runtimes are not at play? As you can see, I'm still rather confused here.

guardrex commented 9 years ago

@ericstj Cool. It works now. I guess my broad question is just that for those us web dev'ing dnxcore50-only projects for WS IIS, do we only need the runtimes section and Microsoft.NETCore.Platforms package for certain packages and not for others? If so, how do we know in advance if a given package will require this?

ericstj commented 9 years ago

DNX will implicitly restore for the runtime you are running on. Looking at your lock file I see that this is indeed working: it contains resolved targets for DNXCore,Version=v5.0/win7-x86 and "DNXCore,Version=v5.0/win7-x64". DNX should have been implicitly referencing a version of Microsoft.NETCore.Platforms that contains the graph for the runtime ID that it used for restore. @anurse or @davidfowl might be able to tell you why that's not happening.

It would be a good practice to list out all the runtimes you'd like to run on just so you can know up-front at dev time if you are using a package that isn't implemented on a particular platform (eg: Registry isn't supported on unix). DNX doesn't yet have the compatibility checks that are present in nuget, but it eventually will and it will flag things like this.

It won't hurt to reference Microsoft.NETCore.Platforms but as I mentioned I thought the latest versions of DNX were going to be doing this implicitly.

guardrex commented 9 years ago

@ericstj Thanks for explaining.

I just found it works if I only add the package. I don't need the runtimes section in project.json.

I would prefer implicit reference to Microsoft.NETCore.Platforms, but 'oh, well.' If I have to add it, no big deal. I'll leave this open for a sec in case @davidfowl and/or @anurse want to comment. If not, I'll close the issue shortly.

analogrelay commented 9 years ago

@GuardRex We definitely do have code to do the implicit reference, it might just be failing for some reason :). Can you post the output of dnx --version? That would help ensure I know exactly which build of DNX you're on. We had some issues with this in the beta8 timeline but I thought we fixed them all.

guardrex commented 9 years ago

@anurse

Locally, where everything runs ok in the debugger (i.e., it runs ok without Microsoft.NETCore.Platforms in dependencies):

capture

On the VM, where it fails (i.e, it fails without Microsoft.NETCore.Platforms in dependencies):

capture

analogrelay commented 9 years ago

@GuardRex are you able to post a complete repro somewhere so I can try it out and debug it?

guardrex commented 9 years ago

@anurse Sure. I'll have it up within an hour.

guardrex commented 9 years ago

@anurse Ok ... took longer than I thought ... had to strip a bunch of crap out of it for a public repo.

https://github.com/GuardRex/PlatformIssue

On WS2012 (IIS 8) with (current version) ...

"System.Net.Security": "4.0.0-beta-23409"

... it chokes with a ...

FileNotFoundException: Could not load file or assembly 'System.Net.Security, Version=4.0.0.0,
Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system
cannot find the file specified.

PlatformIssue.ContactController.Message(Visitor visitor)

... but with (previous version)...

"System.Net.Security": "4.0.0-beta-23405"

... it runs fine.

It also runs with the -23409 package locally ... it's only on my Azure VM that it chokes.

SidharthNabar commented 9 years ago

Removing System.Net label since this issue does not seem to be related to System.Net APIs.

guardrex commented 9 years ago

Covered by ...

https://github.com/dotnet/corefx/issues/4230 https://github.com/NuGet/Home/issues/1660

... based on https://github.com/dotnet/corefx/issues/4217#issuecomment-152195478.

guardrex commented 8 years ago

Confirmed fixed with runtime rc1-update1. See: https://github.com/aspnet/dnx/issues/3183