Skip to content

NamedPipeTransportOptions should support multiple PipeSecurity (DACL) #53306

Closed
@kenans

Description

@kenans

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

Today, Kestrel is capable of binding to multiple NamedPipeEndpoint

// Kestrel will listen on both "pipe1" and "pipe2"
builder.WebHost.ConfigureKestrel(options =>
{
    options.ListenNamedPipe("pipe1");
    options.ListenNamedPipe("pipe2");
});

However, DACL for each Named Pipe is set up using the identical NamedPipeTransportOptions.PipeSecurity found in NamedPipeConnectionListener

if (_options.PipeSecurity != null)
{
    stream = NamedPipeServerStreamAcl.Create(
        _endpoint.PipeName,
        PipeDirection.InOut,
        NamedPipeServerStream.MaxAllowedServerInstances,
        PipeTransmissionMode.Byte,
        pipeOptions,
        inBufferSize: 0, // Buffer in System.IO.Pipelines
        outBufferSize: 0, // Buffer in System.IO.Pipelines
        _options.PipeSecurity);    // <-- NamedPipeTransportOptions.PipeSecurity is used to create NamedPipeServerStream
}
else
{
    // ...
}

The underlying issue for this is that NamedPipeTransportFactory.BindAsync(EndPoint endpoint, CancellationToken cancellationToken) is called multiple times with each NamedPipeEndpoint, but they all share the same NamedPipeTransportOptions.

public ValueTask<IConnectionListener> BindAsync(EndPoint endpoint, CancellationToken cancellationToken = default)
{
    // ...
    
    // The same _options instance is always used here for each endpoint
    var listener = new NamedPipeConnectionListener(namedPipeEndPoint, _options, _loggerFactory, _objectPoolProvider); 

    // ...
}

Describe the solution you'd like

It would be nice to be able to assign unique DACL (PipeSecurity) to different NamedPipeEndpoint.

One possible approach is to map PipeSecurity with the pipe name in NamedPipeTransportOptions,

public sealed class NamedPipeTransportOptions
{
    // ...

    IDictionary<string, PipeSecurity> PipeSecurities { get; set; }

    // ...
}

When NamedPipeServerStream is created, do something like below,

var pipeSecurity = _optionsPipeSecuriteies[endpoint.PipeName];
var stream = NamedPipeServerStreamAcl.Create(
    _endpoint.PipeName,
    PipeDirection.InOut,
    NamedPipeServerStream.MaxAllowedServerInstances,
    PipeTransmissionMode.Byte,
    pipeOptions,
    inBufferSize: 0, // Buffer in System.IO.Pipelines
    outBufferSize: 0, // Buffer in System.IO.Pipelines
    pipeSecurityy); 

Additional context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-networkingIncludes servers, yarp, json patch, bedrock, websockets, http client factory, and http abstractions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions