Securing the named pipe used by WCF
Asked Answered
D

3

7

am newbie to both WCF and Named pipes.

I need a way to securely communicate between a UI application and Windows Service on the same machine. Here's what I need: - Client UI application needs to send (push) various message types to the Windows Service. - Client UI app needs will receive various message types from the service (pushed or pulled).

(message here is simply a structured serialized data).

Now all this exchange should happen only under authorized user account (which might be different from service account). So I was thinking of ACLing a named pipe for both the service and user account.

However, the named pipe supports streams only. I have multiple types of messages that need to be exchanged over the named pipe, which means I need to define them and serialize/deserialize them.

To circumvent this, I thought of using WCF (for serialization and RPC support) over named pipes. Also host WCF service in the Windows service.

Question 1) Is this a good approach ? I hesitate in using http or tcp below WCF as communication must remain within the machine.

Question 2) If and how can I ACL the named pipe that WCF would use ? Is this something that I can control ? I feel ACLing the name pipe with specific SIDs provides me better security as opposed to implementing an authentication scheme between client and server.

Thanks for any pointers, suggestions! Sameer

Downdraft answered 25/2, 2011 at 21:15 Comment(0)
J
8

1) I think this is a good approach. Your thinking is spot on.

2) As you seem to have already discovered, my blog post here shows you one way to set the ACL on the pipe created by the WCF NetNamedPipe binding. It involves using reflection to fill in the gap in the Microsoft's implementation, which was obviosuly intended originally to support a direct mechanism for setting the ACL, but didn't get finished properly.

Derive a AclSecuredNamedPipeBinding from CustomBinding and a corresponding AclSecuredNamedPipeTransportBindingElement from NamedPipeTransportBindingElement. The binding element has a list of of SecurityIdentifier:

internal List<SecurityIdentifier> AllowedUsers { get { return _allowedUsers; } }
private List<SecurityIdentifier> _allowedUsers = new List<SecurityIdentifier>();

The BuildChannelListener<TChannel>(BindingContext)-method is overridden to set the private property AllowedUsers:

public override IChannelListener<TChannel> BuildChannelListener<TChannel>(BindingContext context)
{
  private static Type namedPipeChannelListenerType 
          = Type.GetType("System.ServiceModel.Channels.NamedPipeChannelListener, System.ServiceModel", false);
  IChannelListener<TChannel> listener = base.BuildChannelListener<TChannel>(context);
  PropertyInfo p = namedPipeChannelListenerType.GetProperty(
          "AllowedUsers", BindingFlags.Instance|BindingFlags.NonPublic);
  p.SetValue(listener, _allowedUsers, null);
  return listener;
}

If you go this route, be sure also to patch the "squatting vulnerability" as explained in a later post.

John answered 27/2, 2011 at 1:22 Comment(1)
Unfortunately this blog is no longer available. Anybody remember who to do it? I tried using reflection to set the Allowed Users but that didn't do what I hoped. Any help would be nice.Westminster
D
3

Came across these posts which is very helpful: Exploring the WCF Named Pipe Binding - Part 3 - Chris Dickson's Blog

Downdraft answered 25/2, 2011 at 23:36 Comment(1)
Improve by adding the content pointed to by the link and by updating the link.Enjambment
G
0

I tried what is suggested in above "Chris Disson's blog" but after running service code in admin privilege, got below exception. "There is an issue with StudentService Some or all identity references could not be translated." here is my code which host the service

AclSecuredNamedPipeBinding binding = new AclSecuredNamedPipeBinding();
SecurityIdentifier allowedGroup = (SecurityIdentifier)(new 
NTAccount("NPServiceUsers").Translate(typeof(SecurityIdentifier)));
binding.AddUserOrGroup(allowedGroup);
studentServiceHost = new ServiceHost(typeof(StudentService.StudentService));
Uri httpBaseAddress = new 
Uri("net.pipe://localhost/ServiceHost/ServiceHost");

studentServiceHost.AddServiceEndpoint(
typeof(StudentService.IStudentService),binding, httpBaseAddress); 
studentServiceHost.Open();

then I tried by changing nTAccount from "NPServiceUsers" to "Administrators" then I got below exception.

"There is an issue with StudentService Object reference not set to an instance of an object."

studentService is class which implemented the IStudentService interface.

public class StudentService : IStudentService
{
public void DoWork()
{
}
}
Garceau answered 26/10, 2017 at 10:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.