3
votes

I have an application that needs to be called upon by a second application. These applications need to find each other without configuration (preferably without touching the registry) and function in a terminal services environment properly. I have heard that .net remoting using named pipes may be a way to accomplish this but I do not understand how to limit the pipe to be accessible only within the session that created it. Thanks

Update: I am fine with WCF, the question is not specific to remoting, but how to set a named pipe to be local to a session.

3
C# remoting is obsolete and no longer recommended by MS. You should use WCF service-based communication.David Pfeffer
See msdn.microsoft.com/en-us/library/72x4h507.aspx: "This topic is specific to a legacy technology that is retained for backward compatibility with existing applications and is not recommended for new development. Distributed applications should now be developed using the Windows Communication Foundation (WCF)"John Saunders

3 Answers

2
votes

If your application is running on Windows Vista or Windows 7, and you are using the WCF NetNamedPipeBinding, you will automatically get a service which is only accessible from within the same session PROVIDED that the process which implements the service end of the pipe does not have the SeCreateGlobalPrivilege privilege. In practice, this usually means the server can be any program started in the interactive session provided that it is not started with Run As Administrator.

The reason this is so concerns the named shared memory object which WCF creates to publish the actual pipe name (a GUID) to potential clients. I explain this mechanism on my blog. If the service process has SeCreateGlobalPrivilege, this publishing object is created in the Global kernel namespace visible to all sessions; if it doesn't have this privilege, the object is created in the Local kernel namespace visible only within the same session. Note that this doesn't provide absolute security: the named pipe itself could in theory be accessed from another session (using native API calls rather than the WCF client stack) if the pipe name GUID was somehow disclosed another way.

If you need to support an earlier OS, or if you wanted absolute security on the pipe itself, you would need to implement the restriction explicitly by amending the DACL on the pipe after the WCF service channel stack has created it. This requires some tinkering with the standard binding, and I show how this can be done here. You would also need to write some P/Invoke code, which is not particularly straightforward, to discover the correct logon session SID for which to create the ACE in the DACL. In .NET 4 the WCF service stack itself discovers and uses the Logon Session SID to restrict the permission to create new pipe instances, so you could use Reflector to have a look at how it does this - see: System.ServiceModel.Channels.SecurityDescriptorHelper.GetProcessLogonSid().

1
votes

I have been looking into this exact problem. The best solution I have found so far (but not tried yet) is to create a unique named pipe name by using the session id.

0
votes

I would recommend using Windows Communication Foundation for this.

You'd have the option of configuring, without using the registry, all of the different communication options, including using named pipes, sockets, etc.