How to lower integrity of WCF named pipe

后端 未结 1 1726
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-06 02:48

I have an Internet Explorer add-in, written in C#, which talks via a WCF named-pipe to a .NET desktop application. The desktop app creates the ServiceHost for the netNamedP

相关标签:
1条回答
  • 2021-01-06 03:15

    I don't think this is going to be possible.

    The problem is that the integrity label has to be specified in the security descriptor provided when the Named Pipe is created. In the standard NetNamedPipeBinding, that call to CreateNamedPipe happens inside the private CreatePipe() method of the internal WCF class System.ServiceModel.Channels.PipeConnectionListener. I can't see a way to change how it specifies the initial security descriptor for the pipe.

    See this question and answer for an outline of what we need to achieve.

    Writing a custom named pipe transport binding element from scratch seems like the only way at present to get round this, failing which we'll just have to wait for Microsoft to add some enabling features in a future version of WCF. If you have access to Microsoft Connect, you could add your voice to the others requesting this feature.

    EDIT: I was too pessimistic. I have now found a way to do this.

    The key was that it turned out you don't necessarily have to specify the integrity label in the security descriptor when the pipe is created - but you do have to modify the SACL using the handle returned from CreateNamedPipe when the listener is opened - i.e. the very first server-side handle to the pipe. Using any other handle, the attempt to add the integrity label always fails, because the dwOpenMode flag parameter to CreateNamedPipe overloads the use of one of the bits to mean both FILE_FLAG_FIRST_PIPE_INSTANCE and WRITE_OWNER. We need the latter access permission in order to add the integrity label, but the presence of the former causes the call to fail on any but the first pipe instance.

    Getting hold of the first pipe handle is not a trivial undertaking. WCF squirrels it away in an instance of the type System.ServiceModel.Channels.PipeConnectionListener.PendingAccept, stored in a list maintained by the pipe connection listener. The connection listener is not the same thing as the channel listener (which can be grabbed straightforwardly by overriding the BuildChannelListener<> method of a binding element), and it is much harder to get at. It involves heroics using reflection, to locate the TransportManager for the endpoint, which holds a reference to the endpoint's connection listener, and then working down a chain of connection listeners (which varies according to configuration of tracing etc) until the pipe connection listener is found. If we are lucky the first pipe handle can then be found in the listener's pending accept list (though there is a race condition here - if a client connects before we get hold of the handle, it will be gone forever).

    Once the handle is available, lowering the integrity to allow low integrity clients to communicate wth the service is just a matter of calling SetSecurityInfo on the handle to add the integrity label.

    I plan to cover this is some detail on my blog soon.

    0 讨论(0)
提交回复
热议问题