Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

System.IO.Pipes.AccessControl package does not work #26869

Closed
pjanotti opened this issue Jul 19, 2018 · 25 comments
Closed

System.IO.Pipes.AccessControl package does not work #26869

pjanotti opened this issue Jul 19, 2018 · 25 comments

Comments

@pjanotti
Copy link
Contributor

The platform extension package System.IO.AccessControl package does not work as intended. This package only supports Windows and was created with the intention of providing the functionality that was removed from System.IO.Pipes related to ACLs, that are not part of .NET Standard 2.0. However, as discussed in https://github.com/dotnet/corefx/issues/30170 this does not work because the proper access right flags need to be specified at construction time, and the constructors are not available either at CoreFx or .NET Standard 2.0.

If we want this package to offer functionality to match .NET Fx we need to add factory methods to make the package functional. OTOH if we can consider that the main usage is already covered by CurrentUserOnly that is being added to .NET Standard vNext (the next one after 2.0). In this case we likely should retire or convert this package to PNSE.

/cc @safern @danmosemsft

@kfreezen
Copy link

I have a use case which requires more than just CurrentUserOnly. I have a program split into a local front end and local back end. The program uses named pipes for its IPC.

The problem is that the back end (which is a service) needs to run as an elevated user (i.e. Local System) but the front end only needs to run as the currently logged in user. So, I need some way to set access control to allow non-elevated clients to access the back end.

I have been using .NET Framework up until now for this project, but I'm trying to port bits and pieces of it to .NET Standard in order to make the project cross-platform.

What I know to do is create a .NET Framework project that abstracts the Windows implementation details away from the common functionality. Is there any other workaround that doesn't involve .NET Full?

@pjanotti
Copy link
Contributor Author

Hi @kfreezen - just for me to better understand your usage: can you share the sources that you create the server and client on the full framework? Do you somehow restricts the clients?

@kfreezen
Copy link

kfreezen commented Oct 5, 2018

@MarcusWichelmann
Copy link

@kfreezen Did you find a solution for this? I'm trying to do the same but don't get any further than the UnauthorizedAccessException, too.

_pipeStream = new NamedPipeServerStream(PipeName, PipeDirection.In);

PipeSecurity pipeSecurity = _pipeStream.GetAccessControl();
pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, domainSid: null), PipeAccessRights.ReadWrite, AccessControlType.Allow));
_pipeStream.SetAccessControl(pipeSecurity);

The NamedPipeServerStream is created inside of a .Net Core Windows-Service and a NamedPipeClientStream should be used by an application running in the user session to communicate to that service.

@kfreezen
Copy link

kfreezen commented Dec 6, 2018

I ended up using a socket TCP stream for client-server communication on macOS and then using .NET Framework rather than .NET Core for the Windows portion of the project.

@pjanotti Is there currently a way to do cross-privilege message passing with .NET Core?

@Jens-G
Copy link

Jens-G commented Feb 27, 2019

Is there currently a way to do cross-privilege message passing with .NET Core?

Calling the native WinAPI is still possible.
https://stackoverflow.com/a/54896975/499466

@darinkes
Copy link

darinkes commented Mar 27, 2019

Hey, just to make sure I understood the current situation correctly.
My use case looks like the one of @kfreezen.

  • It's currently just usable for two processes running under the same User?
  • There is currently no way to configure Access-Rules or Permissions on non-Windows OSes?

@omghb
Copy link

omghb commented May 10, 2019

I run into the same issue as @kfreezen.
My library should target .NET Standard 2.0 as it is used by .NET Framework and .NET Core applications.

In my library I use PipeSecurity so that the pipe server can run as elevated user whereas the client runs with the Windows user:

var security = new PipeSecurity();
security.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(
    WellKnownSidType.AuthenticatedUserSid, null), 
PipeAccessRights.CreateNewInstance | PipeAccessRights.ReadWrite, AccessControlType.Allow));
var server = new NamedPipeServerStream(pipeName, PipeDirection.InOut, -1, 
    PipeTransmissionMode.Message, PipeOptions.Asynchronous | PipeOptions.WriteThrough, 
    0, 0, security);

Without being able to accomplish this with .NET Standard 2.0 I have to stay with the classic .NET Framework.

@danmoseley
Copy link
Member

@JeremyKuhne is there any feasible workaround here? This is a famliar problem, that we did not find a good solution for in 3.0

@JeremyKuhne
Copy link
Member

is there any feasible workaround here?

Not really. We have to do the work to allow creating the pipe from a PipeSecurity instance. I presume we'd want to add some ref struct that contains the SECURITY_ATTRIBUTES and add an overload that PipeSecurity can use.

// Some assembly higher up than NamedPipeServerStream
public ref struct SecurityDescriptor
{
   // Contains SECURITY_ATTRIBUTES
}

// NamedPipeServerStream
public NamedPipeServerStream(String pipeName, PipeDirection direction, int maxNumberOfServerInstances,
                PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize,
                SecurityDescriptor pipeSecurity, HandleInheritability inheritability, PipeAccessRights additionalAccessRights)

// PipeSecurity
public NamedPipeServerStream CreateNamedPipeServerStream(String pipeName, PipeDirection direction, int maxNumberOfServerInstances,
                PipeTransmissionMode transmissionMode, PipeOptions options, int inBufferSize, int outBufferSize,
                HandleInheritability inheritability, PipeAccessRights additionalAccessRights)

That's where I would start. If anyone has time to try and make this happen I'm happy to help formalize and push through an API request.

@TonyValenti
Copy link

Hi All!
Are there any solutions for this? I just ran into the ACL issue when trying to port a .NET Framework app to .NET Core. We need to be able to do cross-user IPC and this is blocking for us.

@JeremyKuhne
Copy link
Member

@TonyValenti we have an approved API that we're working on implementing now: dotnet/corefx#41657

@TonyValenti
Copy link

@JeremyKuhne It looks like this has been implemented but isn't targeted for release until .NET 5.0 - a year from now. Is there any chance we can get an update to the System.IO.Pipes.AccessControl library that makes this work today?

@jcapellman
Copy link

Seconding @TonyValenti's comment - porting a critical piece of our previously .NET 4.7.1 app to .NET Core 3.1 this is a blocker.

If there's not an official back port - I'll probably end up doing a cherry-picked merge and crank out a local System.IO.Pipes.AccessControl NuGet package and host it in my Artifactory repo.

@danmoseley
Copy link
Member

@jcapellman we don't have a plan to do this right now - maybe if there were lots of asks we could look at it again. It's tricky publishing packages intended to replace parts of the product, without officially servicing the product. What you described sounds like it would work meantime.

Note that we have historically supported production use on certain preview releases. It's not clear yet which preview build of 5.0 that would start with, but perhaps that would unblock you when it does.

Also note as you see from the links from https://github.com/dotnet/corefx/issues/41657 we added similar API for other objects.

I think this issue is resolved as far as we plan to resolve it, and there should be a way one way or another to get the job done now, so I'll close.

@jcapellman
Copy link

Thanks for the response @danmosemsft - given my product's timetable for our upcoming release I don't think the .NET 5 preview will work. I do plan on porting over to .NET 5 this Fall, so this could just be hold over for the next couple months.

Would it be against policy to publish it to NuGet for others also needing this as a stopgap? Otherwise I'll just keep it in my private artifactory repo. I'll begin the back porting tomorrow.

@danmoseley
Copy link
Member

We ask that folks publishing to NuGet don't publish in such a way the the package looks like a Microsoft artifact if it's not. Ideally the code would be in a different namespace as well.

Another option you have perhaps is just sharing source code that could be pasted in.

Thanks for helping the community @jcapellman

@jcapellman
Copy link

Sounds good - I'll blog the changes/source code instead. It's nice to help out the community.

@jcapellman

This comment was marked as off-topic.

@danmoseley

This comment was marked as off-topic.

@ericstj

This comment was marked as off-topic.

@TonyValenti
Copy link

I was really hoping for an official fix for this. This is blocking us from adopting .NET Core as well.

@jcapellman

This comment was marked as off-topic.

@ericstj

This comment was marked as off-topic.

@HavenDV
Copy link

HavenDV commented Jan 12, 2020

Hello.
Recently I encountered the same problem when translating the project to .Net Core.
I added a nuget package to help with the transition: https://www.nuget.org/packages/NamedPipeServerStream.NetFrameworkVersion/
The package targets .Net Standard 2.0 and contains the original constructor from the .Net Framework (which supports PipeSecurity, HandleInheritability, and PipeAccessRights). I restored it from decompiled code without making any changes. Exceptions are fully supported, no code has been lost. Has a strong name.
The source code is also available.

@msftgits msftgits transferred this issue from dotnet/corefx Jan 31, 2020
@msftgits msftgits added this to the Future milestone Jan 31, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 16, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests