Merge pull request #4907 from akallabeth/transport_write_leak_fix

Transport write leak fix
This commit is contained in:
Martin Fleisz 2018-10-29 14:54:55 +01:00 committed by GitHub
commit 7b0f4f5dc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 531 additions and 435 deletions

View File

@ -56,10 +56,7 @@ BOOL rdp_recv_server_synchronize_pdu(rdpRdp* rdp, wStream* s)
BOOL rdp_send_server_synchronize_pdu(rdpRdp* rdp)
{
wStream* s;
s = rdp_data_pdu_init(rdp);
wStream* s = rdp_data_pdu_init(rdp);
rdp_write_synchronize_pdu(s, rdp->settings);
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->userId);
}
@ -67,7 +64,6 @@ BOOL rdp_send_server_synchronize_pdu(rdpRdp* rdp)
BOOL rdp_recv_client_synchronize_pdu(rdpRdp* rdp, wStream* s)
{
UINT16 messageType;
rdp->finalize_sc_pdus |= FINALIZE_SC_SYNCHRONIZE_PDU;
if (Stream_GetRemainingLength(s) < 4)
@ -80,18 +76,13 @@ BOOL rdp_recv_client_synchronize_pdu(rdpRdp* rdp, wStream* s)
/* targetUser (2 bytes) */
Stream_Seek_UINT16(s);
return TRUE;
}
BOOL rdp_send_client_synchronize_pdu(rdpRdp* rdp)
{
wStream* s;
s = rdp_data_pdu_init(rdp);
wStream* s = rdp_data_pdu_init(rdp);
rdp_write_synchronize_pdu(s, rdp->settings);
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SYNCHRONIZE, rdp->mcs->userId);
}
@ -103,7 +94,6 @@ BOOL rdp_recv_control_pdu(wStream* s, UINT16* action)
Stream_Read_UINT16(s, *action); /* action (2 bytes) */
Stream_Seek_UINT16(s); /* grantId (2 bytes) */
Stream_Seek_UINT32(s); /* controlId (4 bytes) */
return TRUE;
}
@ -118,7 +108,7 @@ BOOL rdp_recv_server_control_pdu(rdpRdp* rdp, wStream* s)
{
UINT16 action;
if(rdp_recv_control_pdu(s, &action) == FALSE)
if (rdp_recv_control_pdu(s, &action) == FALSE)
return FALSE;
switch (action)
@ -138,37 +128,26 @@ BOOL rdp_recv_server_control_pdu(rdpRdp* rdp, wStream* s)
BOOL rdp_send_server_control_cooperate_pdu(rdpRdp* rdp)
{
wStream* s;
s = rdp_data_pdu_init(rdp);
wStream* s = rdp_data_pdu_init(rdp);
Stream_Write_UINT16(s, CTRLACTION_COOPERATE); /* action (2 bytes) */
Stream_Write_UINT16(s, 0); /* grantId (2 bytes) */
Stream_Write_UINT32(s, 0); /* controlId (4 bytes) */
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->userId);
}
BOOL rdp_send_server_control_granted_pdu(rdpRdp* rdp)
{
wStream* s;
s = rdp_data_pdu_init(rdp);
wStream* s = rdp_data_pdu_init(rdp);
Stream_Write_UINT16(s, CTRLACTION_GRANTED_CONTROL); /* action (2 bytes) */
Stream_Write_UINT16(s, rdp->mcs->userId); /* grantId (2 bytes) */
Stream_Write_UINT32(s, 0x03EA); /* controlId (4 bytes) */
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->userId);
}
BOOL rdp_send_client_control_pdu(rdpRdp* rdp, UINT16 action)
{
wStream* s;
s = rdp_data_pdu_init(rdp);
wStream* s = rdp_data_pdu_init(rdp);
rdp_write_client_control_pdu(s, action);
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_CONTROL, rdp->mcs->userId);
}
@ -193,17 +172,14 @@ void rdp_write_client_persistent_key_list_pdu(wStream* s, rdpSettings* settings)
Stream_Write_UINT8(s, PERSIST_FIRST_PDU | PERSIST_LAST_PDU); /* bBitMask (1 byte) */
Stream_Write_UINT8(s, 0); /* pad1 (1 byte) */
Stream_Write_UINT16(s, 0); /* pad3 (2 bytes) */
/* entries */
}
BOOL rdp_send_client_persistent_key_list_pdu(rdpRdp* rdp)
{
wStream* s;
s = rdp_data_pdu_init(rdp);
rdp_write_client_persistent_key_list_pdu(s, rdp->settings);
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST, rdp->mcs->userId);
}
@ -225,11 +201,8 @@ void rdp_write_client_font_list_pdu(wStream* s, UINT16 flags)
BOOL rdp_send_client_font_list_pdu(rdpRdp* rdp, UINT16 flags)
{
wStream* s;
s = rdp_data_pdu_init(rdp);
wStream* s = rdp_data_pdu_init(rdp);
rdp_write_client_font_list_pdu(s, flags);
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_LIST, rdp->mcs->userId);
}
@ -251,7 +224,7 @@ BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, wStream* s)
{
rdp->finalize_sc_pdus |= FINALIZE_SC_FONT_MAP_PDU;
if(Stream_GetRemainingLength(s) >= 8)
if (Stream_GetRemainingLength(s) >= 8)
{
Stream_Seek_UINT16(s); /* numberEntries (2 bytes) */
Stream_Seek_UINT16(s); /* totalNumEntries (2 bytes) */
@ -265,14 +238,11 @@ BOOL rdp_recv_client_font_map_pdu(rdpRdp* rdp, wStream* s)
BOOL rdp_send_server_font_map_pdu(rdpRdp* rdp)
{
wStream* s;
s = rdp_data_pdu_init(rdp);
Stream_Write_UINT16(s, 0); /* numberEntries (2 bytes) */
Stream_Write_UINT16(s, 0); /* totalNumEntries (2 bytes) */
Stream_Write_UINT16(s, FONTLIST_FIRST | FONTLIST_LAST); /* mapFlags (2 bytes) */
Stream_Write_UINT16(s, 4); /* entrySize (2 bytes) */
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FONT_MAP, rdp->mcs->userId);
}
@ -308,7 +278,7 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
Stream_Seek(s, lengthSourceDescriptor); /* sourceDescriptor (should be 0x00) */
}
while(0);
while (0);
}
rdp_client_transition_to_state(rdp, CONNECTION_STATE_CAPABILITIES_EXCHANGE);
@ -327,22 +297,17 @@ BOOL rdp_recv_deactivate_all(rdpRdp* rdp, wStream* s)
BOOL rdp_send_deactivate_all(rdpRdp* rdp)
{
wStream* s;
wStream* s = rdp_send_stream_pdu_init(rdp);
BOOL status;
if (!(s = Stream_New(NULL, 1024)))
if (!s)
return FALSE;
rdp_init_stream_pdu(rdp, s);
Stream_Write_UINT32(s, rdp->settings->ShareId); /* shareId (4 bytes) */
Stream_Write_UINT16(s, 1); /* lengthSourceDescriptor (2 bytes) */
Stream_Write_UINT8(s, 0); /* sourceDescriptor (should be 0x00) */
status = rdp_send_pdu(rdp, s, PDU_TYPE_DEACTIVATE_ALL, rdp->mcs->userId);
Stream_Free(s, TRUE);
Stream_Release(s);
return status;
}
@ -364,30 +329,30 @@ BOOL rdp_server_accept_client_control_pdu(rdpRdp* rdp, wStream* s)
BOOL rdp_server_accept_client_font_list_pdu(rdpRdp* rdp, wStream* s)
{
rdpSettings *settings = rdp->settings;
freerdp_peer *peer = rdp->context->peer;
rdpSettings* settings = rdp->settings;
freerdp_peer* peer = rdp->context->peer;
if (!rdp_recv_client_font_list_pdu(s))
return FALSE;
if (settings->SupportMonitorLayoutPdu && settings->MonitorCount && peer->AdjustMonitorsLayout &&
peer->AdjustMonitorsLayout(peer))
peer->AdjustMonitorsLayout(peer))
{
/* client supports the monitorLayout PDU, let's send him the monitors if any */
wStream *st;
wStream* st = rdp_data_pdu_init(rdp);
BOOL r;
st = rdp_data_pdu_init(rdp);
if (!st)
return FALSE;
if (!rdp_write_monitor_layout_pdu(st, settings->MonitorCount, settings->MonitorDefArray))
{
Stream_Free(st, TRUE);
Stream_Release(st);
return FALSE;
}
r = rdp_send_data_pdu(rdp, st, DATA_PDU_TYPE_MONITOR_LAYOUT, 0);
if (!r)
return FALSE;
}

View File

@ -59,100 +59,97 @@ typedef struct
UINT16 responseType;
} AUTODETECT_RSP_PDU;
static BOOL autodetect_send_rtt_measure_request(rdpContext* context, UINT16 sequenceNumber, UINT16 requestType)
static BOOL autodetect_send_rtt_measure_request(rdpContext* context, UINT16 sequenceNumber,
UINT16 requestType)
{
wStream* s;
s = rdp_message_channel_pdu_init(context->rdp);
if (!s)
return FALSE;
WLog_VRB(AUTODETECT_TAG, "sending RTT Measure Request PDU");
Stream_Write_UINT8(s, 0x06); /* headerLength (1 byte) */
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
Stream_Write_UINT16(s, requestType); /* requestType (2 bytes) */
context->rdp->autodetect->rttMeasureStartTime = GetTickCountPrecise();
return rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ);
}
static BOOL autodetect_send_continuous_rtt_measure_request(rdpContext* context, UINT16 sequenceNumber)
static BOOL autodetect_send_continuous_rtt_measure_request(rdpContext* context,
UINT16 sequenceNumber)
{
return autodetect_send_rtt_measure_request(context, sequenceNumber, RDP_RTT_REQUEST_TYPE_CONTINUOUS);
return autodetect_send_rtt_measure_request(context, sequenceNumber,
RDP_RTT_REQUEST_TYPE_CONTINUOUS);
}
BOOL autodetect_send_connecttime_rtt_measure_request(rdpContext* context, UINT16 sequenceNumber)
{
return autodetect_send_rtt_measure_request(context, sequenceNumber, RDP_RTT_REQUEST_TYPE_CONNECTTIME);
return autodetect_send_rtt_measure_request(context, sequenceNumber,
RDP_RTT_REQUEST_TYPE_CONNECTTIME);
}
static BOOL autodetect_send_rtt_measure_response(rdpRdp* rdp, UINT16 sequenceNumber)
{
wStream* s;
/* Send the response PDU to the server */
s = rdp_message_channel_pdu_init(rdp);
if (!s)
return FALSE;
WLog_VRB(AUTODETECT_TAG, "sending RTT Measure Response PDU");
Stream_Write_UINT8(s, 0x06); /* headerLength (1 byte) */
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_RESPONSE); /* headerTypeId (1 byte) */
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
Stream_Write_UINT16(s, RDP_RTT_RESPONSE_TYPE); /* responseType (1 byte) */
return rdp_send_message_channel_pdu(rdp, s, SEC_AUTODETECT_RSP);
}
static BOOL autodetect_send_bandwidth_measure_start(rdpContext* context, UINT16 sequenceNumber, UINT16 requestType)
static BOOL autodetect_send_bandwidth_measure_start(rdpContext* context, UINT16 sequenceNumber,
UINT16 requestType)
{
wStream* s;
s = rdp_message_channel_pdu_init(context->rdp);
if (!s)
return FALSE;
WLog_VRB(AUTODETECT_TAG, "sending Bandwidth Measure Start PDU");
Stream_Write_UINT8(s, 0x06); /* headerLength (1 byte) */
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
Stream_Write_UINT16(s, requestType); /* requestType (2 bytes) */
return rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ);
}
static BOOL autodetect_send_continuous_bandwidth_measure_start(rdpContext* context, UINT16 sequenceNumber)
static BOOL autodetect_send_continuous_bandwidth_measure_start(rdpContext* context,
UINT16 sequenceNumber)
{
return autodetect_send_bandwidth_measure_start(context, sequenceNumber, RDP_BW_START_REQUEST_TYPE_CONTINUOUS);
return autodetect_send_bandwidth_measure_start(context, sequenceNumber,
RDP_BW_START_REQUEST_TYPE_CONTINUOUS);
}
BOOL autodetect_send_connecttime_bandwidth_measure_start(rdpContext* context, UINT16 sequenceNumber)
{
return autodetect_send_bandwidth_measure_start(context, sequenceNumber, RDP_BW_START_REQUEST_TYPE_CONNECTTIME);
return autodetect_send_bandwidth_measure_start(context, sequenceNumber,
RDP_BW_START_REQUEST_TYPE_CONNECTTIME);
}
BOOL autodetect_send_bandwidth_measure_payload(rdpContext* context, UINT16 payloadLength, UINT16 sequenceNumber)
BOOL autodetect_send_bandwidth_measure_payload(rdpContext* context, UINT16 payloadLength,
UINT16 sequenceNumber)
{
wStream* s;
UCHAR *buffer = NULL;
UCHAR* buffer = NULL;
BOOL bResult = FALSE;
s = rdp_message_channel_pdu_init(context->rdp);
if (!s)
return FALSE;
WLog_VRB(AUTODETECT_TAG, "sending Bandwidth Measure Payload PDU -> payloadLength=%"PRIu16"", payloadLength);
WLog_VRB(AUTODETECT_TAG, "sending Bandwidth Measure Payload PDU -> payloadLength=%"PRIu16"",
payloadLength);
/* 4-bytes aligned */
payloadLength &= ~3;
@ -161,14 +158,15 @@ BOOL autodetect_send_bandwidth_measure_payload(rdpContext* context, UINT16 paylo
Stream_Release(s);
return FALSE;
}
Stream_Write_UINT8(s, 0x08); /* headerLength (1 byte) */
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
Stream_Write_UINT16(s, RDP_BW_PAYLOAD_REQUEST_TYPE); /* requestType (2 bytes) */
Stream_Write_UINT16(s, payloadLength); /* payloadLength (2 bytes) */
/* Random data (better measurement in case the line is compressed) */
buffer = (UCHAR *)malloc(payloadLength);
buffer = (UCHAR*)malloc(payloadLength);
if (NULL == buffer)
{
Stream_Release(s);
@ -177,40 +175,36 @@ BOOL autodetect_send_bandwidth_measure_payload(rdpContext* context, UINT16 paylo
winpr_RAND(buffer, payloadLength);
Stream_Write(s, buffer, payloadLength);
bResult = rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ);
if (!bResult)
{
Stream_Release(s);
}
free(buffer);
return bResult;
}
static BOOL autodetect_send_bandwidth_measure_stop(rdpContext* context, UINT16 payloadLength, UINT16 sequenceNumber, UINT16 requestType)
static BOOL autodetect_send_bandwidth_measure_stop(rdpContext* context, UINT16 payloadLength,
UINT16 sequenceNumber, UINT16 requestType)
{
wStream* s;
UCHAR *buffer = NULL;
UCHAR* buffer = NULL;
BOOL bResult = FALSE;
s = rdp_message_channel_pdu_init(context->rdp);
if (!s)
return FALSE;
WLog_VRB(AUTODETECT_TAG, "sending Bandwidth Measure Stop PDU -> payloadLength=%"PRIu16"", payloadLength);
WLog_VRB(AUTODETECT_TAG, "sending Bandwidth Measure Stop PDU -> payloadLength=%"PRIu16"",
payloadLength);
/* 4-bytes aligned */
payloadLength &= ~3;
Stream_Write_UINT8(s, requestType == RDP_BW_STOP_REQUEST_TYPE_CONNECTTIME ? 0x08 : 0x06); /* headerLength (1 byte) */
Stream_Write_UINT8(s, requestType == RDP_BW_STOP_REQUEST_TYPE_CONNECTTIME ? 0x08 :
0x06); /* headerLength (1 byte) */
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_REQUEST); /* headerTypeId (1 byte) */
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
Stream_Write_UINT16(s, requestType); /* requestType (2 bytes) */
if (requestType == RDP_BW_STOP_REQUEST_TYPE_CONNECTTIME)
{
Stream_Write_UINT16(s, payloadLength); /* payloadLength (2 bytes) */
if (payloadLength > 0)
{
if (!Stream_EnsureRemainingCapacity(s, payloadLength))
@ -221,6 +215,7 @@ static BOOL autodetect_send_bandwidth_measure_stop(rdpContext* context, UINT16 p
/* Random data (better measurement in case the line is compressed) */
buffer = malloc(payloadLength);
if (NULL == buffer)
{
Stream_Release(s);
@ -233,52 +228,49 @@ static BOOL autodetect_send_bandwidth_measure_stop(rdpContext* context, UINT16 p
}
bResult = rdp_send_message_channel_pdu(context->rdp, s, SEC_AUTODETECT_REQ);
if (!bResult)
{
Stream_Release(s);
}
free(buffer);
return bResult;
}
static BOOL autodetect_send_continuous_bandwidth_measure_stop(rdpContext* context, UINT16 sequenceNumber)
static BOOL autodetect_send_continuous_bandwidth_measure_stop(rdpContext* context,
UINT16 sequenceNumber)
{
return autodetect_send_bandwidth_measure_stop(context, 0, sequenceNumber, RDP_BW_STOP_REQUEST_TYPE_CONTINUOUS);
return autodetect_send_bandwidth_measure_stop(context, 0, sequenceNumber,
RDP_BW_STOP_REQUEST_TYPE_CONTINUOUS);
}
BOOL autodetect_send_connecttime_bandwidth_measure_stop(rdpContext* context, UINT16 payloadLength, UINT16 sequenceNumber)
BOOL autodetect_send_connecttime_bandwidth_measure_stop(rdpContext* context, UINT16 payloadLength,
UINT16 sequenceNumber)
{
return autodetect_send_bandwidth_measure_stop(context, payloadLength, sequenceNumber, RDP_BW_STOP_REQUEST_TYPE_CONNECTTIME);
return autodetect_send_bandwidth_measure_stop(context, payloadLength, sequenceNumber,
RDP_BW_STOP_REQUEST_TYPE_CONNECTTIME);
}
static BOOL autodetect_send_bandwidth_measure_results(rdpRdp* rdp, UINT16 responseType, UINT16 sequenceNumber)
static BOOL autodetect_send_bandwidth_measure_results(rdpRdp* rdp, UINT16 responseType,
UINT16 sequenceNumber)
{
BOOL success = TRUE;
wStream* s;
UINT32 timeDelta;
/* Compute the total time */
timeDelta = GetTickCountPrecise() - rdp->autodetect->bandwidthMeasureStartTime;
/* Send the result PDU to the server */
s = rdp_message_channel_pdu_init(rdp);
if (!s)
return FALSE;
WLog_VRB(AUTODETECT_TAG, "sending Bandwidth Measure Results PDU -> timeDelta=%"PRIu32", byteCount=%"PRIu32"", timeDelta, rdp->autodetect->bandwidthMeasureByteCount);
WLog_VRB(AUTODETECT_TAG,
"sending Bandwidth Measure Results PDU -> timeDelta=%"PRIu32", byteCount=%"PRIu32"", timeDelta,
rdp->autodetect->bandwidthMeasureByteCount);
Stream_Write_UINT8(s, 0x0E); /* headerLength (1 byte) */
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_RESPONSE); /* headerTypeId (1 byte) */
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
Stream_Write_UINT16(s, responseType); /* responseType (1 byte) */
Stream_Write_UINT32(s, timeDelta); /* timeDelta (4 bytes) */
Stream_Write_UINT32(s, rdp->autodetect->bandwidthMeasureByteCount); /* byteCount (4 bytes) */
IFCALLRET(rdp->autodetect->ClientBandwidthMeasureResult, success,
rdp->context, rdp->autodetect);
rdp->context, rdp->autodetect);
if (!success)
return FALSE;
@ -289,7 +281,6 @@ static BOOL autodetect_send_bandwidth_measure_results(rdpRdp* rdp, UINT16 respon
static BOOL autodetect_send_netchar_result(rdpContext* context, UINT16 sequenceNumber)
{
wStream* s;
s = rdp_message_channel_pdu_init(context->rdp);
if (!s)
@ -323,38 +314,37 @@ static BOOL autodetect_send_netchar_result(rdpContext* context, UINT16 sequenceN
BOOL autodetect_send_netchar_sync(rdpRdp* rdp, UINT16 sequenceNumber)
{
wStream* s;
/* Send the response PDU to the server */
s = rdp_message_channel_pdu_init(rdp);
if (!s)
return FALSE;
WLog_VRB(AUTODETECT_TAG, "sending Network Characteristics Sync PDU -> bandwidth=%"PRIu32", rtt=%"PRIu32"", rdp->autodetect->netCharBandwidth, rdp->autodetect->netCharAverageRTT);
WLog_VRB(AUTODETECT_TAG,
"sending Network Characteristics Sync PDU -> bandwidth=%"PRIu32", rtt=%"PRIu32"",
rdp->autodetect->netCharBandwidth, rdp->autodetect->netCharAverageRTT);
Stream_Write_UINT8(s, 0x0E); /* headerLength (1 byte) */
Stream_Write_UINT8(s, TYPE_ID_AUTODETECT_RESPONSE); /* headerTypeId (1 byte) */
Stream_Write_UINT16(s, sequenceNumber); /* sequenceNumber (2 bytes) */
Stream_Write_UINT16(s, RDP_NETCHAR_SYNC_RESPONSE_TYPE); /* responseType (1 byte) */
Stream_Write_UINT32(s, rdp->autodetect->netCharBandwidth); /* bandwidth (4 bytes) */
Stream_Write_UINT32(s, rdp->autodetect->netCharAverageRTT); /* rtt (4 bytes) */
return rdp_send_message_channel_pdu(rdp, s, SEC_AUTODETECT_RSP);
}
static BOOL autodetect_recv_rtt_measure_request(rdpRdp* rdp, wStream* s, AUTODETECT_REQ_PDU* autodetectReqPdu)
static BOOL autodetect_recv_rtt_measure_request(rdpRdp* rdp, wStream* s,
AUTODETECT_REQ_PDU* autodetectReqPdu)
{
if (autodetectReqPdu->headerLength != 0x06)
return FALSE;
WLog_VRB(AUTODETECT_TAG, "received RTT Measure Request PDU");
/* Send a response to the server */
return autodetect_send_rtt_measure_response(rdp, autodetectReqPdu->sequenceNumber);
}
static BOOL autodetect_recv_rtt_measure_response(rdpRdp* rdp, wStream* s, AUTODETECT_RSP_PDU* autodetectRspPdu)
static BOOL autodetect_recv_rtt_measure_response(rdpRdp* rdp, wStream* s,
AUTODETECT_RSP_PDU* autodetectRspPdu)
{
BOOL success = TRUE;
@ -362,23 +352,25 @@ static BOOL autodetect_recv_rtt_measure_response(rdpRdp* rdp, wStream* s, AUTODE
return FALSE;
WLog_VRB(AUTODETECT_TAG, "received RTT Measure Response PDU");
rdp->autodetect->netCharAverageRTT = GetTickCountPrecise() - rdp->autodetect->rttMeasureStartTime;
if (rdp->autodetect->netCharBaseRTT == 0 || rdp->autodetect->netCharBaseRTT > rdp->autodetect->netCharAverageRTT)
if (rdp->autodetect->netCharBaseRTT == 0 ||
rdp->autodetect->netCharBaseRTT > rdp->autodetect->netCharAverageRTT)
rdp->autodetect->netCharBaseRTT = rdp->autodetect->netCharAverageRTT;
IFCALLRET(rdp->autodetect->RTTMeasureResponse, success, rdp->context, autodetectRspPdu->sequenceNumber);
IFCALLRET(rdp->autodetect->RTTMeasureResponse, success, rdp->context,
autodetectRspPdu->sequenceNumber);
return success;
}
static BOOL autodetect_recv_bandwidth_measure_start(rdpRdp* rdp, wStream* s, AUTODETECT_REQ_PDU* autodetectReqPdu)
static BOOL autodetect_recv_bandwidth_measure_start(rdpRdp* rdp, wStream* s,
AUTODETECT_REQ_PDU* autodetectReqPdu)
{
if (autodetectReqPdu->headerLength != 0x06)
return FALSE;
WLog_VRB(AUTODETECT_TAG, "received Bandwidth Measure Start PDU - time=%"PRIu32"", GetTickCountPrecise());
WLog_VRB(AUTODETECT_TAG, "received Bandwidth Measure Start PDU - time=%"PRIu32"",
GetTickCountPrecise());
/* Initialize bandwidth measurement parameters */
rdp->autodetect->bandwidthMeasureStartTime = GetTickCountPrecise();
rdp->autodetect->bandwidthMeasureByteCount = 0;
@ -392,7 +384,8 @@ static BOOL autodetect_recv_bandwidth_measure_start(rdpRdp* rdp, wStream* s, AUT
return TRUE;
}
static BOOL autodetect_recv_bandwidth_measure_payload(rdpRdp* rdp, wStream* s, AUTODETECT_REQ_PDU* autodetectReqPdu)
static BOOL autodetect_recv_bandwidth_measure_payload(rdpRdp* rdp, wStream* s,
AUTODETECT_REQ_PDU* autodetectReqPdu)
{
UINT16 payloadLength;
@ -403,16 +396,15 @@ static BOOL autodetect_recv_bandwidth_measure_payload(rdpRdp* rdp, wStream* s, A
return FALSE;
Stream_Read_UINT16(s, payloadLength); /* payloadLength (2 bytes) */
WLog_DBG(AUTODETECT_TAG, "received Bandwidth Measure Payload PDU -> payloadLength=%"PRIu16"", payloadLength);
WLog_DBG(AUTODETECT_TAG, "received Bandwidth Measure Payload PDU -> payloadLength=%"PRIu16"",
payloadLength);
/* Add the payload length to the bandwidth measurement parameters */
rdp->autodetect->bandwidthMeasureByteCount += payloadLength;
return TRUE;
}
static BOOL autodetect_recv_bandwidth_measure_stop(rdpRdp* rdp, wStream* s, AUTODETECT_REQ_PDU* autodetectReqPdu)
static BOOL autodetect_recv_bandwidth_measure_stop(rdpRdp* rdp, wStream* s,
AUTODETECT_REQ_PDU* autodetectReqPdu)
{
UINT16 payloadLength;
UINT16 responseType;
@ -435,8 +427,8 @@ static BOOL autodetect_recv_bandwidth_measure_stop(rdpRdp* rdp, wStream* s, AUTO
payloadLength = 0;
}
WLog_VRB(AUTODETECT_TAG, "received Bandwidth Measure Stop PDU -> payloadLength=%"PRIu16"", payloadLength);
WLog_VRB(AUTODETECT_TAG, "received Bandwidth Measure Stop PDU -> payloadLength=%"PRIu16"",
payloadLength);
/* Add the payload length to the bandwidth measurement parameters */
rdp->autodetect->bandwidthMeasureByteCount += payloadLength;
@ -448,12 +440,13 @@ static BOOL autodetect_recv_bandwidth_measure_stop(rdpRdp* rdp, wStream* s, AUTO
/* Send a response the server */
responseType = autodetectReqPdu->requestType == RDP_BW_STOP_REQUEST_TYPE_CONNECTTIME ?
RDP_BW_RESULTS_RESPONSE_TYPE_CONNECTTIME : RDP_BW_RESULTS_RESPONSE_TYPE_CONTINUOUS;
return autodetect_send_bandwidth_measure_results(rdp, responseType, autodetectReqPdu->sequenceNumber);
RDP_BW_RESULTS_RESPONSE_TYPE_CONNECTTIME : RDP_BW_RESULTS_RESPONSE_TYPE_CONTINUOUS;
return autodetect_send_bandwidth_measure_results(rdp, responseType,
autodetectReqPdu->sequenceNumber);
}
static BOOL autodetect_recv_bandwidth_measure_results(rdpRdp* rdp, wStream* s, AUTODETECT_RSP_PDU* autodetectRspPdu)
static BOOL autodetect_recv_bandwidth_measure_results(rdpRdp* rdp, wStream* s,
AUTODETECT_RSP_PDU* autodetectRspPdu)
{
BOOL success = TRUE;
@ -461,56 +454,65 @@ static BOOL autodetect_recv_bandwidth_measure_results(rdpRdp* rdp, wStream* s, A
return FALSE;
WLog_VRB(AUTODETECT_TAG, "received Bandwidth Measure Results PDU");
Stream_Read_UINT32(s, rdp->autodetect->bandwidthMeasureTimeDelta); /* timeDelta (4 bytes) */
Stream_Read_UINT32(s, rdp->autodetect->bandwidthMeasureByteCount); /* byteCount (4 bytes) */
if (rdp->autodetect->bandwidthMeasureTimeDelta > 0)
rdp->autodetect->netCharBandwidth = rdp->autodetect->bandwidthMeasureByteCount * 8 / rdp->autodetect->bandwidthMeasureTimeDelta;
rdp->autodetect->netCharBandwidth = rdp->autodetect->bandwidthMeasureByteCount * 8 /
rdp->autodetect->bandwidthMeasureTimeDelta;
else
rdp->autodetect->netCharBandwidth = 0;
IFCALLRET(rdp->autodetect->BandwidthMeasureResults, success, rdp->context, autodetectRspPdu->sequenceNumber);
IFCALLRET(rdp->autodetect->BandwidthMeasureResults, success, rdp->context,
autodetectRspPdu->sequenceNumber);
return success;
}
static BOOL autodetect_recv_netchar_result(rdpRdp* rdp, wStream* s, AUTODETECT_REQ_PDU* autodetectReqPdu)
static BOOL autodetect_recv_netchar_result(rdpRdp* rdp, wStream* s,
AUTODETECT_REQ_PDU* autodetectReqPdu)
{
BOOL success = TRUE;
switch (autodetectReqPdu->requestType)
{
case 0x0840:
/* baseRTT and averageRTT fields are present (bandwidth field is not) */
if ((autodetectReqPdu->headerLength != 0x0E) || (Stream_GetRemainingLength(s) < 8))
return FALSE;
Stream_Read_UINT32(s, rdp->autodetect->netCharBaseRTT); /* baseRTT (4 bytes) */
Stream_Read_UINT32(s, rdp->autodetect->netCharAverageRTT); /* averageRTT (4 bytes) */
break;
case 0x0840:
case 0x0880:
/* bandwidth and averageRTT fields are present (baseRTT field is not) */
if ((autodetectReqPdu->headerLength != 0x0E) || (Stream_GetRemainingLength(s) < 8))
return FALSE;
Stream_Read_UINT32(s, rdp->autodetect->netCharBandwidth); /* bandwidth (4 bytes) */
Stream_Read_UINT32(s, rdp->autodetect->netCharAverageRTT); /* averageRTT (4 bytes) */
break;
/* baseRTT and averageRTT fields are present (bandwidth field is not) */
if ((autodetectReqPdu->headerLength != 0x0E) || (Stream_GetRemainingLength(s) < 8))
return FALSE;
case 0x08C0:
/* baseRTT, bandwidth, and averageRTT fields are present */
if ((autodetectReqPdu->headerLength != 0x12) || (Stream_GetRemainingLength(s) < 12))
return FALSE;
Stream_Read_UINT32(s, rdp->autodetect->netCharBaseRTT); /* baseRTT (4 bytes) */
Stream_Read_UINT32(s, rdp->autodetect->netCharBandwidth); /* bandwidth (4 bytes) */
Stream_Read_UINT32(s, rdp->autodetect->netCharAverageRTT); /* averageRTT (4 bytes) */
break;
Stream_Read_UINT32(s, rdp->autodetect->netCharBaseRTT); /* baseRTT (4 bytes) */
Stream_Read_UINT32(s, rdp->autodetect->netCharAverageRTT); /* averageRTT (4 bytes) */
break;
case 0x0880:
/* bandwidth and averageRTT fields are present (baseRTT field is not) */
if ((autodetectReqPdu->headerLength != 0x0E) || (Stream_GetRemainingLength(s) < 8))
return FALSE;
Stream_Read_UINT32(s, rdp->autodetect->netCharBandwidth); /* bandwidth (4 bytes) */
Stream_Read_UINT32(s, rdp->autodetect->netCharAverageRTT); /* averageRTT (4 bytes) */
break;
case 0x08C0:
/* baseRTT, bandwidth, and averageRTT fields are present */
if ((autodetectReqPdu->headerLength != 0x12) || (Stream_GetRemainingLength(s) < 12))
return FALSE;
Stream_Read_UINT32(s, rdp->autodetect->netCharBaseRTT); /* baseRTT (4 bytes) */
Stream_Read_UINT32(s, rdp->autodetect->netCharBandwidth); /* bandwidth (4 bytes) */
Stream_Read_UINT32(s, rdp->autodetect->netCharAverageRTT); /* averageRTT (4 bytes) */
break;
}
WLog_VRB(AUTODETECT_TAG, "received Network Characteristics Result PDU -> baseRTT=%"PRIu32", bandwidth=%"PRIu32", averageRTT=%"PRIu32"", rdp->autodetect->netCharBaseRTT, rdp->autodetect->netCharBandwidth, rdp->autodetect->netCharAverageRTT);
IFCALLRET(rdp->autodetect->NetworkCharacteristicsResult, success, rdp->context, autodetectReqPdu->sequenceNumber);
WLog_VRB(AUTODETECT_TAG,
"received Network Characteristics Result PDU -> baseRTT=%"PRIu32", bandwidth=%"PRIu32", averageRTT=%"PRIu32"",
rdp->autodetect->netCharBaseRTT, rdp->autodetect->netCharBandwidth,
rdp->autodetect->netCharAverageRTT);
IFCALLRET(rdp->autodetect->NetworkCharacteristicsResult, success, rdp->context,
autodetectReqPdu->sequenceNumber);
return success;
}
@ -518,7 +520,7 @@ int rdp_recv_autodetect_request_packet(rdpRdp* rdp, wStream* s)
{
AUTODETECT_REQ_PDU autodetectReqPdu;
BOOL success = FALSE;
if (Stream_GetRemainingLength(s) < 6)
return -1;
@ -526,51 +528,50 @@ int rdp_recv_autodetect_request_packet(rdpRdp* rdp, wStream* s)
Stream_Read_UINT8(s, autodetectReqPdu.headerTypeId); /* headerTypeId (1 byte) */
Stream_Read_UINT16(s, autodetectReqPdu.sequenceNumber); /* sequenceNumber (2 bytes) */
Stream_Read_UINT16(s, autodetectReqPdu.requestType); /* requestType (2 bytes) */
WLog_VRB(AUTODETECT_TAG,
"rdp_recv_autodetect_request_packet: headerLength=%"PRIu8", headerTypeId=%"PRIu8", sequenceNumber=%"PRIu16", requestType=%04"PRIx16"",
autodetectReqPdu.headerLength, autodetectReqPdu.headerTypeId,
autodetectReqPdu.sequenceNumber, autodetectReqPdu.requestType);
"rdp_recv_autodetect_request_packet: headerLength=%"PRIu8", headerTypeId=%"PRIu8", sequenceNumber=%"PRIu16", requestType=%04"PRIx16"",
autodetectReqPdu.headerLength, autodetectReqPdu.headerTypeId,
autodetectReqPdu.sequenceNumber, autodetectReqPdu.requestType);
if (autodetectReqPdu.headerTypeId != TYPE_ID_AUTODETECT_REQUEST)
return -1;
switch (autodetectReqPdu.requestType)
{
case RDP_RTT_REQUEST_TYPE_CONTINUOUS:
case RDP_RTT_REQUEST_TYPE_CONNECTTIME:
/* RTT Measure Request (RDP_RTT_REQUEST) - MS-RDPBCGR 2.2.14.1.1 */
success = autodetect_recv_rtt_measure_request(rdp, s, &autodetectReqPdu);
break;
case RDP_RTT_REQUEST_TYPE_CONTINUOUS:
case RDP_RTT_REQUEST_TYPE_CONNECTTIME:
/* RTT Measure Request (RDP_RTT_REQUEST) - MS-RDPBCGR 2.2.14.1.1 */
success = autodetect_recv_rtt_measure_request(rdp, s, &autodetectReqPdu);
break;
case RDP_BW_START_REQUEST_TYPE_CONTINUOUS:
case RDP_BW_START_REQUEST_TYPE_TUNNEL:
case RDP_BW_START_REQUEST_TYPE_CONNECTTIME:
/* Bandwidth Measure Start (RDP_BW_START) - MS-RDPBCGR 2.2.14.1.2 */
success = autodetect_recv_bandwidth_measure_start(rdp, s, &autodetectReqPdu);
break;
case RDP_BW_START_REQUEST_TYPE_CONTINUOUS:
case RDP_BW_START_REQUEST_TYPE_TUNNEL:
case RDP_BW_START_REQUEST_TYPE_CONNECTTIME:
/* Bandwidth Measure Start (RDP_BW_START) - MS-RDPBCGR 2.2.14.1.2 */
success = autodetect_recv_bandwidth_measure_start(rdp, s, &autodetectReqPdu);
break;
case RDP_BW_PAYLOAD_REQUEST_TYPE:
/* Bandwidth Measure Payload (RDP_BW_PAYLOAD) - MS-RDPBCGR 2.2.14.1.3 */
success = autodetect_recv_bandwidth_measure_payload(rdp, s, &autodetectReqPdu);
break;
case RDP_BW_PAYLOAD_REQUEST_TYPE:
/* Bandwidth Measure Payload (RDP_BW_PAYLOAD) - MS-RDPBCGR 2.2.14.1.3 */
success = autodetect_recv_bandwidth_measure_payload(rdp, s, &autodetectReqPdu);
break;
case RDP_BW_STOP_REQUEST_TYPE_CONNECTTIME:
case RDP_BW_STOP_REQUEST_TYPE_CONTINUOUS:
case RDP_BW_STOP_REQUEST_TYPE_TUNNEL:
/* Bandwidth Measure Stop (RDP_BW_STOP) - MS-RDPBCGR 2.2.14.1.4 */
success = autodetect_recv_bandwidth_measure_stop(rdp, s, &autodetectReqPdu);
break;
case RDP_BW_STOP_REQUEST_TYPE_CONNECTTIME:
case RDP_BW_STOP_REQUEST_TYPE_CONTINUOUS:
case RDP_BW_STOP_REQUEST_TYPE_TUNNEL:
/* Bandwidth Measure Stop (RDP_BW_STOP) - MS-RDPBCGR 2.2.14.1.4 */
success = autodetect_recv_bandwidth_measure_stop(rdp, s, &autodetectReqPdu);
break;
case 0x0840:
case 0x0880:
case 0x08C0:
/* Network Characteristics Result (RDP_NETCHAR_RESULT) - MS-RDPBCGR 2.2.14.1.5 */
success = autodetect_recv_netchar_result(rdp, s, &autodetectReqPdu);
break;
case 0x0840:
case 0x0880:
case 0x08C0:
/* Network Characteristics Result (RDP_NETCHAR_RESULT) - MS-RDPBCGR 2.2.14.1.5 */
success = autodetect_recv_netchar_result(rdp, s, &autodetectReqPdu);
break;
default:
break;
default:
break;
}
return success ? 0 : -1;
@ -588,30 +589,29 @@ int rdp_recv_autodetect_response_packet(rdpRdp* rdp, wStream* s)
Stream_Read_UINT8(s, autodetectRspPdu.headerTypeId); /* headerTypeId (1 byte) */
Stream_Read_UINT16(s, autodetectRspPdu.sequenceNumber); /* sequenceNumber (2 bytes) */
Stream_Read_UINT16(s, autodetectRspPdu.responseType); /* responseType (2 bytes) */
WLog_VRB(AUTODETECT_TAG,
"rdp_recv_autodetect_response_packet: headerLength=%"PRIu8", headerTypeId=%"PRIu8", sequenceNumber=%"PRIu16", requestType=%04"PRIx16"",
autodetectRspPdu.headerLength, autodetectRspPdu.headerTypeId,
autodetectRspPdu.sequenceNumber, autodetectRspPdu.responseType);
"rdp_recv_autodetect_response_packet: headerLength=%"PRIu8", headerTypeId=%"PRIu8", sequenceNumber=%"PRIu16", requestType=%04"PRIx16"",
autodetectRspPdu.headerLength, autodetectRspPdu.headerTypeId,
autodetectRspPdu.sequenceNumber, autodetectRspPdu.responseType);
if (autodetectRspPdu.headerTypeId != TYPE_ID_AUTODETECT_RESPONSE)
return -1;
switch (autodetectRspPdu.responseType)
{
case RDP_RTT_RESPONSE_TYPE:
/* RTT Measure Response (RDP_RTT_RESPONSE) - MS-RDPBCGR 2.2.14.2.1 */
success = autodetect_recv_rtt_measure_response(rdp, s, &autodetectRspPdu);
break;
case RDP_RTT_RESPONSE_TYPE:
/* RTT Measure Response (RDP_RTT_RESPONSE) - MS-RDPBCGR 2.2.14.2.1 */
success = autodetect_recv_rtt_measure_response(rdp, s, &autodetectRspPdu);
break;
case RDP_BW_RESULTS_RESPONSE_TYPE_CONNECTTIME:
case RDP_BW_RESULTS_RESPONSE_TYPE_CONTINUOUS:
/* Bandwidth Measure Results (RDP_BW_RESULTS) - MS-RDPBCGR 2.2.14.2.2 */
success = autodetect_recv_bandwidth_measure_results(rdp, s, &autodetectRspPdu);
break;
case RDP_BW_RESULTS_RESPONSE_TYPE_CONNECTTIME:
case RDP_BW_RESULTS_RESPONSE_TYPE_CONTINUOUS:
/* Bandwidth Measure Results (RDP_BW_RESULTS) - MS-RDPBCGR 2.2.14.2.2 */
success = autodetect_recv_bandwidth_measure_results(rdp, s, &autodetectRspPdu);
break;
default:
break;
default:
break;
}
return success ? 0 : -1;
@ -623,9 +623,8 @@ rdpAutoDetect* autodetect_new(void)
if (autoDetect)
{
}
return autoDetect;
}

View File

@ -3966,17 +3966,16 @@ BOOL rdp_write_demand_active(wStream* s, rdpSettings* settings)
BOOL rdp_send_demand_active(rdpRdp* rdp)
{
wStream* s;
wStream* s = rdp_send_stream_pdu_init(rdp);
BOOL status;
if (!(s = Stream_New(NULL, 4096)))
if (!s)
return FALSE;
rdp_init_stream_pdu(rdp, s);
rdp->settings->ShareId = 0x10000 + rdp->mcs->userId;
status = rdp_write_demand_active(s, rdp->settings) &&
rdp_send_pdu(rdp, s, PDU_TYPE_DEMAND_ACTIVE, rdp->mcs->userId);
Stream_Free(s, TRUE);
Stream_Release(s);
return status;
}
@ -4196,15 +4195,14 @@ BOOL rdp_write_confirm_active(wStream* s, rdpSettings* settings)
BOOL rdp_send_confirm_active(rdpRdp* rdp)
{
wStream* s;
wStream* s = rdp_send_stream_pdu_init(rdp);
BOOL status;
if (!(s = Stream_New(NULL, 4096)))
if (!s)
return FALSE;
rdp_init_stream_pdu(rdp, s);
status = rdp_write_confirm_active(s, rdp->settings) &&
rdp_send_pdu(rdp, s, PDU_TYPE_CONFIRM_ACTIVE, rdp->mcs->userId);
Stream_Free(s, TRUE);
Stream_Release(s);
return status;
}

View File

@ -112,10 +112,7 @@ BOOL freerdp_channel_send(rdpRdp* rdp, UINT16 channelId, const BYTE* data, int s
/* WLog_DBG(TAG, "%s: sending data (flags=0x%x size=%d)", __FUNCTION__, flags, size); */
if (!rdp_send(rdp, s, channelId))
{
Stream_Release(s);
return FALSE;
}
data += chunkSize;
left -= chunkSize;

View File

@ -918,20 +918,24 @@ wStream* fastpath_input_pdu_init(rdpFastPath* fastpath, BYTE eventFlags, BYTE ev
BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNumEvents)
{
BOOL rc = FALSE;
rdpRdp* rdp;
UINT16 length;
BYTE eventHeader;
if (!fastpath || !fastpath->rdp || !s)
if (!s)
return FALSE;
if (!fastpath || !fastpath->rdp)
goto fail;
/*
* A maximum of 15 events are allowed per request
* if the optional numEvents field isn't used
* see MS-RDPBCGR 2.2.8.1.2 for details
*/
if (iNumEvents > 15)
return FALSE;
goto fail;
rdp = fastpath->rdp;
length = Stream_GetPosition(s);
@ -939,7 +943,7 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
if (length >= (2 << 14))
{
WLog_ERR(TAG, "Maximum FastPath PDU length is 32767");
return FALSE;
goto fail;
}
eventHeader = FASTPATH_INPUT_ACTION_FASTPATH;
@ -974,13 +978,13 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
Stream_Write_UINT8(s, pad); /* padding */
if (!security_hmac_signature(fpInputEvents, fpInputEvents_length, Stream_Pointer(s), rdp))
return FALSE;
goto fail;
if (pad)
memset(fpInputEvents + fpInputEvents_length, 0, pad);
if (!security_fips_encrypt(fpInputEvents, fpInputEvents_length + pad, rdp))
return FALSE;
goto fail;
length += pad;
}
@ -995,7 +999,7 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
status = security_mac_signature(rdp, fpInputEvents, fpInputEvents_length, Stream_Pointer(s));
if (!status || !security_encrypt(fpInputEvents, fpInputEvents_length, rdp))
return FALSE;
goto fail;
}
}
@ -1012,9 +1016,12 @@ BOOL fastpath_send_multiple_input_pdu(rdpFastPath* fastpath, wStream* s, int iNu
Stream_SealLength(s);
if (transport_write(fastpath->rdp->transport, s) < 0)
return FALSE;
goto fail;
return TRUE;
rc = TRUE;
fail:
Stream_Release(s);
return rc;
}
BOOL fastpath_send_input_pdu(rdpFastPath* fastpath, wStream* s)

View File

@ -929,9 +929,8 @@ BOOL rdp_recv_client_info(rdpRdp* rdp, wStream* s)
BOOL rdp_send_client_info(rdpRdp* rdp)
{
wStream* s;
BOOL status;
rdp->sec_flags |= SEC_INFO_PKT;
s = Stream_New(NULL, 2048);
s = rdp_send_stream_init(rdp);
if (!s)
{
@ -939,11 +938,8 @@ BOOL rdp_send_client_info(rdpRdp* rdp)
return FALSE;
}
rdp_init_stream(rdp, s);
rdp_write_info_packet(rdp, s);
status = rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID);
Stream_Free(s, TRUE);
return status;
return rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID);
}
static BOOL rdp_recv_logon_info_v1(rdpRdp* rdp, wStream* s, logon_info* info)
@ -1461,7 +1457,7 @@ BOOL rdp_send_save_session_info(rdpContext* context, UINT32 type, void* data)
if (status)
status = rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SAVE_SESSION_INFO, rdp->mcs->userId);
else
Stream_Free(s, TRUE);
Stream_Release(s);
return status;
}

View File

@ -121,9 +121,9 @@ static void license_print_product_info(LICENSE_PRODUCT_INFO* productInfo)
char* CompanyName = NULL;
char* ProductId = NULL;
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) productInfo->pbCompanyName,
productInfo->cbCompanyName / 2, &CompanyName, 0, NULL, NULL);
productInfo->cbCompanyName / 2, &CompanyName, 0, NULL, NULL);
ConvertFromUnicode(CP_UTF8, 0, (WCHAR*) productInfo->pbProductId,
productInfo->cbProductId / 2, &ProductId, 0, NULL, NULL);
productInfo->cbProductId / 2, &ProductId, 0, NULL, NULL);
WLog_INFO(TAG, "ProductInfo:");
WLog_INFO(TAG, "\tdwVersion: 0x%08"PRIX32"", productInfo->dwVersion);
WLog_INFO(TAG, "\tCompanyName: %s", CompanyName);
@ -178,12 +178,16 @@ BOOL license_read_preamble(wStream* s, BYTE* bMsgType, BYTE* flags, UINT16* wMsg
* @param wMsgSize message size
*/
void license_write_preamble(wStream* s, BYTE bMsgType, BYTE flags, UINT16 wMsgSize)
static BOOL license_write_preamble(wStream* s, BYTE bMsgType, BYTE flags, UINT16 wMsgSize)
{
if (!Stream_EnsureRemainingCapacity(s, 4))
return FALSE;
/* preamble (4 bytes) */
Stream_Write_UINT8(s, bMsgType); /* bMsgType (1 byte) */
Stream_Write_UINT8(s, flags); /* flags (1 byte) */
Stream_Write_UINT16(s, wMsgSize); /* wMsgSize (2 bytes) */
return TRUE;
}
/**
@ -196,7 +200,6 @@ wStream* license_send_stream_init(rdpLicense* license)
{
wStream* s;
BOOL do_crypt = license->rdp->do_crypt;
license->rdp->sec_flags = SEC_LICENSE_PKT;
/**
@ -213,15 +216,21 @@ wStream* license_send_stream_init(rdpLicense* license)
license->rdp->do_crypt = license->rdp->do_crypt_license;
}
s = transport_send_stream_init(license->rdp->transport, 4096);
s = rdp_send_stream_init(license->rdp);
if (!s)
return NULL;
rdp_init_stream(license->rdp, s);
license->rdp->do_crypt = do_crypt;
license->PacketHeaderLength = Stream_GetPosition(s);
Stream_Seek(s, LICENSE_PREAMBLE_LENGTH);
if (!Stream_SafeSeek(s, LICENSE_PREAMBLE_LENGTH))
goto fail;
return s;
fail:
Stream_Release(s);
return NULL;
}
/**
@ -231,13 +240,71 @@ wStream* license_send_stream_init(rdpLicense* license)
* @param s stream
*/
BOOL license_send(rdpLicense* license, wStream* s, BYTE type)
static BOOL license_send(rdpLicense* license, BYTE type)
{
BOOL rc = FALSE;
size_t length;
BYTE flags;
UINT16 wMsgSize;
rdpRdp* rdp = license->rdp;
rdpRdp* rdp;
wStream* s = license_send_stream_init(license);
if (!s)
return FALSE;
if (!license || !license->rdp)
goto fail;
rdp = license->rdp;
DEBUG_LICENSE("Sending %s Packet", LICENSE_MESSAGE_STRINGS[type & 0x1F]);
switch (type)
{
case NEW_LICENSE_REQUEST:
if (!license_write_new_license_request_packet(license, s))
goto fail;
break;
case PLATFORM_CHALLENGE_RESPONSE:
{
BYTE mac_data[16];
size_t length = license->PlatformChallenge->length + HWID_LENGTH;
BYTE* buffer = (BYTE*) malloc(length);
if (!buffer)
goto fail;
CopyMemory(buffer, license->PlatformChallenge->data, license->PlatformChallenge->length);
CopyMemory(&buffer[license->PlatformChallenge->length], license->HardwareId, HWID_LENGTH);
rc = security_mac_data(license->MacSaltKey, buffer, length, mac_data);
free(buffer);
if (!rc)
goto fail;
if (!license_write_platform_challenge_response_packet(license, s, mac_data))
goto fail;
}
break;
case ERROR_ALERT:
{
if (!Stream_EnsureRemainingCapacity(s, 8))
goto fail;
Stream_Write_UINT32(s, STATUS_VALID_CLIENT); /* dwErrorCode */
Stream_Write_UINT32(s, ST_NO_TRANSITION); /* dwStateTransition */
if (!license_write_binary_blob(s, license->ErrorInfo))
goto fail;
}
break;
default:
goto fail;
}
length = Stream_GetPosition(s);
wMsgSize = length - license->PacketHeaderLength;
Stream_SetPosition(s, license->PacketHeaderLength);
@ -251,15 +318,21 @@ BOOL license_send(rdpLicense* license, wStream* s, BYTE type)
if (!rdp->settings->ServerMode)
flags |= EXTENDED_ERROR_MSG_SUPPORTED;
license_write_preamble(s, type, flags, wMsgSize);
if (!license_write_preamble(s, type, flags, wMsgSize))
goto fail;
#ifdef WITH_DEBUG_LICENSE
WLog_DBG(TAG, "Sending %s Packet, length %"PRIu16"", LICENSE_MESSAGE_STRINGS[type & 0x1F], wMsgSize);
WLog_DBG(TAG, "Sending %s Packet, length %"PRIu16"", LICENSE_MESSAGE_STRINGS[type & 0x1F],
wMsgSize);
winpr_HexDump(TAG, WLOG_DEBUG, Stream_Pointer(s) - LICENSE_PREAMBLE_LENGTH, wMsgSize);
#endif
Stream_SetPosition(s, length);
rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID);
rc = rdp_send(rdp, s, MCS_GLOBAL_CHANNEL_ID);
rdp->sec_flags = 0;
return TRUE;
return rc;
fail:
Stream_Release(s);
return FALSE;
}
/**
@ -305,6 +378,7 @@ int license_recv(rdpLicense* license, wStream* s)
Stream_Rewind(s, RDP_SECURITY_HEADER_LENGTH);
status = rdp_recv_out_of_sequence_pdu(license->rdp, s);
if (status < 0)
{
WLog_ERR(TAG, "unexpected license packet.");
@ -327,6 +401,7 @@ int license_recv(rdpLicense* license, wStream* s)
if (!license_send_new_license_request_packet(license))
return -1;
break;
case PLATFORM_CHALLENGE:
@ -335,6 +410,7 @@ int license_recv(rdpLicense* license, wStream* s)
if (!license_send_platform_challenge_response_packet(license))
return -1;
break;
case NEW_LICENSE:
@ -348,6 +424,7 @@ int license_recv(rdpLicense* license, wStream* s)
case ERROR_ALERT:
if (!license_read_error_alert_packet(license, s))
return -1;
break;
default:
@ -380,19 +457,20 @@ BOOL license_generate_keys(rdpLicense* license)
BOOL ret;
if (
/* MasterSecret */
!security_master_secret(license->PremasterSecret, license->ClientRandom,
license->ServerRandom, license->MasterSecret) ||
/* SessionKeyBlob */
!security_session_key_blob(license->MasterSecret, license->ClientRandom,
license->ServerRandom, license->SessionKeyBlob))
/* MasterSecret */
!security_master_secret(license->PremasterSecret, license->ClientRandom,
license->ServerRandom, license->MasterSecret) ||
/* SessionKeyBlob */
!security_session_key_blob(license->MasterSecret, license->ClientRandom,
license->ServerRandom, license->SessionKeyBlob))
{
return FALSE;
}
security_mac_salt_key(license->SessionKeyBlob, license->ClientRandom,
license->ServerRandom, license->MacSaltKey); /* MacSaltKey */
license->ServerRandom, license->MacSaltKey); /* MacSaltKey */
ret = security_licensing_encryption_key(license->SessionKeyBlob, license->ClientRandom,
license->ServerRandom, license->LicensingEncryptionKey); /* LicensingEncryptionKey */
license->ServerRandom, license->LicensingEncryptionKey); /* LicensingEncryptionKey */
#ifdef WITH_DEBUG_LICENSE
WLog_DBG(TAG, "ClientRandom:");
winpr_HexDump(TAG, WLOG_DEBUG, license->ClientRandom, CLIENT_RANDOM_LENGTH);
@ -420,14 +498,14 @@ BOOL license_generate_keys(rdpLicense* license)
BOOL license_generate_hwid(rdpLicense* license)
{
BYTE macAddress[6];
ZeroMemory(macAddress, sizeof(macAddress));
ZeroMemory(license->HardwareId, HWID_LENGTH);
/* Allow FIPS override for use of MD5 here, really this does not have to be MD5 as we are just taking a MD5 hash of the 6 bytes of 0's(macAddress) */
/* and filling in the Data1-Data4 fields of the CLIENT_HARDWARE_ID structure(from MS-RDPELE section 2.2.2.3.1). This is for RDP licensing packets */
/* which will already be encrypted under FIPS, so the use of MD5 here is not for sensitive data protection. */
if (!winpr_Digest_Allow_FIPS(WINPR_MD_MD5, macAddress, sizeof(macAddress), &license->HardwareId[HWID_PLATFORM_ID_LENGTH], WINPR_MD5_DIGEST_LENGTH))
if (!winpr_Digest_Allow_FIPS(WINPR_MD_MD5, macAddress, sizeof(macAddress),
&license->HardwareId[HWID_PLATFORM_ID_LENGTH], WINPR_MD5_DIGEST_LENGTH))
return FALSE;
return TRUE;
@ -443,8 +521,8 @@ BOOL license_get_server_rsa_public_key(rdpLicense* license)
if (license->ServerCertificate->length < 1)
{
if (!certificate_read_server_certificate(license->certificate,
settings->ServerCertificate, settings->ServerCertificateLength))
return FALSE;
settings->ServerCertificate, settings->ServerCertificateLength))
return FALSE;
}
Exponent = license->certificate->cert_info.exponent;
@ -453,8 +531,10 @@ BOOL license_get_server_rsa_public_key(rdpLicense* license)
CopyMemory(license->Exponent, Exponent, 4);
license->ModulusLength = ModulusLength;
license->Modulus = (BYTE*) malloc(ModulusLength);
if (!license->Modulus)
return FALSE;
CopyMemory(license->Modulus, Modulus, ModulusLength);
return TRUE;
}
@ -472,8 +552,8 @@ BOOL license_encrypt_premaster_secret(rdpLicense* license)
WLog_DBG(TAG, "Exponent:");
winpr_HexDump(TAG, WLOG_DEBUG, license->Exponent, 4);
#endif
EncryptedPremasterSecret = (BYTE*) calloc(1, license->ModulusLength);
if (!EncryptedPremasterSecret)
return FALSE;
@ -481,8 +561,8 @@ BOOL license_encrypt_premaster_secret(rdpLicense* license)
license->EncryptedPremasterSecret->length = PREMASTER_SECRET_LENGTH;
#ifndef LICENSE_NULL_PREMASTER_SECRET
license->EncryptedPremasterSecret->length =
crypto_rsa_public_encrypt(license->PremasterSecret, PREMASTER_SECRET_LENGTH,
license->ModulusLength, license->Modulus, license->Exponent, EncryptedPremasterSecret);
crypto_rsa_public_encrypt(license->PremasterSecret, PREMASTER_SECRET_LENGTH,
license->ModulusLength, license->Modulus, license->Exponent, EncryptedPremasterSecret);
#endif
license->EncryptedPremasterSecret->data = EncryptedPremasterSecret;
return TRUE;
@ -492,27 +572,28 @@ BOOL license_decrypt_platform_challenge(rdpLicense* license)
{
BOOL rc;
WINPR_RC4_CTX* rc4;
license->PlatformChallenge->data = (BYTE*)malloc(license->EncryptedPlatformChallenge->length);
license->PlatformChallenge->data = (BYTE *)malloc(license->EncryptedPlatformChallenge->length);
if (!license->PlatformChallenge->data)
return FALSE;
license->PlatformChallenge->length = license->EncryptedPlatformChallenge->length;
/* Allow FIPS override for use of RC4 here, this is only used for decrypting the MACData field of the */
/* Server Platform Challenge packet (from MS-RDPELE section 2.2.2.4). This is for RDP licensing packets */
/* which will already be encrypted under FIPS, so the use of RC4 here is not for sensitive data protection. */
if ((rc4 = winpr_RC4_New_Allow_FIPS(license->LicensingEncryptionKey,
LICENSING_ENCRYPTION_KEY_LENGTH)) == NULL)
LICENSING_ENCRYPTION_KEY_LENGTH)) == NULL)
{
free(license->PlatformChallenge->data);
license->PlatformChallenge->data = NULL;
license->PlatformChallenge->length = 0;
return FALSE;
}
rc = winpr_RC4_Update(rc4, license->EncryptedPlatformChallenge->length,
license->EncryptedPlatformChallenge->data,
license->PlatformChallenge->data);
rc = winpr_RC4_Update(rc4, license->EncryptedPlatformChallenge->length,
license->EncryptedPlatformChallenge->data,
license->PlatformChallenge->data);
winpr_RC4_Free(rc4);
return rc;
}
@ -541,8 +622,10 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo)
productInfo->pbProductId = NULL;
productInfo->pbCompanyName = (BYTE*) malloc(productInfo->cbCompanyName);
if (!productInfo->pbCompanyName)
return FALSE;
Stream_Read(s, productInfo->pbCompanyName, productInfo->cbCompanyName);
if (Stream_GetRemainingLength(s) < 4)
@ -557,11 +640,12 @@ BOOL license_read_product_info(wStream* s, LICENSE_PRODUCT_INFO* productInfo)
goto out_fail;
productInfo->pbProductId = (BYTE*) malloc(productInfo->cbProductId);
if (!productInfo->pbProductId)
goto out_fail;
Stream_Read(s, productInfo->pbProductId, productInfo->cbProductId);
return TRUE;
out_fail:
free(productInfo->pbCompanyName);
free(productInfo->pbProductId);
@ -580,8 +664,10 @@ LICENSE_PRODUCT_INFO* license_new_product_info()
{
LICENSE_PRODUCT_INFO* productInfo;
productInfo = (LICENSE_PRODUCT_INFO*) malloc(sizeof(LICENSE_PRODUCT_INFO));
if (!productInfo)
return NULL;
productInfo->dwVersion = 0;
productInfo->cbCompanyName = 0;
productInfo->pbCompanyName = NULL;
@ -635,13 +721,16 @@ BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob)
if ((blob->type != wBlobType) && (blob->type != BB_ANY_BLOB))
{
WLog_ERR(TAG, "license binary blob type (0x%"PRIx16") does not match expected type (0x%"PRIx16").", wBlobType, blob->type);
WLog_ERR(TAG, "license binary blob type (0x%"PRIx16") does not match expected type (0x%"PRIx16").",
wBlobType, blob->type);
}
blob->type = wBlobType;
blob->data = (BYTE*) malloc(blob->length);
if (!blob->data)
return FALSE;
Stream_Read(s, blob->data, blob->length); /* blobData */
return TRUE;
}
@ -656,17 +745,22 @@ BOOL license_read_binary_blob(wStream* s, LICENSE_BLOB* blob)
BOOL license_write_binary_blob(wStream* s, LICENSE_BLOB* blob)
{
if (!Stream_EnsureRemainingCapacity(s, blob->length + 4))
{
Stream_Release(s);
return FALSE;
}
Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */
Stream_Write_UINT16(s, blob->length); /* wBlobLen (2 bytes) */
if (blob->length > 0)
Stream_Write(s, blob->data, blob->length); /* blobData */
return TRUE;
}
BOOL license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob, UINT32 ModulusLength)
static BOOL license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blob,
UINT32 ModulusLength)
{
UINT32 length;
length = ModulusLength + 8;
@ -679,6 +773,7 @@ BOOL license_write_encrypted_premaster_secret_blob(wStream* s, LICENSE_BLOB* blo
if (!Stream_EnsureRemainingCapacity(s, length + 4))
return FALSE;
Stream_Write_UINT16(s, blob->type); /* wBlobType (2 bytes) */
Stream_Write_UINT16(s, length); /* wBlobLen (2 bytes) */
@ -699,8 +794,10 @@ LICENSE_BLOB* license_new_binary_blob(UINT16 type)
{
LICENSE_BLOB* blob;
blob = (LICENSE_BLOB*) calloc(1, sizeof(LICENSE_BLOB));
if (blob)
blob->type = type;
return blob;
}
@ -741,6 +838,7 @@ BOOL license_read_scope_list(wStream* s, SCOPE_LIST* scopeList)
scopeList->count = scopeCount;
scopeList->array = (LICENSE_BLOB*) calloc(scopeCount, sizeof(LICENSE_BLOB));
if (!scopeList->array)
return FALSE;
@ -829,11 +927,11 @@ BOOL license_read_license_request_packet(rdpLicense* license, wStream* s)
/* Parse Server Certificate */
if (!certificate_read_server_certificate(license->certificate,
license->ServerCertificate->data, license->ServerCertificate->length))
license->ServerCertificate->data, license->ServerCertificate->length))
return FALSE;
if (!license_generate_keys(license) || !license_generate_hwid(license) ||
!license_encrypt_premaster_secret(license))
!license_encrypt_premaster_secret(license))
return FALSE;
#ifdef WITH_DEBUG_LICENSE
@ -856,7 +954,6 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
{
BYTE MacData[16];
UINT32 ConnectFlags = 0;
DEBUG_LICENSE("Receiving Platform Challenge Packet");
if (Stream_GetRemainingLength(s) < 4)
@ -865,6 +962,7 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
Stream_Read_UINT32(s, ConnectFlags); /* ConnectFlags, Reserved (4 bytes) */
/* EncryptedPlatformChallenge */
license->EncryptedPlatformChallenge->type = BB_ANY_BLOB;
if (!license_read_binary_blob(s, license->EncryptedPlatformChallenge))
return FALSE;
@ -874,14 +972,18 @@ BOOL license_read_platform_challenge_packet(rdpLicense* license, wStream* s)
return FALSE;
Stream_Read(s, MacData, 16); /* MACData (16 bytes) */
if (!license_decrypt_platform_challenge(license))
return FALSE;
#ifdef WITH_DEBUG_LICENSE
WLog_DBG(TAG, "ConnectFlags: 0x%08"PRIX32"", ConnectFlags);
WLog_DBG(TAG, "EncryptedPlatformChallenge:");
winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedPlatformChallenge->data, license->EncryptedPlatformChallenge->length);
winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedPlatformChallenge->data,
license->EncryptedPlatformChallenge->length);
WLog_DBG(TAG, "PlatformChallenge:");
winpr_HexDump(TAG, WLOG_DEBUG, license->PlatformChallenge->data, license->PlatformChallenge->length);
winpr_HexDump(TAG, WLOG_DEBUG, license->PlatformChallenge->data,
license->PlatformChallenge->length);
WLog_DBG(TAG, "MacData:");
winpr_HexDump(TAG, WLOG_DEBUG, MacData, 16);
#endif
@ -937,7 +1039,7 @@ BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s)
#ifdef WITH_DEBUG_LICENSE
WLog_DBG(TAG, "dwErrorCode: %s, dwStateTransition: %s",
error_codes[dwErrorCode], state_transitions[dwStateTransition]);
error_codes[dwErrorCode], state_transitions[dwStateTransition]);
#endif
if (dwErrorCode == STATUS_VALID_CLIENT)
@ -951,14 +1053,18 @@ BOOL license_read_error_alert_packet(rdpLicense* license, wStream* s)
case ST_TOTAL_ABORT:
license->state = LICENSE_STATE_ABORTED;
break;
case ST_NO_TRANSITION:
license->state = LICENSE_STATE_COMPLETED;
break;
case ST_RESET_PHASE_TO_START:
license->state = LICENSE_STATE_AWAIT;
break;
case ST_RESEND_LAST_MESSAGE:
break;
default:
break;
}
@ -977,19 +1083,20 @@ BOOL license_write_new_license_request_packet(rdpLicense* license, wStream* s)
{
UINT32 PlatformId;
UINT32 PreferredKeyExchangeAlg = KEY_EXCHANGE_ALG_RSA;
PlatformId = CLIENT_OS_ID_WINNT_POST_52 | CLIENT_IMAGE_ID_MICROSOFT;
Stream_Write_UINT32(s, PreferredKeyExchangeAlg); /* PreferredKeyExchangeAlg (4 bytes) */
Stream_Write_UINT32(s, PlatformId); /* PlatformId (4 bytes) */
Stream_Write(s, license->ClientRandom, 32); /* ClientRandom (32 bytes) */
/* EncryptedPremasterSecret */
if (!license_write_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret, license->ModulusLength) ||
/* ClientUserName */
!license_write_binary_blob(s, license->ClientUserName) ||
/* ClientMachineName */
!license_write_binary_blob(s, license->ClientMachineName))
/* EncryptedPremasterSecret */
if (!license_write_encrypted_premaster_secret_blob(s, license->EncryptedPremasterSecret,
license->ModulusLength) ||
/* ClientUserName */
!license_write_binary_blob(s, license->ClientUserName) ||
/* ClientMachineName */
!license_write_binary_blob(s, license->ClientMachineName))
{
Stream_Release(s);
return FALSE;
}
@ -998,9 +1105,12 @@ BOOL license_write_new_license_request_packet(rdpLicense* license, wStream* s)
WLog_DBG(TAG, "ClientRandom:");
winpr_HexDump(TAG, WLOG_DEBUG, license->ClientRandom, 32);
WLog_DBG(TAG, "EncryptedPremasterSecret");
winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedPremasterSecret->data, license->EncryptedPremasterSecret->length);
WLog_DBG(TAG, "ClientUserName (%"PRIu16"): %s", license->ClientUserName->length, (char*) license->ClientUserName->data);
WLog_DBG(TAG, "ClientMachineName (%"PRIu16"): %s", license->ClientMachineName->length, (char*) license->ClientMachineName->data);
winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedPremasterSecret->data,
license->EncryptedPremasterSecret->length);
WLog_DBG(TAG, "ClientUserName (%"PRIu16"): %s", license->ClientUserName->length,
(char*) license->ClientUserName->data);
WLog_DBG(TAG, "ClientMachineName (%"PRIu16"): %s", license->ClientMachineName->length,
(char*) license->ClientMachineName->data);
#endif
return TRUE;
}
@ -1013,12 +1123,8 @@ BOOL license_write_new_license_request_packet(rdpLicense* license, wStream* s)
BOOL license_send_new_license_request_packet(rdpLicense* license)
{
wStream* s;
char* username;
DEBUG_LICENSE("Sending New License Packet");
s = license_send_stream_init(license);
if (!s)
return FALSE;
if (license->rdp->settings->Username != NULL)
username = license->rdp->settings->Username;
@ -1029,11 +1135,9 @@ BOOL license_send_new_license_request_packet(rdpLicense* license)
license->ClientUserName->length = strlen(username) + 1;
license->ClientMachineName->data = (BYTE*) license->rdp->settings->ClientHostname;
license->ClientMachineName->length = strlen(license->rdp->settings->ClientHostname) + 1;
if (!license_write_new_license_request_packet(license, s) ||
!license_send(license, s, NEW_LICENSE_REQUEST))
{
if (!license_send(license, NEW_LICENSE_REQUEST))
return FALSE;
}
license->ClientUserName->data = NULL;
license->ClientUserName->length = 0;
@ -1050,12 +1154,15 @@ BOOL license_send_new_license_request_packet(rdpLicense* license)
* @param mac_data signature
*/
BOOL license_write_platform_challenge_response_packet(rdpLicense* license, wStream* s, BYTE* macData)
BOOL license_write_platform_challenge_response_packet(rdpLicense* license, wStream* s,
BYTE* macData)
{
if (!license_write_binary_blob(s, license->EncryptedPlatformChallenge) || /* EncryptedPlatformChallengeResponse */
!license_write_binary_blob(s, license->EncryptedHardwareId) || /* EncryptedHWID */
!Stream_EnsureRemainingCapacity(s, 16))
if (!license_write_binary_blob(s, license->EncryptedPlatformChallenge) ||
/* EncryptedPlatformChallengeResponse */
!license_write_binary_blob(s, license->EncryptedHardwareId) || /* EncryptedHWID */
!Stream_EnsureRemainingCapacity(s, 16))
{
Stream_Release(s);
return FALSE;
}
@ -1071,44 +1178,28 @@ BOOL license_write_platform_challenge_response_packet(rdpLicense* license, wStre
BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
{
wStream* s;
int length;
BYTE* buffer;
WINPR_RC4_CTX* rc4;
BYTE mac_data[16];
BOOL status;
DEBUG_LICENSE("Sending Platform Challenge Response Packet");
s = license_send_stream_init(license);
license->EncryptedPlatformChallenge->type = BB_DATA_BLOB;
length = license->PlatformChallenge->length + HWID_LENGTH;
buffer = (BYTE*) malloc(length);
if (!buffer)
return FALSE;
CopyMemory(buffer, license->PlatformChallenge->data, license->PlatformChallenge->length);
CopyMemory(&buffer[license->PlatformChallenge->length], license->HardwareId, HWID_LENGTH);
status = security_mac_data(license->MacSaltKey, buffer, length, mac_data);
free(buffer);
if (!status)
return FALSE;
/* Allow FIPS override for use of RC4 here, this is only used for encrypting the EncryptedHWID field of the */
/* Client Platform Challenge Response packet (from MS-RDPELE section 2.2.2.5). This is for RDP licensing packets */
/* which will already be encrypted under FIPS, so the use of RC4 here is not for sensitive data protection. */
rc4 = winpr_RC4_New_Allow_FIPS(license->LicensingEncryptionKey,
LICENSING_ENCRYPTION_KEY_LENGTH);
LICENSING_ENCRYPTION_KEY_LENGTH);
if (!rc4)
return FALSE;
buffer = (BYTE*) malloc(HWID_LENGTH);
if (!buffer)
return FALSE;
status = winpr_RC4_Update(rc4, HWID_LENGTH, license->HardwareId, buffer);
winpr_RC4_Free(rc4);
if (!status)
{
free(buffer);
@ -1126,8 +1217,7 @@ BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
WLog_DBG(TAG, "EncryptedHardwareId:");
winpr_HexDump(TAG, WLOG_DEBUG, license->EncryptedHardwareId->data, HWID_LENGTH);
#endif
return license_write_platform_challenge_response_packet(license, s, mac_data) &&
license_send(license, s, PLATFORM_CHALLENGE_RESPONSE);
return license_send(license, PLATFORM_CHALLENGE_RESPONSE);
}
/**
@ -1138,17 +1228,13 @@ BOOL license_send_platform_challenge_response_packet(rdpLicense* license)
BOOL license_send_valid_client_error_packet(rdpLicense* license)
{
wStream* s;
s = license_send_stream_init(license);
wStream* s = license_send_stream_init(license);
if (!s)
return FALSE;
DEBUG_LICENSE("Sending Error Alert Packet");
Stream_Write_UINT32(s, STATUS_VALID_CLIENT); /* dwErrorCode */
Stream_Write_UINT32(s, ST_NO_TRANSITION); /* dwStateTransition */
return license_write_binary_blob(s, license->ErrorInfo) &&
license_send(license, s, ERROR_ALERT);
return license_send(license, ERROR_ALERT);
}
/**
@ -1161,40 +1247,51 @@ rdpLicense* license_new(rdpRdp* rdp)
{
rdpLicense* license;
license = (rdpLicense*) calloc(1, sizeof(rdpLicense));
if (!license)
return NULL;
license->rdp = rdp;
license->state = LICENSE_STATE_AWAIT;
if (!(license->certificate = certificate_new()))
goto out_error;
if (!(license->ProductInfo = license_new_product_info()))
goto out_error;
if (!(license->ErrorInfo = license_new_binary_blob(BB_ERROR_BLOB)))
goto out_error;
if (!(license->KeyExchangeList = license_new_binary_blob(BB_KEY_EXCHG_ALG_BLOB)))
goto out_error;
if (!(license->ServerCertificate = license_new_binary_blob(BB_CERTIFICATE_BLOB)))
goto out_error;
if (!(license->ClientUserName = license_new_binary_blob(BB_CLIENT_USER_NAME_BLOB)))
goto out_error;
if (!(license->ClientMachineName = license_new_binary_blob(BB_CLIENT_MACHINE_NAME_BLOB)))
goto out_error;
if (!(license->PlatformChallenge = license_new_binary_blob(BB_ANY_BLOB)))
goto out_error;
if (!(license->EncryptedPlatformChallenge = license_new_binary_blob(BB_ANY_BLOB)))
goto out_error;
if (!(license->EncryptedPremasterSecret = license_new_binary_blob(BB_ANY_BLOB)))
goto out_error;
if (!(license->EncryptedHardwareId = license_new_binary_blob(BB_ENCRYPTED_DATA_BLOB)))
goto out_error;
if (!(license->ScopeList = license_new_scope_list()))
goto out_error;
license_generate_randoms(license);
return license;
out_error:
license_free(license);
return NULL;

View File

@ -202,7 +202,6 @@ struct rdp_license
};
FREERDP_LOCAL int license_recv(rdpLicense* license, wStream* s);
FREERDP_LOCAL BOOL license_send(rdpLicense* license, wStream* s, BYTE type);
FREERDP_LOCAL BOOL license_send_valid_client_error_packet(rdpLicense* license);

View File

@ -1831,6 +1831,7 @@ static size_t nla_sizeof_ts_request(size_t length)
BOOL nla_send(rdpNla* nla)
{
BOOL rc = TRUE;
wStream* s;
size_t length;
size_t ts_request_length;
@ -1933,9 +1934,12 @@ BOOL nla_send(rdpNla* nla)
}
Stream_SealLength(s);
transport_write(nla->transport, s);
if (transport_write(nla->transport, s) < 0)
rc = FALSE;
Stream_Free(s, TRUE);
return TRUE;
return rc;
}
static int nla_decode_ts_request(rdpNla* nla, wStream* s)

View File

@ -171,10 +171,7 @@ static int freerdp_peer_virtual_channel_write(freerdp_peer* client, HANDLE hChan
Stream_Write(s, buffer, chunkSize);
if (!rdp_send(rdp, s, peerChannel->channelId))
{
Stream_Release(s);
return -1;
}
buffer += chunkSize;
length -= chunkSize;

View File

@ -181,14 +181,21 @@ void rdp_write_share_data_header(wStream* s, UINT16 length, BYTE type, UINT32 sh
Stream_Write_UINT16(s, 0); /* compressedLength (2 bytes) */
}
static int rdp_security_stream_init(rdpRdp* rdp, wStream* s, BOOL sec_header)
static BOOL rdp_security_stream_init(rdpRdp* rdp, wStream* s, BOOL sec_header)
{
if (!rdp || !s)
return FALSE;
if (rdp->do_crypt)
{
Stream_Seek(s, 12);
if (!Stream_SafeSeek(s, 12))
return FALSE;
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
Stream_Seek(s, 4);
{
if (!Stream_SafeSeek(s, 4))
return FALSE;
}
rdp->sec_flags |= SEC_ENCRYPT;
@ -197,53 +204,62 @@ static int rdp_security_stream_init(rdpRdp* rdp, wStream* s, BOOL sec_header)
}
else if (rdp->sec_flags != 0 || sec_header)
{
Stream_Seek(s, 4);
if (!Stream_SafeSeek(s, 4))
return FALSE;
}
return 0;
}
int rdp_init_stream(rdpRdp* rdp, wStream* s)
{
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
return rdp_security_stream_init(rdp, s, FALSE);
return TRUE;
}
wStream* rdp_send_stream_init(rdpRdp* rdp)
{
wStream* s;
s = transport_send_stream_init(rdp->transport, 2048);
rdp_init_stream(rdp, s);
return s;
}
int rdp_init_stream_pdu(rdpRdp* rdp, wStream* s)
{
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
rdp_security_stream_init(rdp, s, FALSE);
Stream_Seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
return 0;
}
int rdp_init_stream_data_pdu(rdpRdp* rdp, wStream* s)
{
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
rdp_security_stream_init(rdp, s, FALSE);
Stream_Seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH);
Stream_Seek(s, RDP_SHARE_DATA_HEADER_LENGTH);
return 0;
}
wStream* rdp_data_pdu_init(rdpRdp* rdp)
{
wStream* s;
s = transport_send_stream_init(rdp->transport, 2048);
wStream* s = transport_send_stream_init(rdp->transport, 4096);
if (!s)
return NULL;
rdp_init_stream_data_pdu(rdp, s);
if (!Stream_SafeSeek(s, RDP_PACKET_HEADER_MAX_LENGTH))
goto fail;
if (!rdp_security_stream_init(rdp, s, FALSE))
goto fail;
return s;
fail:
Stream_Release(s);
return NULL;
}
wStream* rdp_send_stream_pdu_init(rdpRdp* rdp)
{
wStream* s = rdp_send_stream_init(rdp);
if (!s)
return NULL;
if (!Stream_SafeSeek(s, RDP_SHARE_CONTROL_HEADER_LENGTH))
goto fail;
return s;
fail:
Stream_Release(s);
return NULL;
}
wStream* rdp_data_pdu_init(rdpRdp* rdp)
{
wStream* s = rdp_send_stream_pdu_init(rdp);
if (!s)
return NULL;
if (!Stream_SafeSeek(s, RDP_SHARE_DATA_HEADER_LENGTH))
goto fail;
return s;
fail:
Stream_Release(s);
return NULL;
}
BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo)
@ -278,15 +294,21 @@ BOOL rdp_set_error_info(rdpRdp* rdp, UINT32 errorInfo)
wStream* rdp_message_channel_pdu_init(rdpRdp* rdp)
{
wStream* s;
s = transport_send_stream_init(rdp->transport, 2048);
wStream* s = transport_send_stream_init(rdp->transport, 4096);
if (!s)
return NULL;
Stream_Seek(s, RDP_PACKET_HEADER_MAX_LENGTH);
rdp_security_stream_init(rdp, s, TRUE);
if (!Stream_SafeSeek(s, RDP_PACKET_HEADER_MAX_LENGTH))
goto fail;
if (!rdp_security_stream_init(rdp, s, TRUE))
goto fail;
return s;
fail:
Stream_Release(s);
return NULL;
}
/**
@ -537,23 +559,34 @@ static UINT32 rdp_get_sec_bytes(rdpRdp* rdp, UINT16 sec_flags)
BOOL rdp_send(rdpRdp* rdp, wStream* s, UINT16 channel_id)
{
BOOL rc = FALSE;
UINT32 pad;
UINT16 length;
if (!s)
return FALSE;
if (!rdp)
goto fail;
length = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
rdp_write_header(rdp, s, length, channel_id);
if (!rdp_security_stream_out(rdp, s, length, 0, &pad))
return FALSE;
goto fail;
length += pad;
Stream_SetPosition(s, length);
Stream_SealLength(s);
if (transport_write(rdp->transport, s) < 0)
return FALSE;
goto fail;
return TRUE;
rc = TRUE;
fail:
Stream_Release(s);
return rc;
}
BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id)
@ -562,6 +595,10 @@ BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id)
UINT32 sec_bytes;
size_t sec_hold;
UINT32 pad;
if (!rdp || !s)
return FALSE;
length = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
@ -586,10 +623,18 @@ BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type, UINT16 channel_id)
BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
{
BOOL rc = FALSE;
size_t length;
UINT32 sec_bytes;
size_t sec_hold;
UINT32 pad;
if (!s)
return FALSE;
if (!rdp)
goto fail;
length = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
rdp_write_header(rdp, s, length, MCS_GLOBAL_CHANNEL_ID);
@ -601,7 +646,7 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
Stream_SetPosition(s, sec_hold);
if (!rdp_security_stream_out(rdp, s, length, 0, &pad))
return FALSE;
goto fail;
length += pad;
Stream_SetPosition(s, length);
@ -610,30 +655,44 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type, UINT16 channel_id)
type, Stream_Length(s), channel_id);
if (transport_write(rdp->transport, s) < 0)
return FALSE;
goto fail;
return TRUE;
rc = TRUE;
fail:
Stream_Release(s);
return rc;
}
BOOL rdp_send_message_channel_pdu(rdpRdp* rdp, wStream* s, UINT16 sec_flags)
{
BOOL rc = FALSE;
UINT16 length;
UINT32 pad;
if (!s)
return FALSE;
if (!rdp)
goto fail;
length = Stream_GetPosition(s);
Stream_SetPosition(s, 0);
rdp_write_header(rdp, s, length, rdp->mcs->messageChannelId);
if (!rdp_security_stream_out(rdp, s, length, sec_flags, &pad))
return FALSE;
goto fail;
length += pad;
Stream_SetPosition(s, length);
Stream_SealLength(s);
if (transport_write(rdp->transport, s) < 0)
return FALSE;
goto fail;
return TRUE;
rc = TRUE;
fail:
Stream_Release(s);
return rc;
}
static BOOL rdp_recv_server_shutdown_denied_pdu(rdpRdp* rdp, wStream* s)

View File

@ -192,20 +192,18 @@ FREERDP_LOCAL BOOL rdp_read_share_data_header(wStream* s, UINT16* length,
FREERDP_LOCAL void rdp_write_share_data_header(wStream* s, UINT16 length,
BYTE type, UINT32 share_id);
FREERDP_LOCAL int rdp_init_stream(rdpRdp* rdp, wStream* s);
FREERDP_LOCAL wStream* rdp_send_stream_init(rdpRdp* rdp);
FREERDP_LOCAL wStream* rdp_send_stream_pdu_init(rdpRdp* rdp);
FREERDP_LOCAL BOOL rdp_read_header(rdpRdp* rdp, wStream* s, UINT16* length,
UINT16* channel_id);
FREERDP_LOCAL void rdp_write_header(rdpRdp* rdp, wStream* s, UINT16 length,
UINT16 channel_id);
FREERDP_LOCAL int rdp_init_stream_pdu(rdpRdp* rdp, wStream* s);
FREERDP_LOCAL BOOL rdp_send_pdu(rdpRdp* rdp, wStream* s, UINT16 type,
UINT16 channel_id);
FREERDP_LOCAL wStream* rdp_data_pdu_init(rdpRdp* rdp);
FREERDP_LOCAL int rdp_init_stream_data_pdu(rdpRdp* rdp, wStream* s);
FREERDP_LOCAL BOOL rdp_send_data_pdu(rdpRdp* rdp, wStream* s, BYTE type,
UINT16 channel_id);
FREERDP_LOCAL int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s);

View File

@ -995,21 +995,17 @@ static void update_write_refresh_rect(wStream* s, BYTE count,
static BOOL update_send_refresh_rect(rdpContext* context, BYTE count,
const RECTANGLE_16* areas)
{
wStream* s;
rdpRdp* rdp = context->rdp;
if (rdp->settings->RefreshRect)
{
BOOL ret;
s = rdp_data_pdu_init(rdp);
wStream* s = rdp_data_pdu_init(rdp);
if (!s)
return FALSE;
update_write_refresh_rect(s, count, areas);
ret = rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_REFRESH_RECT, rdp->mcs->userId);
Stream_Release(s);
return ret;
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_REFRESH_RECT, rdp->mcs->userId);
}
return TRUE;
@ -1034,22 +1030,18 @@ static void update_write_suppress_output(wStream* s, BYTE allow,
static BOOL update_send_suppress_output(rdpContext* context, BYTE allow,
const RECTANGLE_16* area)
{
wStream* s;
rdpRdp* rdp = context->rdp;
if (rdp->settings->SuppressOutput)
{
BOOL ret;
s = rdp_data_pdu_init(rdp);
wStream* s = rdp_data_pdu_init(rdp);
if (!s)
return FALSE;
update_write_suppress_output(s, allow, area);
ret = rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SUPPRESS_OUTPUT,
rdp->mcs->userId);
Stream_Release(s);
return ret;
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SUPPRESS_OUTPUT,
rdp->mcs->userId);
}
return TRUE;
@ -1169,22 +1161,18 @@ out_fail:
static BOOL update_send_frame_acknowledge(rdpContext* context, UINT32 frameId)
{
wStream* s;
rdpRdp* rdp = context->rdp;
if (rdp->settings->ReceivedCapabilities[CAPSET_TYPE_FRAME_ACKNOWLEDGE])
{
BOOL ret;
s = rdp_data_pdu_init(rdp);
wStream* s = rdp_data_pdu_init(rdp);
if (!s)
return FALSE;
Stream_Write_UINT32(s, frameId);
ret = rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE,
rdp->mcs->userId);
Stream_Release(s);
return ret;
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_FRAME_ACKNOWLEDGE,
rdp->mcs->userId);
}
return TRUE;
@ -1244,7 +1232,6 @@ static BOOL update_send_play_sound(rdpContext* context,
{
wStream* s;
rdpRdp* rdp = context->rdp;
BOOL ret;
if (!rdp->settings->ReceivedCapabilities[CAPSET_TYPE_SOUND])
{
@ -1258,9 +1245,7 @@ static BOOL update_send_play_sound(rdpContext* context,
Stream_Write_UINT32(s, play_sound->duration);
Stream_Write_UINT32(s, play_sound->frequency);
ret = rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_PLAY_SOUND, rdp->mcs->userId);
Stream_Release(s);
return ret;
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_PLAY_SOUND, rdp->mcs->userId);
}
/**
* Primary Drawing Orders
@ -2065,7 +2050,6 @@ static BOOL update_send_set_keyboard_indicators(rdpContext* context,
{
wStream* s;
rdpRdp* rdp = context->rdp;
BOOL ret;
s = rdp_data_pdu_init(rdp);
if (!s)
@ -2074,10 +2058,8 @@ static BOOL update_send_set_keyboard_indicators(rdpContext* context,
Stream_Write_UINT16(s,
0); /* unitId should be 0 according to MS-RDPBCGR 2.2.8.2.1.1 */
Stream_Write_UINT16(s, led_flags); /* ledFlags (2 bytes) */
ret = rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS,
rdp->mcs->userId);
Stream_Release(s);
return ret;
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS,
rdp->mcs->userId);
}
static BOOL update_send_set_keyboard_ime_status(rdpContext* context,
@ -2085,7 +2067,6 @@ static BOOL update_send_set_keyboard_ime_status(rdpContext* context,
{
wStream* s;
rdpRdp* rdp = context->rdp;
BOOL ret;
s = rdp_data_pdu_init(rdp);
if (!s)
@ -2095,10 +2076,8 @@ static BOOL update_send_set_keyboard_ime_status(rdpContext* context,
Stream_Write_UINT16(s, imeId);
Stream_Write_UINT32(s, imeState);
Stream_Write_UINT32(s, imeConvMode);
ret = rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS,
rdp->mcs->userId);
Stream_Release(s);
return ret;
return rdp_send_data_pdu(rdp, s, DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS,
rdp->mcs->userId);
}
void update_register_server_callbacks(rdpUpdate* update)

View File

@ -175,6 +175,7 @@ wStream* StreamPool_Take(wStreamPool* pool, size_t size)
else
{
Stream_SetPosition(s, 0);
Stream_SetLength(s, Stream_Capacity(s));
StreamPool_ShiftAvailable(pool, foundIndex, -1);
}