Skip to content

Conversation

@filipnavara
Copy link
Member

Adds support for tvOS and Android as a side-effect.

@ghost ghost added community-contribution Indicates that the PR has been added by a community member area-System.Net.Security new-api-needs-documentation labels May 31, 2023
@ghost
Copy link

ghost commented May 31, 2023

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@ghost
Copy link

ghost commented May 31, 2023

Tagging subscribers to this area: @dotnet/ncl, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

Issue Details

Adds support for tvOS and Android as a side-effect.

Author: filipnavara
Assignees: -
Labels:

area-System.Net.Security, new-api-needs-documentation, community-contribution

Milestone: -

@filipnavara filipnavara requested a review from wfurt May 31, 2023 11:39
Comment on lines 2860 to 2649
<Suppression>
<DiagnosticId>CP0015</DiagnosticId>
<Target>M:System.Type.GetEnumValues:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute]</Target>
<Left>net7.0/mscorlib.dll</Left>
<Right>net8.0/mscorlib.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0015</DiagnosticId>
<Target>M:System.Type.GetEnumValues:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute]</Target>
<Left>net7.0/netstandard.dll</Left>
<Right>net8.0/netstandard.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0015</DiagnosticId>
<Target>M:System.Type.GetEnumValues:[T:System.Diagnostics.CodeAnalysis.RequiresDynamicCodeAttribute]</Target>
<Left>net7.0/System.Runtime.dll</Left>
<Right>net8.0/System.Runtime.dll</Right>
</Suppression>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is side-effect of rebuilding the API compat file.

}

private static unsafe int DecryptNtlm(
internal static unsafe void GetMIC(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this produce same output e.g. would it be compatible with other versions of NegotiateStream?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the NTLM code should be compatible.

(There's a part of code where I fixed the on-wire transmission of error codes. It was broken ever since Unix support was added and didn't follow the spec or the .NET Framework version.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is Kerberos what worries me more. And SqlClient uses fragments of this as well. (dotnet/SqlClient#303)

cc: @JRahnama @DavoudEshtehari for visibility

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should not be any change of the on-wire data with this PR with two exceptions:

  • The fixed error codes that now match the spec and .NET Framework
  • Write sends the frame length separately from the data to the underlying transport stream (valid according to Stream contract but may be problematic if someone was using NegotiateStream to implement Negotiate algorithm, and stripping the frame headers)

There's no modification of the native shim beyond what was already done in .NET 7.

exception = new AuthenticationException(SR.Format(SR.net_auth_context_expectation, result.ToString(), _expectedProtectionLevel.ToString()));
int statusCode = ERROR_TRUST_FAILURE;
message = new byte[sizeof(long)];
message = new byte[sizeof(long)];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we make it static constant?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose we can but I am not sure it's worth it. It's an error condition that can happen only once per connection. Is it really worth optimizing an error code path?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

while the impact is small it also seem super easy...

Copy link
Member Author

@filipnavara filipnavara Jun 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was not done previously. The code basically stayed the same. I felt the diff was hard enough to read as-is.

Copy link
Member

@wfurt wfurt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @filipnavara. generally looks good to me but it is big cleanup. I wish we can test agains previous implementation but our tests are not set up for that.

@filipnavara
Copy link
Member Author

I wish we can test against previous implementation but our tests are not set up for that.

I think I can test that manually. I'll report back on the results.

@wfurt
Copy link
Member

wfurt commented Jun 8, 2023

I wish we can test against previous implementation but our tests are not set up for that.

I think I can test that manually. I'll report back on the results.

That would be great. Possibly also cover dotnet/SqlClient#1390 - probably does not need any real database.

@filipnavara
Copy link
Member Author

filipnavara commented Jun 8, 2023

Test case

using System;
using System.IO.Pipes;
using System.Net.Security;
using System.Text;

class Program
{
    public static void Main(string[] args)
    {
        if (args.Length == 0)
            return;

        bool isClient = args[0] == "client";

        if (isClient)
        {
            using var pipeStream = new NamedPipeClientStream(".", "negtest", PipeDirection.InOut, PipeOptions.None);
            pipeStream.Connect();
            using var negStream = new NegotiateStream(pipeStream);
            negStream.AuthenticateAsClient();
            negStream.Write("hello"u8.ToArray(), 0, 5);
            negStream.Flush();
        }
        else
        {
            using var pipeStream = new NamedPipeServerStream("negtest", PipeDirection.InOut);
            pipeStream.WaitForConnection();
            using var negStream = new NegotiateStream(pipeStream);
            negStream.AuthenticateAsServer();
            byte[] buffer = new byte[5];
            negStream.Read(buffer, 0, 5);
            Console.WriteLine(Encoding.UTF8.GetString(buffer));
        }
    }
}

I tested the basic communication between all the variations of .NET 4.8, .NET 8 Preview 4 and runtime build from this PR (on Windows). In all cases the communication was successfully established and the data were transferred.

I modified the code above to test both Signed-only and Encrypted-and-Signed scenarios for NTLM (on Windows) since that's the part that had the largest level of refactoring.

@filipnavara
Copy link
Member Author

I checked that Linux-Linux communication also works. I tried Windows-Linux too but run into W11 rejecting the NTLM exchange from Linux (unrelated to the changes in this PR) but at least it showed that the transmission of error codes over the wire works as well.

Copy link
Member

@wfurt wfurt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @filipnavara

@wfurt
Copy link
Member

wfurt commented Jun 16, 2023

can you please resolve the conflict @filipnavara? Ill merge it.

@filipnavara
Copy link
Member Author

Sure, will do it in few minutes.

suppression changes
@filipnavara
Copy link
Member Author

can you please resolve the conflict @filipnavara? Ill merge it.

done

@wfurt wfurt merged commit 77ad806 into dotnet:main Jun 16, 2023
@filipnavara filipnavara deleted the negotiatestream-cleanup branch June 16, 2023 10:50
@karelz karelz added this to the 8.0.0 milestone Jul 3, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Aug 2, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

area-System.Net.Security community-contribution Indicates that the PR has been added by a community member new-api-needs-documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants