简体   繁体   中英

Detect source of remote desktop connection

This question tells me how to detect a remote desktop session.

Do anybody know if it's possible to find out from where the remote connection was initialized?

@Vegar, you can use the WTSEnumerateSessions and WTSQuerySessionInformation functions to retrieve this info.

check this link for an example using the Jedi Api Headers .

check this code.

program ProjectTsInfo;

{$APPTYPE CONSOLE}

Uses
  Windows,
  JwaWinType,
  JwaWtsApi32,
  JwaWinsock2,
  SysUtils,
  TypInfo;


type
  PWtsSessionInfoAArray = ^TWtsSessionInfoAArray;
  TWtsSessionInfoAArray = array[0..ANYSIZE_ARRAY-1] of WTS_SESSION_INFOA;

//Get the info for all clients connected
procedure GetAll_TSClientsInfo;
var
  SessionInfoAArray: PWtsSessionInfoAArray;
  ClientAddr       : PWtsClientAddress;
  ClientName       : PAnsiChar;
  //ClientInfo       : PWTSCLIENT;
  RetBytes         : Cardinal;
  IPAddr           : String;
  i                : integer;
  pCount           : Cardinal;
  SessionId        : Cardinal;
begin

  if WtsEnumerateSessions(WTS_CURRENT_SERVER, 0, 1, PWTS_SESSION_INFO(SessionInfoAArray),  pCount) then
  begin

    for i := 0 to pCount - 1 do
    begin
      SessionId:=SessionInfoAArray^[i].SessionId;
      WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientAddress, Pointer(ClientAddr), RetBytes);
      WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientName, Pointer(ClientName), RetBytes);
      //WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientInfo, Pointer(ClientInfo), RetBytes);  //This value is supported for Windows Server 2008 and Windows Vista with SP1.

     try
      case ClientAddr^.AddressFamily of
        AF_INET:
          IPAddr:= Format('%d.%d.%d.%d', [
            ClientAddr^.Address[2],
            ClientAddr^.Address[3],
            ClientAddr^.Address[4],
            ClientAddr^.Address[5]
            ]);
        else
        IPAddr:= '<unknow>';
      end;

      WriteLn(Format('Session Id  : %d ', [SessionId]));
      WriteLn(Format('Client Name : %s ', [ClientName]));
      WriteLn(Format('Station Name: %s ', [SessionInfoAArray^[i].pWinStationName]));
      WriteLn(Format('State       : %s ', [GetEnumName(TypeInfo(WTS_CONNECTSTATE_CLASS),integer(SessionInfoAArray^[i].State))]));
      WriteLn(Format('IP          : %s ', [IPAddr]));

      //supported for Windows Server 2008 and Windows Vista with SP1.
      {
      WriteLn(Format('ClientName      : %s ', [ClientInfo^.ClientName]));
      WriteLn(Format('Domain          : %s ', [ClientInfo^.Domain]));
      WriteLn(Format('UserName        : %s ', [ClientInfo^.UserName]));
      WriteLn(Format('WorkDirectory   : %s ', [ClientInfo^.WorkDirectory]));
      WriteLn(Format('InitialProgram  : %s ', [ClientInfo^.InitialProgram]));
      WriteLn(Format('EncryptionLevel : %d ', [ClientInfo^.EncryptionLevel]));
      WriteLn(Format('HRes            : %d ', [ClientInfo^.HRes]));
      WriteLn(Format('VRes            : %d ', [ClientInfo^.VRes]));
      WriteLn(Format('ColorDepth      : %d ', [ClientInfo^.ColorDepth]));
      WriteLn(Format('ClientDirectory : %s ', [ClientInfo^.ClientDirectory]));
      }
      Writeln('');

   finally
      WTSFreeMemory(ClientAddr);
      WTSFreeMemory(ClientName);
   end;
    end;
  end;

  WtsFreeMemory(SessionInfoAArray);
end;

//Get the ip address of the actual connected client
function GetIpActualClient : string;
var
  ClientAddr       : PWtsClientAddress;
  RetBytes         : Cardinal;
  IPAddr           : String;
  SessionId        : Cardinal;
begin
      SessionId:=WTS_CURRENT_SESSION;
      WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientAddress, Pointer(ClientAddr), RetBytes);
      try
        case ClientAddr^.AddressFamily of
          AF_INET:
            IPAddr:= Format('%d.%d.%d.%d', [
              ClientAddr^.Address[2],
              ClientAddr^.Address[3],
              ClientAddr^.Address[4],
              ClientAddr^.Address[5]
              ]);
          else
          IPAddr:= '<unknow>';
        end;
      Result:=IPAddr;
      finally
       WTSFreeMemory(ClientAddr);
      end;
end;

begin
  Writeln('IP Actual client '+GetIpActualClient);
  Writeln('-----------------------------------');

  GetAll_TSClientsInfo;
  Readln;
end.

UPDATE

As @Remko says, the WTSQuerySessionInformation function with the WTSClientAddress type, can return the local IP of the client. if you wanna get the real ip you can use the WinStationGetRemoteIPAddress helper function located in the JwaWinSta unit.

Var
Port    : Word;
IpAddr  : WideString;
Begin
WinStationGetRemoteIPAddress(WTS_CURRENT_SERVER,WTS_CURRENT_SESSION,IpAddr,Port);
End;

对我来说,这行得通,它获得了所连接机器的名称。

Environment.GetEnvironmentVariable("CLIENTNAME")

由于它在 Windows 中,因此使用 netstat 来检查您连接到哪些机器以及在哪些端口上,只需解析使用远程桌面使用的端口的地址即可。

WTSQuerySessionInformation returns the client IP as the client reports it, this will probably be (one) of it's local IP Address. If you want to know the REAL ip address and port that is connected you can use WinStationQueryInformationW with information class WinStationRemoteAddress. You will need my unit JwaWinsta from the Jedi Apilib.

I have provided a simple wrapper in the same unit as well:

function WinStationGetRemoteIPAddress(hServer: HANDLE; SessionId: DWORD;
  var RemoteIPAddress: WideString; var Port: WORD): Boolean;

尝试运行qwinsta

If you want to get the remote session ID and get the IP address that connected via Citrix you can use the below. This was designed to run when a user connects to a server via a citrix session and display/create a string for the IP address it is connecting from.

// Prints out ICA or RDP session ID of current user & gets ICA session clientAddress variable

using System;
using Microsoft.Win32;

namespace ViaRegedit
{
    class Program03
    {
        static void Main(string[] args)
        {
            // Obtain an instance of RegistryKey for the CurrentUser registry 
            RegistryKey rkCurrentUser = Registry.CurrentUser;
            // Obtain the test key (read-only) and display it.
            RegistryKey rkTest = rkCurrentUser.OpenSubKey("Remote");

            foreach (string valueName in rkTest.GetSubKeyNames())
            {
                //Getting path to RDP/Citrix session ID
                string RDPICApath = "";
                if (rkTest.OpenSubKey(valueName) != null && rkTest.OpenSubKey(valueName) != null) { RDPICApath = rkTest.OpenSubKey(valueName).ToString(); }
                Console.WriteLine("Getting CurrentUser ICA-RDP path from string = " + RDPICApath);

                //Split RDPICApath to get session number
                string RDPICAnumber = RDPICApath.Substring(RDPICApath.LastIndexOf('\\') + 1);
                Console.WriteLine("Current User RDPICAnumber = " + RDPICAnumber);

                //Getting reg local machine info for Citrix based on RDP/Citrix session ID "RDPICAnumber"
                string regLocal = @"SOFTWARE\Citrix\Ica\Session\" + RDPICAnumber + @"\Connection";
                RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64);
                RegistryKey citrixKey = localKey.OpenSubKey(regLocal);
                Console.WriteLine("Registry " + citrixKey + " Does Exist - going to get ClientAddress");
                //getting clietAddress var from citrixKey 
                string clientAddress = "";
                if (citrixKey != null && citrixKey.GetValue("clientAddress") != null)
                    {clientAddress = citrixKey.GetValue("clientAddress").ToString();}
                    Console.WriteLine("Getting current user clientAddress from string = " + clientAddress); 
            }
            rkTest.Close();
            rkCurrentUser.Close();
            Console.ReadLine();
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM