多人线命名为管服务器

问题描述 投票:0回答:1

using Newtonsoft.Json; using System; using System.IO; using System.IO.Pipes; using System.Security.AccessControl; using System.Security.Principal; using System.Text; using System.Threading; namespace API.PipeServer { public class Server { private bool running; private Thread runningThread; private EventWaitHandle terminateHandle = new EventWaitHandle(false, EventResetMode.AutoReset); public string PipeName { get; set; } private void ServerLoop() { while (running) { ProcessNextClient(); } terminateHandle.Set(); } public void Run() { running = true; runningThread = new Thread(ServerLoop); runningThread.Start(); } public void Stop() { running = false; terminateHandle.WaitOne(); } public virtual string ProcessRequest(string message) { return ""; } public void ProcessClientThread(object o) { using (NamedPipeServerStream pipeStream = (NamedPipeServerStream)o) { StreamReader sr = new StreamReader(pipeStream); //Receive instruction message string instructionJson = sr.ReadLine(); Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}: --- Receiving Instruction ---"); Console.WriteLine(instructionJson); //Getting instruction message var instruction = JsonConvert.DeserializeObject<InstructionHandler.Instruction>(instructionJson); //Get data var json = API.API.GetAPIJson(instruction); //Send data back to Python client try { pipeStream.Write(Encoding.UTF8.GetBytes(json)); pipeStream.WaitForPipeDrain(); } catch (Exception ex) { Console.WriteLine(ex); } Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}: --- Closing Stream ---"); pipeStream.Close(); pipeStream.Dispose(); } } public void ProcessNextClient() { try { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}: Creating server"); PipeSecurity pipeSecurity = new PipeSecurity(); pipeSecurity.AddAccessRule(new PipeAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), PipeAccessRights.ReadWrite, AccessControlType.Allow)); var pipeStream = NamedPipeServerStreamAcl.Create("test_api", PipeDirection.InOut, 254, PipeTransmissionMode.Message, PipeOptions.None, 1024, 1024, pipeSecurity); pipeStream.WaitForConnection(); //Spawn a new thread for each request and continue waiting Thread t = new Thread(ProcessClientThread); t.Start(pipeStream); } catch (Exception e) { Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}: Error - {e.Message}"); } } } }

below是一个典型的输出:


    

我知道这是一个古老的问题,但是在我自己遇到同一问题之后,我终于奏效了。 没有太深的深入Win32内部设备,在允许服务器端上多个管道实例时要理解的主要内容是,在引擎盖窗户下方会大致执行以下操作:

如果这是第一个实例,请分配内部结构并设置包括安全性ACL在内的所有内容,然后返回新实例。
c# .net named-pipes
1个回答
0
投票

ACCESS

现有管道并为IT创建一个新实例

  • 在这里创建后续实例时,要注意的重要事项是“访问”一词。即使当前的服务器进程创建了管道,ACL仍然适用。因此,服务器过程必须具有所需的访问权限,才能从现有管道中设置新管道实例。
  • 查看您的代码,您仅指定每个人的读/写入访问权限。由于未指定其他访问规则,因此这些规则也适用于拥有过程,而
  • SUB的尝试创建新的管道实例的尝试将失败,而拒绝访问例外。 解决此问题的解决方案是创建一个附加的访问控制规则,以允许对所有者的管道进行完全控制。这是用于创建使用ACL的命名管服务器流的工厂类,用于在多线程服务器中使用: internal sealed class Win32NamedPipeServerStreamFactory : INamedPipeServerStreamFactory { private static readonly Lock s_lock = new(); private static volatile PipeSecurity? s_pipeSecurity; public NamedPipeServerStream CreateInstance(string pipeName) { PipeOptions options = GetOptions(out PipeSecurity pipeSecurity); // modify creation options as needed NamedPipeServerStream pipe = NamedPipeServerStreamAcl.Create ( pipeName: pipeName, direction: PipeDirection.InOut, maxNumberOfServerInstances: NamedPipeServerStream.MaxAllowedServerInstances, transmissionMode: PipeTransmissionMode.Byte, options: options, inBufferSize: 0, outBufferSize: 0, pipeSecurity: pipeSecurity, inheritability: HandleInheritability.None ); return pipe; } private static PipeOptions GetOptions(out PipeSecurity pipeSecurity) { PipeSecurity? security = s_pipeSecurity; if (security is not null) { pipeSecurity = security; return PipeOptions.None; } lock (s_lock) { security = s_pipeSecurity; if (security is not null) { pipeSecurity = security; return PipeOptions.None; } SecurityIdentifier currentUser = WindowsIdentity.GetCurrent().Owner ?? throw new InvalidOperationException("Could not determine current user"); PipeAccessRule fullControlForCurrentUser = new ( currentUser, PipeAccessRights.FullControl, AccessControlType.Allow ); SecurityIdentifier otherUsers = new(WellKnownSidType.AuthenticatedUserSid, null); PipeAccessRule readWriteForOtherUsers = new ( otherUsers, // deny access to extended attributes due to security concerns: // https://googleprojectzero.blogspot.com/2019/09/windows-exploitation-tricks-spoofing.html rights: PipeAccessRights.ReadData | PipeAccessRights.WriteData | PipeAccessRights.ReadAttributes | PipeAccessRights.WriteAttributes, AccessControlType.Allow ); pipeSecurity = new PipeSecurity(); pipeSecurity.AddAccessRule(fullControlForCurrentUser); pipeSecurity.AddAccessRule(readWriteForOtherUsers); s_pipeSecurity = pipeSecurity; return PipeOptions.FirstPipeInstance; } }

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.