diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index a0e5fdbc5..f6e36d311 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -119,7 +119,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) { if (rpc->VirtualConnection->State >= VIRTUAL_CONNECTION_STATE_OPENED) { - printf("Receiving Out-of-Sequence RTS PDU\n"); + //printf("Receiving Out-of-Sequence RTS PDU\n"); rts_recv_out_of_sequence_pdu(rpc, buffer, header->common.frag_length); rpc_client_fragment_pool_return(rpc, fragment); diff --git a/libfreerdp/core/gateway/rts.c b/libfreerdp/core/gateway/rts.c index dbde640dc..15afc4625 100644 --- a/libfreerdp/core/gateway/rts.c +++ b/libfreerdp/core/gateway/rts.c @@ -841,9 +841,11 @@ int rts_recv_flow_control_ack_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) offset += rts_flow_control_ack_command_read(rpc, &buffer[offset], length - offset, &BytesReceived, &AvailableWindow, (BYTE*) &ChannelCookie) + 4; +#if 0 printf("BytesReceived: %d AvailableWindow: %d\n", BytesReceived, AvailableWindow); printf("ChannelCookie: " RPC_UUID_FORMAT_STRING "\n", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie)); +#endif rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow = AvailableWindow - (rpc->VirtualConnection->DefaultInChannel->BytesSent - BytesReceived); @@ -880,9 +882,11 @@ int rts_recv_flow_control_ack_with_destination_pdu(rdpRpc* rpc, BYTE* buffer, UI offset += rts_flow_control_ack_command_read(rpc, &buffer[offset], length - offset, &BytesReceived, &AvailableWindow, (BYTE*) &ChannelCookie) + 4; +#if 0 printf("Destination: %d BytesReceived: %d AvailableWindow: %d\n", Destination, BytesReceived, AvailableWindow); printf("ChannelCookie: " RPC_UUID_FORMAT_STRING "\n", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie)); +#endif rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow = AvailableWindow - (rpc->VirtualConnection->DefaultInChannel->BytesSent - BytesReceived); @@ -999,7 +1003,6 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) rts = (rpcconn_rts_hdr_t*) buffer; rts_extract_pdu_signature(rpc, &signature, rts); - rts_print_pdu_signature(rpc, &signature); SignatureId = rts_identify_pdu_signature(rpc, &signature, NULL); if (SignatureId == RTS_PDU_FLOW_CONTROL_ACK) @@ -1017,6 +1020,7 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) else { printf("Unimplemented signature id: 0x%08X\n", SignatureId); + rts_print_pdu_signature(rpc, &signature); } return 0; diff --git a/libfreerdp/core/gateway/tsg.c b/libfreerdp/core/gateway/tsg.c index 43778827f..92558a758 100644 --- a/libfreerdp/core/gateway/tsg.c +++ b/libfreerdp/core/gateway/tsg.c @@ -181,8 +181,11 @@ BOOL TsProxyCreateTunnelWriteRequest(rdpTsg* tsg) * * Using reduced capabilities appears to trigger * TSG_PACKET_TYPE_QUARENC_RESPONSE instead of TSG_PACKET_TYPE_CAPS_RESPONSE + * + * However, reduced capabilities may break connectivity with servers enforcing features, such as + * "Only allow connections from Remote Desktop Services clients that support RD Gateway messaging" */ - NapCapabilities = TSG_NAP_CAPABILITY_IDLE_TIMEOUT; + //NapCapabilities = TSG_NAP_CAPABILITY_IDLE_TIMEOUT; *((UINT32*) &buffer[44]) = NapCapabilities; /* capabilities */ diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index 5ffff741b..fe630a880 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -112,6 +112,7 @@ NTLM_CONTEXT* ntlm_ContextNew() context->NTLMv2 = TRUE; context->UseMIC = FALSE; context->SendVersionInfo = TRUE; + context->SendSingleHostData = FALSE; status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\WinPR\\NTLM"), 0, KEY_READ | KEY_WOW64_64KEY, &hKey); @@ -126,6 +127,9 @@ NTLM_CONTEXT* ntlm_ContextNew() if (RegQueryValueEx(hKey, _T("SendVersionInfo"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) context->SendVersionInfo = dwValue ? 1 : 0; + if (RegQueryValueEx(hKey, _T("SendSingleHostData"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) + context->SendSingleHostData = dwValue ? 1 : 0; + RegCloseKey(hKey); } diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.h b/winpr/libwinpr/sspi/NTLM/ntlm.h index 1c8ad520b..fe79b7554 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.h +++ b/winpr/libwinpr/sspi/NTLM/ntlm.h @@ -92,7 +92,7 @@ enum _NTLM_AV_ID MsvAvDnsTreeName, MsvAvFlags, MsvAvTimestamp, - MsvAvRestrictions, + MsvAvSingleHost, MsvAvTargetName, MsvChannelBindings }; @@ -126,15 +126,15 @@ struct _NTLM_VERSION_INFO }; typedef struct _NTLM_VERSION_INFO NTLM_VERSION_INFO; -struct _NTLM_RESTRICTION_ENCODING +struct _NTLM_SINGLE_HOST_DATA { UINT32 Size; UINT32 Z4; - UINT32 IntegrityLevel; - UINT32 SubjectIntegrityLevel; + UINT32 DataPresent; + UINT32 CustomData; BYTE MachineID[32]; }; -typedef struct _NTLM_RESTRICTION_ENCODING NTLM_RESTRICTION_ENCODING; +typedef struct _NTLM_SINGLE_HOST_DATA NTLM_SINGLE_HOST_DATA; struct _NTLM_RESPONSE { @@ -244,6 +244,8 @@ struct _NTLM_CONTEXT BYTE* ChannelBindingToken; BYTE ChannelBindingsHash[16]; SecPkgContext_Bindings Bindings; + BOOL SendSingleHostData; + NTLM_SINGLE_HOST_DATA SingleHostData; SecBuffer NegotiateMessage; SecBuffer ChallengeMessage; SecBuffer AuthenticateMessage; diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c index bfa2d91c8..d27a54628 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c @@ -279,6 +279,19 @@ void ntlm_compute_channel_bindings(NTLM_CONTEXT* context) MD5_Final(context->ChannelBindingsHash, &md5); } +BYTE ntlm_MachineID[32] = + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF"; + +void ntlm_compute_single_host_data(NTLM_CONTEXT* context) +{ + context->SingleHostData.Size = 48; + context->SingleHostData.Z4 = 0; + context->SingleHostData.DataPresent = 1; + context->SingleHostData.CustomData = 0x2000; + CopyMemory(context->SingleHostData.MachineID, ntlm_MachineID, 32); +} + void ntlm_construct_challenge_target_info(NTLM_CONTEXT* context) { int length; @@ -383,9 +396,6 @@ void ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context) AvPairsValueLength += 4; } - //AvPairsCount++; /* MsvAvRestrictions */ - //AvPairsValueLength += 48; - /** * Extended Protection for Authentication: * http://blogs.technet.com/b/srd/archive/2009/12/08/extended-protection-for-authentication.aspx @@ -407,6 +417,13 @@ void ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context) AvPairsCount++; /* MsvAvTargetName */ AvPairsValueLength += context->ServicePrincipalName.Length; } + + if (context->SendSingleHostData) + { + AvPairsCount++; /* MsvAvSingleHost */ + ntlm_compute_single_host_data(context); + AvPairsValueLength += context->SingleHostData.Size; + } } size = ntlm_av_pair_list_size(AvPairsCount, AvPairsValueLength); @@ -453,6 +470,12 @@ void ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context) (PBYTE) context->ServicePrincipalName.Buffer, context->ServicePrincipalName.Length); } + + if (context->SendSingleHostData) + { + ntlm_av_pair_add(AuthenticateTargetInfo, MsvAvSingleHost, + (PBYTE) &context->SingleHostData, context->SingleHostData.Size); + } } if (context->NTLMv2)