Capturing RDP Client IP in Credential Provider

Viewed 389

We have a custom credential provider running on windows server 2012, which calls APIs of our authentication server before allowing the user to login. We are also maintaining logs of our credential provider.

We now need to capture and log the IP address of the user who is logging in to the server using the remote desktop connection. Would it be possible to capture the IP address from inside credential provider? Does the serialized credential package sent by RDP client to the server contain this information? If yes, how to access it in credential provider?

1 Answers

You must get remote desktop session and read info:

int GetRDPClientIP(wstring& ip)
{
    if (DEVELOP_MODE) PrintLn(L"Call GetRDPClientIP func", __FILEW__, __FUNCTIONW__, __LINE__);
    WINSTATIONREMOTEADDRESS wsInfo;
    ULONG len;
    if (DEVELOP_MODE) PrintLn(L"Check remote desktop", __FILEW__, __FUNCTIONW__, __LINE__);
    if (WinStationQueryInformationW(0, LOGONID_CURRENT, WinStationRemoteAddress, &wsInfo, sizeof(wsInfo), &len))
    {
        if (DEVELOP_MODE) PrintLn(L"It is remote desktop (RDP)", __FILEW__, __FUNCTIONW__, __LINE__);
        ULONG cb;
        union {
            SOCKADDR sa;
            SOCKADDR_IN sa4;
            SOCKADDR_IN6 sa6;
        };
        switch (sa.sa_family = wsInfo.sin_family)
        {
        case AF_INET:
            if (DEVELOP_MODE) PrintLn(L"It is IPv4", __FILEW__, __FUNCTIONW__, __LINE__);
            sa4.sin_port = wsInfo.ipv4.sin_port;
            sa4.sin_addr.S_un.S_addr = wsInfo.ipv4.in_addr;
            RtlZeroMemory(sa4.sin_zero, sizeof(sa4.sin_zero));
            cb = sizeof(SOCKADDR_IN);
            break;
        case AF_INET6:
            if (DEVELOP_MODE) PrintLn(L"It is IPv6", __FILEW__, __FUNCTIONW__, __LINE__);
            sa6.sin6_port = wsInfo.ipv6.sin6_port;
            sa6.sin6_flowinfo = wsInfo.ipv6.sin6_flowinfo;
            memcpy(&sa6.sin6_addr, &wsInfo.ipv6.sin6_addr, sizeof(in6_addr));
            sa6.sin6_scope_id = wsInfo.ipv6.sin6_scope_id;
            cb = sizeof(SOCKADDR_IN6);
            break;
        default:
            if (DEVELOP_MODE) PrintLn(L"Error in IP version", __FILEW__, __FUNCTIONW__, __LINE__);
            return -1;
        }

        WSADATA wd;
        if (DEVELOP_MODE) PrintLn(L"Call WSAStartup", __FILEW__, __FUNCTIONW__, __LINE__);
        if (WSAStartup(WINSOCK_VERSION, &wd) == 0)
        {
            wchar_t AddressString[64];
            ULONG dwAddressStringLength = _countof(AddressString);

            if (WSAAddressToString(&sa, cb, 0, AddressString, &dwAddressStringLength) == 0)
            {
                if (DEVELOP_MODE) PrintLn((L"IP Address get successfully: " + wstring(AddressString, dwAddressStringLength)).c_str(), __FILEW__, __FUNCTIONW__, __LINE__);
                ip = wstring(AddressString, dwAddressStringLength);
                return 0;
            }
            else
            {
                if (DEVELOP_MODE) PrintLn((L"Error code WSAAddressToString: " + to_wstring(WSAGetLastError())).c_str(), __FILEW__, __FUNCTIONW__, __LINE__);
                return -1;
            }
        }
        else
        {
            if (DEVELOP_MODE) PrintLn((L"Error code WSAStartup: " + to_wstring(WSAGetLastError())).c_str(), __FILEW__, __FUNCTIONW__, __LINE__);
            return -1;
        }
    }

    if (DEVELOP_MODE) PrintLn(L"It is not remote desktop (RDP)", __FILEW__, __FUNCTIONW__, __LINE__);
    return 1;
}
Related