Skip to content

Add CreateNamedPipeServerStream to named pipes options #56568

Closed
@JamesNK

Description

Background and Motivation

Addresses #53306

Named pipes transport allows pipe security to be configured, but it's applied to all of server's named pipe endpoints. An API is needed to customize endpoint security when they're created.

Proposed API

Adds CreateNamedPipeServerStream func to options, allowing advanced users to customize creating endpoints. They can choose to specify different PipeSecurity options on a per-endpoint basis.

This feature is modeled after SocketTransportOptions.CreateBoundListenSocket.

namespace Microsoft.AspNetCore.Server.Kestrel.Transport.NamedPipes;

+ public sealed class CreateNamedPipeServerStreamContext
+ {
+     public required NamedPipeEndPoint NamedPipeEndPoint { get; init; }
+     public PipeOptions PipeOptions { get; init; }
+     public PipeSecurity? PipeSecurity { get; init; }
+ }

public sealed class NamedPipeTransportOptions
{
+     public Func<CreateNamedPipeServerStreamContext, NamedPipeServerStream> CreateNamedPipeServerStream { get; set; }
+     public static NamedPipeServerStream CreateDefaultNamedPipeServerStream(CreateNamedPipeServerStreamContext context);
}

CreateNamedPipeServerStreamContext is added because more information than just the endpoint is needed when creating a NamedPipeServerStream. An object provides flexibility for more data to be provided, if needed. Allocations aren't a concern because the context is only created when a stream is created, and streams are cached and reused.

Usage Examples

var builder = new HostBuilder()
    .ConfigureWebHost(webHostBuilder =>
    {
        webHostBuilder
            .UseKestrel(o =>
            {
                o.ListenNamedPipe(defaultSecurityPipeName, listenOptions =>
                {
                    listenOptions.Protocols = HttpProtocols.Http1;
                });
                o.ListenNamedPipe(customSecurityPipeName, listenOptions =>
                {
                    listenOptions.Protocols = HttpProtocols.Http1;
                });
            })
            .UseNamedPipes(options =>
            {
                var defaultSecurity = new PipeSecurity();
                defaultSecurity.AddAccessRule(new PipeAccessRule("Users", PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance, AccessControlType.Allow));
                options.PipeSecurity = defaultSecurity;
                options.CurrentUserOnly = false;
                options.CreateNamedPipeServerStream = (context) =>
                {
                    if (context.NamedPipeEndPoint.PipeName == defaultSecurityPipeName)
                    {
                        return NamedPipeTransportOptions.CreateDefaultNamedPipeServerStream(context);
                    }
                    var allowSecurity = new PipeSecurity();
                    allowSecurity.AddAccessRule(new PipeAccessRule("Users", PipeAccessRights.FullControl, AccessControlType.Allow));
                    return NamedPipeServerStreamAcl.Create(
                        context.NamedPipeEndPoint.PipeName,
                        PipeDirection.InOut,
                        NamedPipeServerStream.MaxAllowedServerInstances,
                        PipeTransmissionMode.Byte,
                        context.PipeOptions,
                        inBufferSize: 0, // Buffer in System.IO.Pipelines
                        outBufferSize: 0, // Buffer in System.IO.Pipelines
                        allowSecurity);
                };
            })
            .Configure(app =>
            {
                app.Run(async context =>
                {
                    await context.Response.WriteAsync("hello, world");
                });
            });
    });

Alternative Designs

Risks

Metadata

Assignees

No one assigned

    Labels

    api-approvedAPI was approved in API review, it can be implementedarea-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