Remote Desktop - getting session information (id, session name, etc.) from client side

724 Views Asked by At

Let's consider the following scenario: take a Windows Server instance (2012 or newer), with multiple user accounts. Each of those accounts needs to run an individual instance of a target application, which requires an active GUI as well as orchestration, in an automated fashion. We have no control over this target application so we need to work around it.

After much research and experimenting trying to programmatically create interactive windows sessions (with a GUI) using win32 APIs such as WTS calls (or even LsaLogonUser), we gave up and tried creating these sessions using rdp or freerdp. This manages to create the required sessions.

Now for the issue at hand. Due to the nature of the target application as well as the fact that it requires orchestration and autonomous running (it needs to be triggered remotely, without user intervention), we opted for the following architecture:

  1. a windows service that exposes an API (which can be used as the trigger) - let's call this the "command center".
  2. a user-level application that is run automatically when each user logs on and receives commands from the previously mentioned service (via named pipes). Let's call this the "agent". This agent then automates the target application in respect to the commands received from the command center.

In order for the command center to properly push commands to each agent, each agent features a named pipe server that's named uniquely: agent_[username]_[sessionid]. This ensures that even if a particular user has multiple sessions running multiple agents, each one can be controlled individually.

In terms of triggering this functionality this is the flow:

  1. an HTTP Rest request is sent to the command center
  2. the command center programmatically creates a new session for the designated user using freerdp (C# with some C++)
  3. the session is created and the agent starts automatically (from a scheduled task)
  4. once the session is up and running the command center connects to the agent via the target named pipe server (as described in the naming scheme above).

Everything up to step 3 is done and works correctly, however, we're having issues determining the session id (and other session data) when creating new sessions (step 2), so that the command center knows the string id for the named pipe server (agent) which it needs to send commands to. In essence, it knows the username for which the session has been created but it lacks the session id.

What we need to do is figure out how to grab session data (mainly the session id) from the new freerdp session that's created. What we've thought about but haven't managed:

  1. Querying session info using the WTSQuerySessionInformationA API call - this is not really robust enough as you can't really reliably monitor newly created sessions and reconciliate with existing sessions for the same user.
  2. Creating the new freerdp session with custom session names (such as GUID), which would allow us to confidently identify and link sessions using the above API call. So far, all sessions that are created with freerdp have blank session names, so we haven't been able to assign custom names, but this might be a solution.
  3. Retrieving client info from the rdp_rdp object we're using to create the session - no luck so far, as the documentation is pretty limited and we haven't managed to obtain this information - this however seems like the most direct and sure way to solve our issue.

To sum things up, we need a way to communicate between multiple distinctly named agents and a service app - and for this we need to determine the session id or name for each newly created windows session. Is there any way to do this, or maybe alternative approaches we haven't though about?

Many thanks!

1

There are 1 best solutions below

0
On BEST ANSWER

To come back on this, I have not found any viable way of setting custom session id for newly created session using freerdp. It might be possible if someone studied the whole protocol and reverse engineered the freerdp project, but it's a titanic task.

In the end, we imposed a restriction of a single active session per user. This allows us to easily query and communicate with the mentioned agents using a named pipe server.