I am running a windows service to which I send messages over a NetNamedPipeBinding. The messages are send from a client application which is triggered by a GPO. I just installed the service and client on a new server and I'm getting the following message:
System.ServiceModel.EndpointNotFoundException:
There was no endpoint listening at
net.pipe://localhost/VOXAServices/VOXADefaultPipe that could accept the
message. This is often caused by an incorrect address or SOAP action.
See InnerException, if present, for more details.
There is no inner exception. If I run the client application by double-clicking it's icon on the desktop, it runs without a problem. I manage the code for both the windows service and client application, so I can change whatever I need to. But so far, I'm pretty convinced that the binding, contract, and address are all correct (since everything runs fine when run from the desktop). I believe the problem must be with the client app being run from a GPO. But I can't think of any reason why that would cause this error.
UPDATE:
I read this this on Microsoft's website:
A named pipe is an object in the Windows operating system kernel, such
as a section of shared memory that processes can use for
communication. A named pipe has a name, and can be used for one-way or
duplex communication between processes on a single machine.
When communication is required between different WCF applications on a
single computer, and you want to prevent any communication from
another machine, then use the named pipes transport. An additional
restriction is that processes running from Windows Remote Desktop may
be restricted to the same Windows Remote Desktop session unless they
have elevated privileges.
(Choosing a Transport, Emphasis added)
I need the client process to run in the context of the (unprivileged) user and having a UAC dialog pop up is not an option. Is there anyway for me to give this client process elevated privileges while keeping the process running in the user context and not making the user privileged?
UPDATE #2:
It appears that there is such a thing as global and local (to the windows session) Named Pipes. I believe my windows service is creating a local named pipe and that if I can force it to create a global named pipe, it would solve my problem. (This explains why I couldn't see my pipe in sysinternals "Process Explorer", even though my client app could find it if I launched it from a privileged session). The trouble is, I don't know (and can't seem to find out) how to force a named pipe to be created globally (c#). Any ideas?
The mechanism by which WCF clients find WCF service NetNamedPipe endpoints involves a kernel shared memory object which the service uses to tell clients the actual name of the pipe to be used. If clients are going to be in a different logon session to the server, this shared memory object must be in the Global and not the Local kernel namespace. The named pipes themselves have a single namespace, visible to all clients. You cannot directly control the namespace WCF uses for the shared memory object, but it will be the Global kernel namespace provided that your server is a Windows Service running with SeCreateGlobalPrivilege. Your question seems to imply that this is the case, so I'm sceptical whether your problem is connected with kernel object namespaces.
Two other possible causes are:
The ACLs which protect both the shared memory object and the named pipe. These will always deny access to any security context which has membership of the NETWORK USERS group (SID S-1-5-2). This enforces the WCF guarantee of no remote access to named pipe endpoints.
If you are running on Vista or later, the Mandatory Integrity level of the client process must not be lower than the Mandatory Integrity level of the kernel objects (which will be the implied level - Medium - unless you have taken special steps to elevate using Mandatory Integrity Labels)
I don't know enough about the security context in which your client process started by the GPO would run to advise further, but I suggest you check these two possibilities and post further updates to your question accordingly.
Related
I am working on a Windows server application that will transfer sensitive information to another Windows server over a socket using an HTTPClient. The servers are supposed to be configured to use IPSec. So yay, I I don't have to do anything to setup the secure connection at the application level. However, I have been instructed to ensure that if the connection is using IPSec and abort if it is not.
How can I programmatically determine if the connection is indeed secured with IPSec? The application is C#, on Windows Server 2016. I am open to P/Invoke based solutions or C code if that is required to make this work. So long as it can ultimately work with a C# HttpClient class.
It is not application's concern and can't be done. The tunnel is transparent to application level users of the network stack. If you want the application to ensure that connection is encrypted and authenticated, use TLS. Otherwise it is up to the network/system administrators to make sure that policies are setup so that only ipsec traffic is allowed.
Imagine that you figure out a way to ensure that tunnel is setup by interrogating the OS in some way. And then in 2 years the system needs to be scaled up and IPSec termination is moved to dedicated hardware. Oops.
Based on everything I've read about WCF services using net pipes I expected to be able to use the address net.pipe://localhost/service/ on different user sessions as WCF does not use the name but a GUID.
Anyway when I launch several services I get a AddressAlreadyInUseException with the message:
Cannot listen on pipe name 'net.pipe://localhost/service/' because another pipe endpoint is already listening on that name.
Is there a way to limit the scope of every WCF service to the user session? Connections will come always from the same user session.
What we have found is that Administrator users can see named piped between sessions while normal users do not see them. So we ended up running the application without admin rights and that was it.
What I don't know if this behavior is something that can be changed or if it is fixed in Windows.
Background
I have multiple servers that I currently connect to remotely to run a number of different commands/scripts to obtain information about the servers and/or applications running on the servers.
I'd like to automate running the commands/scripts (or the code contained in the scripts converted to C#/.NET) and have the server send alerts/notifications/messages to a client (basically a Windows Form) running on multiple workstations, but need some guidance.
For reference, I have limited experience creating Windows Services, but feel fairly confident in being able to create them on the server to handle to command/script automation, which I'm assuming would be the best way to go about handling the command/script automation on the server (since the commands/scripts would need to be run all the time or at set intervals).
Question
How can I connect multiple servers to multiple clients so that the server sends alerts/notifications/messages to the client when a command/script or even an event occurs on the server?
For instance, if an application on the server has a built-in command that can be run to determine the status of the application (up, down, limbo, etc.), I would like the Windows Form on the client to receive an alert from the server when the command returns "down" or "limbo" when it is run, presumably from a Windows Service. The alerts would be displayed on the Windows Form that would be setup basically as a dashboard for the servers that the client can connect to.
An even better outcome would be that the client runs as a background application and a notification appears similar to how Microsoft Outlook displays a notification when new email messages arrive (although these notifications would likely require user interaction to close instead of fading out like the Outlook notifications).
I would also like for the client to use a configuration file that has the connection information for the servers in it so that the servers being used can be changed quickly new servers are added or existing servers are decommissioned.
Research (so far)
I've read about WCF and duplex contracts, and how WCF can be hosted in Windows Services. From what I've read, this seems promising. However, I'm not quite sure how I would set this up so that the client can connect to a WCF service on multiple servers.
One thing that I'm concerned about with WCF is that in all of the WCF examples (which implement a calculator-type service) I've seen the client has to initiate the communication with the server in order to receive a message through a callback. In the calculator service examples, the client sends numbers to the service and the result is provided in the callback. I've also seen an asynchronous example, but in that example the client initiated a single, long running request and the callback returned a single response when it was finished processing.
And, just so I'm clear about bindings in WCF, it is possible to create and use bindings for multiple servers using a configuration file without having to use SvcUtil.exe to generate the code, correct? The reason I ask is because the servers that will be configured will likely be change for different users, so the client needs to be flexible when connecting to the services.
I've just now started looking at Sockets, but I'm not familiar enough with them to know if this would be the better option to achieve my objective.
Summary
I'm just looking for guidance, so if you can help direct me to some resources that will help me achieve my objective, I would appreciate it. I've searched extensively, but the majority of my searching either doesn't apply to my scenario, it is limited to a single server/client interaction, or it is limited to a single server with multiple clients.
Since I'm not sure what direction to go in, I don't have any code examples, although I have implemented the examples in the following Microsoft article: Windows Communication Foundation - Getting Started Tutorial
So you want to build a system of
multiple servers which execute commands on the computer they are running on
multiple clients which will receive the status of the commands executed on server or such information from the server
This would be my advice
Servers can be implemented as windows service. You will be able to administrate them easily this way using the services console or the scm. Checkout this link for a creating a simple C# service How do you write and use a Windows Service in C#?
Also, you can set the service to run as an in-built service user with different levels of permissions in addition to regular user accounts.
I have not used WCF, but usually clients connect to the server; this is a pretty common model, and hence all samples are such. Initiating connection from server is not a big deal (at least in a socket program), but just a bad model. You have to ask yourself, if no client is connected to your servers, how can they relay a status to the end user. You have to think clearly about the communication model. I would suggest a central repository of messages. It can be a file on a shared file system or a database or any such entity which can act as a data repository. This way all servers can convey there messages without caring if a client is connected or not. You can use Sockets to achieve what you want to do. Check the asychronous socket server sample from MSDN to understand how to do it.
Making the client run in the background and just have a notification area icon is also easy in c#. You can use NotifyIcon Class for that. This CodeProject article (Formless System Tray Application) demonstrates its usage. To show notification a la outlook style, you can refer to the following post: How to create form popup from from system tray on windows application (not web) with c#. Look at not only the accepted answer but other answers too; there are lot of useful links in it.
So far we have windows service talking over sockets, storing messages in a central repository and capable of handling multiple clients with toast style pops for client side notification.
You need a far richer client side GUI so the end users can take actions on the messages sent from the server. You can maintain a list of servers in app.config for the client that the client connects on startup. You should to provide a GUI for users to manage all servers and their connections.
Lat but not least, by building such a client server model, you are effectively building a security loophole in your systems. You should implement a good authorization mechanism. Checkout the following post: Authenticate user in WinForms (Nothing to do with ASP.Net)
EDIT:
You can also implement your server to accept "custom command" when you implement it as a service. This way, your client server communication will be standardized by using ServiceController to pass the command. This post might help: How to send a custom command to a .NET windows Service from .NET code?.
Don't get confused in the "command" terminology here. ServiceController issues standard commands to a service for start, stop, pause, resume and restart the service. These are the same items you see on the context menu when you right click a service in the services.msc snap-in. The same way a service can respond to custom commands. In your case the custom command maybe a request to execute a process.
Note that some mechanisms I have described are geared towards an intranet setup while others scale fine on both intranet and internet
I've developped a WPF composite application which is installed through MSI in c:\Program Files\WPFAPP1 on a Windows Server 2008.
Due to the targeted system environment constraint, several local windows account users launched the main .exe file (and thus start each one an instance of this WPF app) from a remote machine with a .RDP link.
Each Windows user is a known WPF application user (user access rights).
I would like to develop a .NET component to share data between users and provide a messenger-like feature : can I achieve this by using WCF service with named pipes please?
Thanks for your reply,
It is possible, but far from an ideal solution. I have used named pipes for inter-process communication, but only for time signalling where the 2 processes had to be synchronized. It was not very reliable and had its weaknesses.
Named pipes communication requires additional threads to be running all the time listening for messages and the other processes would have to know exactly which name key to use to communicate with a particular process.
Basically, you would be far better off creating a client/server architecture using WCF and have the clients send messages up to the server to be distributed to the other clients. You could use a duplex channel like NetTcp or WsHttp to push messages from server to client, or have clients poll the server for new messages.
I'm currently working on a project in c# where I have a service running as LocalSystem, and a user application (tray app) running for each logged on user.
I need to have communications between the two.
Initially I've set up an endpoint using NetTcpBinding on the service for the clients to connect to and supply their username. Thereafter the clients each set up an endpoint themselves as such; net.tcp://localhost:5001/UserApp/'username', with port sharing enabled. The service can then connect to that endpoint, knowing the username.
Though, when trying to get the program to work well with UAC I ran into some issues. Port sharing with UAC enabled requires the user to be registred in <'allowAccounts> of SMSvcHost.exe.config, and even though I've added the user, I still get the following errror when trying to register the endpoint;
The service endpoint failed to listen on the URI
'net.tcp://localhost:5001/UserApp/myuser' because access was denied.
Verify that the current user is granted access in the appropriate
allowAccounts section of SMSvcHost.exe.config.
I've also tried switching to NetNamedPipeBinding, which works well when hosting the user application. But when using this binding the service can not access the endpoints opened by the clients.
So, basically I need a way for a single service to provide an endpoint for multiple user applications on the same machine, and the service to be able to connect to and send event updates to multiple user applications.
Any suggestions?
in this case I would think about using callback channels instead of opening new services on the client (ok - it's almost the same but it fit nices into the WCF framework and setting).
You can read about this here: What you need to know about One-Way Calls, Callbacks, And Events
You may want to also look Duplex services, in particular the 'wsDualHttpBinding'. It is designed to do just want you are asking... to allow both the service and client to send messages independently to each other.
http://msdn.microsoft.com/en-us/library/ms731064.aspx