From 16ce7f64bd7d1dd5ff0f6b343729fb0adec8f8d0 Mon Sep 17 00:00:00 2001 From: Greg W Date: Wed, 22 Jan 2025 11:40:21 +1300 Subject: [PATCH 1/2] Add ability to specifiy access control and auditing requirements when creating a named pipe server --- .../ConnectionFactory.cs | 42 ++++++++++++++++++- .../protobuf-net.GrpcLite.csproj | 1 + 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/protobuf-net.GrpcLite/ConnectionFactory.cs b/src/protobuf-net.GrpcLite/ConnectionFactory.cs index 3c9f85a..ad465da 100644 --- a/src/protobuf-net.GrpcLite/ConnectionFactory.cs +++ b/src/protobuf-net.GrpcLite/ConnectionFactory.cs @@ -10,6 +10,9 @@ using System.Net; using System.Net.Security; using System.Net.Sockets; +#if NET6_0_OR_GREATER +using System.Runtime.Versioning; +#endif using System.Security.Cryptography.X509Certificates; using System.Threading; using System.Threading.Tasks; @@ -46,10 +49,46 @@ public static Func>> Connec /// /// Listen (as a server) to a named-pipe. /// - public static Func>> ListenNamedPipe(string pipeName, ILogger? logger = null) => async cancellationToken => + public static Func>> ListenNamedPipe(string pipeName, ILogger? logger = null) { var pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough); + + return ListenToPipe(pipeName, pipe, logger); + } + +#if !NET5_0 && !NETCOREAPP3_1 + /// + /// Listen (as a server) to a named-pipe. + /// +#if NET6_0_OR_GREATER + [SupportedOSPlatform("windows")] +#endif + public static Func>> ListenNamedPipe(string pipeName, PipeSecurity pipeSecurity, ILogger? logger = null) + { +#if NETFRAMEWORK + var pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, + PipeOptions.Asynchronous | PipeOptions.WriteThrough, 0, 0, pipeSecurity); + +#elif NETSTANDARD2_1 + + var pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, + PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough, 0, 0); + + pipe.SetAccessControl(pipeSecurity); +#else + + var pipe = NamedPipeServerStreamAcl.Create(pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, + PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough, 0, 0, pipeSecurity); + +#endif + + return ListenToPipe(pipeName, pipe, logger); + } +#endif + + private static Func>> ListenToPipe(string pipeName, NamedPipeServerStream pipe, ILogger? logger = null) => async cancellationToken => + { try { logger.Debug(pipeName, static (state, _) => $"waiting for connection... {state}"); @@ -67,6 +106,7 @@ public static Func>> Listen } }; + /// /// Connect (as a client) to a socket server. /// diff --git a/src/protobuf-net.GrpcLite/protobuf-net.GrpcLite.csproj b/src/protobuf-net.GrpcLite/protobuf-net.GrpcLite.csproj index e8e13c9..33aa0ee 100644 --- a/src/protobuf-net.GrpcLite/protobuf-net.GrpcLite.csproj +++ b/src/protobuf-net.GrpcLite/protobuf-net.GrpcLite.csproj @@ -17,6 +17,7 @@ + From 3b4779120802d4450200756ab961994c3bef3096 Mon Sep 17 00:00:00 2001 From: Greg W Date: Fri, 24 Jan 2025 13:42:45 +1300 Subject: [PATCH 2/2] Fixed messed up call logic. The NamedPipe was being created only once when ListenNamedPipe is called - rather than every time the factory method returned by ListenNamedPipe is called --- .../ConnectionFactory.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/protobuf-net.GrpcLite/ConnectionFactory.cs b/src/protobuf-net.GrpcLite/ConnectionFactory.cs index ad465da..8f1dd81 100644 --- a/src/protobuf-net.GrpcLite/ConnectionFactory.cs +++ b/src/protobuf-net.GrpcLite/ConnectionFactory.cs @@ -49,13 +49,14 @@ public static Func>> Connec /// /// Listen (as a server) to a named-pipe. /// - public static Func>> ListenNamedPipe(string pipeName, ILogger? logger = null) + public static Func>> ListenNamedPipe(string pipeName, ILogger? logger = null) => async cancellationToken => { - var pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, + var pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, + NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough); - return ListenToPipe(pipeName, pipe, logger); - } + return await WaitForClientConnection(pipeName, pipe, logger, cancellationToken); + }; #if !NET5_0 && !NETCOREAPP3_1 /// @@ -64,7 +65,7 @@ public static Func>> Listen #if NET6_0_OR_GREATER [SupportedOSPlatform("windows")] #endif - public static Func>> ListenNamedPipe(string pipeName, PipeSecurity pipeSecurity, ILogger? logger = null) + public static Func>> ListenNamedPipe(string pipeName, PipeSecurity pipeSecurity, ILogger? logger = null) => async cancellationToken => { #if NETFRAMEWORK var pipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, @@ -83,11 +84,11 @@ public static Func>> Listen #endif - return ListenToPipe(pipeName, pipe, logger); - } + return await WaitForClientConnection(pipeName, pipe, logger, cancellationToken); + }; #endif - private static Func>> ListenToPipe(string pipeName, NamedPipeServerStream pipe, ILogger? logger = null) => async cancellationToken => + private static async Task> WaitForClientConnection(string pipeName, NamedPipeServerStream pipe, ILogger? logger, CancellationToken cancellationToken) { try { @@ -104,7 +105,7 @@ private static Func>> Liste pipe.SafeDispose(); throw; } - }; + } ///