I need to implement a dead man's switch in my application. If the application is running from RDP, I need to act if it loses connection to the remote client.
I know when I am running in RDP by using
GetSystemMetrics(SystemMetric.SM_REMOTESESSION)
But when the client closes without signing out, the session will continue. This is the scenario I want to react to, but I don't know how to detect a client disconnecting. I need to know if there is an active RDP user or not.
I could potentially find the remote endpoint by watching the RDP port, but as think could potentially be setup on a non-default port, I'd like to avoid this solution if a better one exists.
I'd prefer a solution that was not specific to WinForms, WPF, UWP etc. Bonus points if it works with .NET Core as well.
Not a .NET Core solution, but a windows API one. There are session change notifications that you can opt into via WTSRegisterSessionNotification (and similarly unregister later).
These notifications are then delivered in your windows message loop, so you need to be running one. (WinForms and WPF do, and there are specific mechanisms to allow you to perform custom message handling)
You'll then get notified when the session becomes locked or disconnected.
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.
I've tried researching this, but haven't found much that sounds similar to something I'm needing to implement. In short, we'll be running an ASP Website on a server that will be accessed by clients. Ideally, we have a function that we want to initialize upon the start of a user's session, and stop when the session ends. While the session is happening, this function sends and receives messages via socket communication, meaning we need to access the send/receive functions of this class from pages in order to move information. What's the best way to go about this?
Look into SignalR. That's probably what you're wanting. Its "hubs" are effectively what you're looking for to spin up on session initiation, and spin down when the user disappears. It has a client-side JS library that automatically chooses the best connection method available (e.g., websockets > server-sent-events > long-polling), and it allows you to send messages both from the client to the server, and from the server to the client.
http://www.asp.net/signalr
Another alternative that I've played around with in the past is XSockets:
https://xsockets.net/
It's similar to SignalR in many respects, but it's not free.
It's hard to tell from you description, are you looking to communicate with the client browser via sockets? Or are you trying to communicate with some other service via sockets?
Web applications are not ideally suited for deterministic types of actions. It's difficult for the web server to know whether or not the client has actually closed their browser or not. In most cases, sessions simply time out after a period of inactivity (20+ minutes in most cases). So you cannot reliably know when the users session has actually ended.
To top it off, there are certain edge cases where Session_End will not fire. For instance, if the app pool recycles, then no Session_End event will fire. This may not be an issue, since if the app pool recycles your other connections would also recycle, but it's still an issue to keep in mind.
Finally, Web apps are not intended to be long running.
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 am writing you because of a new problem I need to solve, and I have now been banging my head against a wall for too long now.
Basically, I need to create an application that can take care of the following:
A user starts an app, which sends a broadcast to the subnet, and recieves a response of all servers there with their IP (and some additional info). The user can then select what server he wants to connect to.
Making it work is simple enough, with identifying the subnet, and broadcasting with UDP, and then having a different server application recieving it and sending back a response . The problem lies with these restrictions, that I need to take into consideration:
There will most likely also be clients on the server machines in the network, meaning that we can assume that the application is present on all machines. Every machine needs to have the listener running, and every machine can launch the GUI for selecting a server.
I am only allowed to add one exception to the firewall - an exception that handles both sending out the broadcasts, recieving broadcasts, sending answers and recieving answers.
I should also only be adding one Windows Service
on a server machine, the listener should run as a windows service, so the user won't notice it. Nor will the user notice, that the response is sent back to the client.
On the client machine, the user can start an application, which will notify the application to emmit the broadcast, and will get all the server responses, so the user can choose one to connect to.
Besides from the application that the user launches in order to select a server, there should be no interaction with the user whatsoever. Not even a popup, requesting the user to allow traffic trough the firewall - it should all be automatically
It needs to work on and in between Win XP, Win Vista and Win 7.
I don't know if I am putting too many constrains on myself, but I really hope that I can make the application with these requirements.
I have a few ideas - I just need to figure out how to do it:
Should i make everything into one application, that I add to the firewall exception list, so it will take care of the traffic on both the server and the client machines?
Should I add a custom exception to the firewall, allowing UDP traffic on a specific port, and then have all traffic flow trough that?
Is there a third and better option for managing that?
It is OK to have the service running on both client and server machines. But can it take care of everything for me - like it handling both the broadcast send/recieve and answer send/recieve? And is there any way to extract the information about servers on the network from a service?
I know it is a lot, but I really hope that you will be able to help me out.
let me know if I wasn't clear enough, or if you need further explanations.
I am coding in C# .Net, and I can utilize all I want from the .Net framework. As soon as I have this functionality implemented
All the best
/Sagi
The kind of peer-to-peer networking problems become simple to the point of being trivial if you designate one machine as the master server. It should have a well-known name that all sub-servers can connect to so they can publish (and withdraw) their availability. A client can then send a query request to the same server and get a list of known servers in return.
This can also solve your firewall problem, the master server could be listening on port 80.
Look into the System.Net.PeerToPeer namespace for a p2p solution supported by the framework.
Maybe a UPnP server and client may be a solution to your problem?
I have a windows service written in C# .NET framework 3.5 and would like to know the best way to check if previous shutdown of a service was regular.
Upon starting the service, there should be a check if the last shutdown was regular (via stop service button in services management) or if somebody just killed the process (or it crashed for some reason not directly linked to the service itself).
I thought about writing encrypted XML on a hard drive upon starting a service, and then editing it with some values when service is being stopped. In that way, after I start the service again next time, I could check the XML and see if the values were edited in correct way during shutdown, and if they were not I'd know the process was killed or it crashed.
This way seems too unreliable and not a good practice. What do you suggest?
Clarification:
What the service does is it sits on a server and listens to connections from client machines. Once the connection has been established, it communicates to a remote database via web services and determines whether they have right to connect (and therefore use application that is the caller). One of the aspects of protection is concurrency check, and if I have a limit set to 5 work stations, I keep the TcpClient connection alive from windows service to, let's say 5 workstations, and the sixth one cannot connect.
If I kill the service process and restart it, the connections are gone and I have 5 "licensed" apps running on workstations, and now there are 5 free connection slots to be taken by 5 more.
I also cant see anything bad using a file. You could even use this file to log some more information.
Eg. you could attach to the AppDomains Unhanded Exception event and try to log that exception.
Or you could evaluate how log your service has been running/not running (parsing a logfile for that task is a little bit harder).
Of course - this is not an excuse for not using logfiles.
I went with this in the end:
Service used to check up on the connected workstations to see if they're alive, but now I've built in periodical check from all the workstations as well (they connect through a common router dll where I've built in the check). Every 10 seconds the connection is verified, and if there is none, the client will try to reconnect in 15 seconds, which will be successful if there was just a temporary network problem, but will fail if the service was shut down forcefully (since all it's Tcp objects will be lost).
I would suggest to use the EventLog. Add a log event when a service start or stops and read through the event logs to detect anomalies.
Here's a basic sample from CodeProject.
Here's a walkthrough from MSDN how to create/delete/read event logs and entries.
Unless the service is running some sort securiy system that you need to have a "tamper" proof system i dont see why using a file is a bad solution.
Personaly i think a encrpted xml file is overkill, a simple text file should be enough.
I think you are on the right track, I'm not sure why you want to edit the values, just use the file (or a registry key) as a marker to indicate that the service was started and is running. During a graceful shutdown remove the marker. You then just need to look for the existence of the marker to know whether you were shutdown gracefully or crashed.
If you are finding that the file isn't created reliably, then make sure you are closing and flushing and disposing of the file object rather than relying on the garbage collector.
--- EDIT following clarification ---
So the requirement is for a licensing system and not simply to determine if the service was shutdown gracefully. I'm guessing that the desire is for the 'licenses' to be cleared on a graceful shutdown and restored following a crash, the scenarios are interchangeable.
I would probably use a database backing store, with suitable security, to hold the license keys at the server. As each client connects and requests a license they are provided with a key that has to be presented for each communication from the client. The server is obviously verifying that the presented key is valid for the current session. Should the server be gracefully shutdown it can clear the key table, if it crashes then the keys would still be present and can be honoured. That's probably the simplest approach I can think of that's secure.
If there's yet more to the story then let us know.