Before I start, I'll give fair warning, this fits squarely into the category of post where the topic is going to be of very little interest to most readers, however it just might make one person out there a very very happy developer and save them some pain.
I'm nearing the end of my adventures (I sure as hell hope there are no more problems, put it that way) writing a Winsock LSP and I have to say, it's been a gloriously excrusiating experience.
One of the problems I had when tinkering with this was with the new Windows Integrity Control stuff in Vista, in particular, how it all applies to IE7 Protected Mode. I'm sure it's all far more secure and that's a great thing, but it does put some obstacles in the road of people writing code which runs in the IE process, such as BHO's and toolbars... and also Winsock LSPs.
I needed to perform some operations which Protected Mode wouldn't allow, and after playing with several alternatives, I decided I'd have the code which required more priveledges running in it's own process and have all instances of my LSP talk to it over named pipes. Because my LSP, when running in IE, was low integrity I needed to lower the integrity of the pipe I was creating in my medium integrity broker. This is where it got a little trickier, given there is no real built in way to do this in .Net. I ended up writing a load of P/Invoke stuff to get it all working, so without further ado, let's check out how to use it.
SafePipeHandle handle =
LowIntegrityPipeFactory.CreateLowIntegrityNamedPipe("NameOfMyPipe");
NamedPipeServerStream server =
new NamedPipeServerStream(PipeDirection.InOut, false, false, handle);
Pretty simple right? Here's a look at the insides of that factory method...
Byte[] securityDescriptor = ConvertStringSDToSD(lowIntegritySddl);
using (SECURITY_ATTRIBUTES securityAttributes =
new SECURITY_ATTRIBUTES(securityDescriptor, inheritability))
{
IntPtr handle = CreateNamedPipe(@"\\.\pipe\" + pipeName,
(Int32)direction | (Int32)options,
(Int32)mode,
maxInstances, inBufferSize, outBufferSize, 1000,
securityAttributes);
return new SafePipeHandle(handle, true);
}
So here we create our security descriptor with the low mandatory label. We use it to populate an instance of SECURITY_ATTRIBUTES and then we call the unmanaged CreateNamedPipe.
The reason this is all such a pain.. Well first of all, it doesn't seem that you can lower the integrity of a named pipe you've already created. This is frustrating because all of the samples for lowering resource integrity do so on an exisintg resource and nowhere is it suggested that you need to, with pipes, create the resource with the low label as assigning it later won't seem to work. Secondly, this should all be possible in pure managed code using the PipeSecurity class, unfortunately for some unknown reason I wasn't able to get this to work. This is how it should look though.
PipeSecurity security = new PipeSecurity();
security.SetSecurityDescriptorSddlForm(lowIntegritySddl);
NamedPipeServerStream server =
new NamedPipeServerStream("NameOfMyPipe", PipeDirection.InOut,
serverInstances, PipeTransmissionMode.Byte, PipeOptions.None,
inBuffer, outBuffer,
security);
Nevermind, I got it all working right in the end, and I hope this helps someone out.. Code file attached!
LowIntegrityPipeFactory.zip (1.45 kb)