diff --git a/libfreerdp/core/gateway/ncacn_http.c b/libfreerdp/core/gateway/ncacn_http.c index 6f945fcb9..5f26c8e3c 100644 --- a/libfreerdp/core/gateway/ncacn_http.c +++ b/libfreerdp/core/gateway/ncacn_http.c @@ -94,9 +94,8 @@ int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc) if (!s) return -1; - WLog_DBG(TAG, "\n%s", Stream_Buffer(s)); - status = rpc_in_write(rpc, Stream_Buffer(s), Stream_Length(s)); + Stream_Free(s, TRUE); return (status > 0) ? 1 : -1; @@ -104,33 +103,39 @@ int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc) int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc) { - char* token64; - int ntlm_token_length = 0; - BYTE* ntlm_token_data = NULL; - HttpResponse* http_response; + int status = -1; + char* token64 = NULL; + HttpResponse* response; + int ntlmTokenLength = 0; + BYTE* ntlmTokenData = NULL; rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm; - http_response = http_response_recv(rpc->TlsIn); + response = http_response_recv(rpc->TlsIn); - if (!http_response) + if (!response) return -1; - if (ListDictionary_Contains(http_response->Authenticates, "NTLM")) + if (ListDictionary_Contains(response->Authenticates, "NTLM")) { - token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM"); + token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM"); if (!token64) goto out; - crypto_base64_decode(token64, strlen(token64), &ntlm_token_data, &ntlm_token_length); + crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength); + } + + if (ntlmTokenData && ntlmTokenLength) + { + ntlm->inputBuffer[0].pvBuffer = ntlmTokenData; + ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength; + status = 1; } out: - ntlm->inputBuffer[0].pvBuffer = ntlm_token_data; - ntlm->inputBuffer[0].cbBuffer = ntlm_token_length; - http_response_free(http_response); + http_response_free(response); - return 1; + return status; } int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel) @@ -182,36 +187,48 @@ int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel) return 1; } +void rpc_ncacn_http_ntlm_uninit(rdpRpc* rpc, TSG_CHANNEL channel) +{ + if (channel == TSG_CHANNEL_IN) + { + ntlm_client_uninit(rpc->NtlmHttpIn->ntlm); + ntlm_free(rpc->NtlmHttpIn->ntlm); + rpc->NtlmHttpIn->ntlm = NULL; + } + else if (channel == TSG_CHANNEL_OUT) + { + ntlm_client_uninit(rpc->NtlmHttpOut->ntlm); + ntlm_free(rpc->NtlmHttpOut->ntlm); + rpc->NtlmHttpOut->ntlm = NULL; + } +} + BOOL rpc_ntlm_http_in_connect(rdpRpc* rpc) { BOOL status = FALSE; - rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm; - if (rpc_ncacn_http_ntlm_init(rpc, TSG_CHANNEL_IN) <= 0) + if (rpc_ncacn_http_ntlm_init(rpc, TSG_CHANNEL_IN) < 0) goto out; /* Send IN Channel Request */ - if (rpc_ncacn_http_send_in_channel_request(rpc) <= 0) + if (rpc_ncacn_http_send_in_channel_request(rpc) < 0) goto out; /* Receive IN Channel Response */ - if (rpc_ncacn_http_recv_in_channel_response(rpc) <= 0) + if (rpc_ncacn_http_recv_in_channel_response(rpc) < 0) goto out; /* Send IN Channel Request */ - if (rpc_ncacn_http_send_in_channel_request(rpc) <= 0) + if (rpc_ncacn_http_send_in_channel_request(rpc) < 0) goto out; status = TRUE; out: - ntlm_client_uninit(ntlm); - ntlm_free(ntlm); - rpc->NtlmHttpIn->ntlm = NULL; - + rpc_ncacn_http_ntlm_uninit(rpc, TSG_CHANNEL_IN); return status; } @@ -219,22 +236,21 @@ int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc) { wStream* s; int status; - int content_length; - BOOL continue_needed; + int contentLength; + BOOL continueNeeded; rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm; - continue_needed = ntlm_authenticate(ntlm); + continueNeeded = ntlm_authenticate(ntlm); - content_length = (continue_needed) ? 0 : 76; + contentLength = (continueNeeded) ? 0 : 76; - s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer[0], content_length, TSG_CHANNEL_OUT); + s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer[0], contentLength, TSG_CHANNEL_OUT); if (!s) return -1; - WLog_DBG(TAG, "\n%s", Stream_Buffer(s)); - status = rpc_out_write(rpc, Stream_Buffer(s), Stream_Length(s)); + Stream_Free(s, TRUE); return (status > 0) ? 1 : -1; @@ -242,10 +258,11 @@ int rpc_ncacn_http_send_out_channel_request(rdpRpc* rpc) int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc) { - char* token64; + int status = -1; + char* token64 = NULL; HttpResponse* response; - int ntlm_token_length = 0; - BYTE* ntlm_token_data = NULL; + int ntlmTokenLength = 0; + BYTE* ntlmTokenData = NULL; rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm; response = http_response_recv(rpc->TlsOut); @@ -260,57 +277,64 @@ int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc) if (!token64) goto out; - crypto_base64_decode(token64, strlen(token64), &ntlm_token_data, &ntlm_token_length); + crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength); + } + + if (ntlmTokenData && ntlmTokenLength) + { + ntlm->inputBuffer[0].pvBuffer = ntlmTokenData; + ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength; + status = 1; } out: - ntlm->inputBuffer[0].pvBuffer = ntlm_token_data; - ntlm->inputBuffer[0].cbBuffer = ntlm_token_length; http_response_free(response); - return 1; + return status; } int rpc_http_send_replacement_out_channel_request(rdpRpc* rpc) { + int status; wStream* s; - int content_length; - content_length = 120; + s = rpc_ntlm_http_request(rpc, NULL, 120, TSG_CHANNEL_OUT); - s = rpc_ntlm_http_request(rpc, NULL, content_length, TSG_CHANNEL_OUT); + if (!s) + return -1; WLog_DBG(TAG, "\n%s", Stream_Buffer(s)); - rpc_out_write(rpc, Stream_Buffer(s), Stream_Length(s)); + + status = rpc_out_write(rpc, Stream_Buffer(s), Stream_Length(s)); + Stream_Free(s, TRUE); - return 0; + return (status > 0) ? 1 : -1; } BOOL rpc_ntlm_http_out_connect(rdpRpc* rpc) { BOOL status = FALSE; - rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm; - if (rpc_ncacn_http_ntlm_init(rpc, TSG_CHANNEL_OUT) <= 0) + if (rpc_ncacn_http_ntlm_init(rpc, TSG_CHANNEL_OUT) < 0) goto out; /* Send OUT Channel Request */ - if (rpc_ncacn_http_send_out_channel_request(rpc) <= 0) + if (rpc_ncacn_http_send_out_channel_request(rpc) < 0) { WLog_ERR(TAG, "rpc_ncacn_http_send_out_channel_request failure"); goto out; } /* Receive OUT Channel Response */ - if (rpc_ncacn_http_recv_out_channel_response(rpc) <= 0) + if (rpc_ncacn_http_recv_out_channel_response(rpc) < 0) { WLog_ERR(TAG, "rpc_ncacn_http_recv_out_channel_response failure"); goto out; } /* Send OUT Channel Request */ - if (rpc_ncacn_http_send_out_channel_request(rpc) <= 0) + if (rpc_ncacn_http_send_out_channel_request(rpc) < 0) { WLog_ERR(TAG, "rpc_ncacn_http_send_out_channel_request failure"); goto out; @@ -319,10 +343,7 @@ BOOL rpc_ntlm_http_out_connect(rdpRpc* rpc) status = TRUE; out: - ntlm_client_uninit(ntlm); - ntlm_free(ntlm); - rpc->NtlmHttpOut->ntlm = NULL; - + rpc_ncacn_http_ntlm_uninit(rpc, TSG_CHANNEL_OUT); return status; } diff --git a/libfreerdp/core/gateway/ncacn_http.h b/libfreerdp/core/gateway/ncacn_http.h index 3e92b4dc4..9a070aa6e 100644 --- a/libfreerdp/core/gateway/ncacn_http.h +++ b/libfreerdp/core/gateway/ncacn_http.h @@ -32,6 +32,9 @@ #include "rpc.h" +int rpc_ncacn_http_ntlm_init(rdpRpc* rpc, TSG_CHANNEL channel); +void rpc_ncacn_http_ntlm_uninit(rdpRpc* rpc, TSG_CHANNEL channel); + BOOL rpc_ntlm_http_out_connect(rdpRpc* rpc); BOOL rpc_ntlm_http_in_connect(rdpRpc* rpc); diff --git a/libfreerdp/core/gateway/rpc.c b/libfreerdp/core/gateway/rpc.c index afa38c48d..b782d28a5 100644 --- a/libfreerdp/core/gateway/rpc.c +++ b/libfreerdp/core/gateway/rpc.c @@ -260,16 +260,19 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* l rpc_offset_align(offset, 8); alloc_hint = header->response.alloc_hint; break; + case PTYPE_REQUEST: *offset += 4; rpc_offset_align(offset, 8); alloc_hint = header->request.alloc_hint; break; + case PTYPE_RTS: *offset += 4; break; + default: - WLog_ERR(TAG, "unknown ptype=0x%x", header->common.ptype); + WLog_ERR(TAG, "Unknown PTYPE: 0x%04X", header->common.ptype); return FALSE; } @@ -289,13 +292,12 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* l sec_trailer_offset = frag_length - auth_length - 8; sec_trailer = (rpc_sec_trailer*) &buffer[sec_trailer_offset]; auth_pad_length = sec_trailer->auth_pad_length; + #if 0 - WLog_DBG(TAG, "sec_trailer: type: %d level: %d pad_length: %d reserved: %d context_id: %d", - sec_trailer->auth_type, - sec_trailer->auth_level, - sec_trailer->auth_pad_length, - sec_trailer->auth_reserved, - sec_trailer->auth_context_id); + WLog_DBG(TAG, "sec_trailer: type: %d level: %d pad_length: %d reserved: %d context_id: %d", + sec_trailer->auth_type, sec_trailer->auth_level, + sec_trailer->auth_pad_length, sec_trailer->auth_reserved, + sec_trailer->auth_context_id); #endif /** @@ -363,7 +365,6 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) if (!ntlm || !ntlm->table) { WLog_ERR(TAG, "invalid ntlm context"); - fprintf(stderr, "invalid ntlm context: %p %p\n", ntlm, ntlm->table); return -1; } @@ -372,6 +373,7 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) WLog_ERR(TAG, "QueryContextAttributes SECPKG_ATTR_SIZES failure"); return -1; } + ZeroMemory(&Buffers, sizeof(Buffers)); request_pdu = (rpcconn_request_hdr_t*) calloc(1, sizeof(rpcconn_request_hdr_t)); @@ -454,6 +456,8 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) length = -1; free(request_pdu); + free(buffer); + return length; out_free_clientCall: @@ -522,12 +526,15 @@ void rpc_client_virtual_connection_init(rdpRpc* rpc, RpcVirtualConnection* conne RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc) { - RpcVirtualConnection* connection = (RpcVirtualConnection*) calloc(1, sizeof(RpcVirtualConnection)); + RpcVirtualConnection* connection; + + connection = (RpcVirtualConnection*) calloc(1, sizeof(RpcVirtualConnection)); if (!connection) return NULL; connection->State = VIRTUAL_CONNECTION_STATE_INITIAL; + connection->DefaultInChannel = (RpcInChannel*) calloc(1, sizeof(RpcInChannel)); if (!connection->DefaultInChannel) @@ -539,6 +546,7 @@ RpcVirtualConnection* rpc_client_virtual_connection_new(rdpRpc* rpc) goto out_default_in; rpc_client_virtual_connection_init(rpc, connection); + return connection; out_default_in: free(connection->DefaultInChannel); diff --git a/libfreerdp/core/gateway/rpc_bind.c b/libfreerdp/core/gateway/rpc_bind.c index bc010cee0..741491ea6 100644 --- a/libfreerdp/core/gateway/rpc_bind.c +++ b/libfreerdp/core/gateway/rpc_bind.c @@ -264,6 +264,7 @@ int rpc_send_bind_pdu(rdpRpc* rpc) free(buffer); return -1; } + if (ArrayList_Add(rpc->client->ClientCallList, clientCall) < 0) { free(buffer); @@ -277,7 +278,9 @@ int rpc_send_bind_pdu(rdpRpc* rpc) free(bind_pdu->p_context_elem.p_cont_elem); free(bind_pdu); - return status; + free(buffer); + + return (status > 0) ? 1 : -1; } /** @@ -397,6 +400,7 @@ int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) status = rpc_send_pdu(rpc, buffer, length); free(auth_3_pdu); + free(buffer); - return status; + return (status > 0) ? 1 : -1; } diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 176c09c92..b509e5f09 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -194,7 +194,13 @@ int rpc_client_recv_pdu(rdpRpc* rpc, RPC_PDU* pdu) return -1; } - rts_recv_CONN_A3_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s)); + status = rts_recv_CONN_A3_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s)); + + if (status < 0) + { + WLog_ERR(TAG, "rts_recv_CONN_A3_pdu failure"); + return -1; + } rpc_client_virtual_connection_transition_to_state(rpc, rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_WAIT_C2); @@ -210,10 +216,16 @@ int rpc_client_recv_pdu(rdpRpc* rpc, RPC_PDU* pdu) if (!rts_match_pdu_signature(rpc, &RTS_PDU_CONN_C2_SIGNATURE, rts)) { WLog_ERR(TAG, "unexpected RTS PDU: Expected CONN/C2"); - return FALSE; + return -1; } - rts_recv_CONN_C2_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s)); + status = rts_recv_CONN_C2_pdu(rpc, Stream_Buffer(pdu->s), Stream_Length(pdu->s)); + + if (status < 0) + { + WLog_ERR(TAG, "rts_recv_CONN_C2_pdu failure"); + return -1; + } rpc_client_virtual_connection_transition_to_state(rpc, rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_OPENED); @@ -573,6 +585,9 @@ int rpc_send_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) status = rpc_in_write(rpc, buffer, length); + if (status <= 0) + return -1; + header = (rpcconn_common_hdr_t*) buffer; clientCall = rpc_client_call_find_by_id(rpc, header->call_id); clientCall->State = RPC_CLIENT_CALL_STATE_DISPATCHED; @@ -590,8 +605,6 @@ int rpc_send_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) inChannel->SenderAvailableWindow -= status; } - free(buffer); - return status; } diff --git a/libfreerdp/core/gateway/rts.c b/libfreerdp/core/gateway/rts.c index 6b08b0704..04b239506 100644 --- a/libfreerdp/core/gateway/rts.c +++ b/libfreerdp/core/gateway/rts.c @@ -33,6 +33,25 @@ #define TAG FREERDP_TAG("core.gateway.rts") +const char* const RTS_CMD_STRINGS[] = +{ + "ReceiveWindowSize", + "FlowControlAck", + "ConnectionTimeout", + "Cookie", + "ChannelLifetime", + "ClientKeepalive", + "Version", + "Empty", + "Padding", + "NegativeANCE", + "ANCE", + "ClientAddress", + "AssociationGroupId", + "Destination", + "PingTrafficSentNotify" +}; + /** * [MS-RPCH]: Remote Procedure Call over HTTP Protocol Specification: * http://msdn.microsoft.com/en-us/library/cc243950/ @@ -75,6 +94,8 @@ BOOL rts_connect(rdpRpc* rpc) return FALSE; } + /* Send CONN/A1 PDU over OUT channel */ + if (rts_send_CONN_A1_pdu(rpc) < 0) { WLog_ERR(TAG, "rpc_send_CONN_A1_pdu error!"); @@ -87,6 +108,8 @@ BOOL rts_connect(rdpRpc* rpc) return FALSE; } + /* Send CONN/B1 PDU over IN channel */ + if (rts_send_CONN_B1_pdu(rpc) < 0) { WLog_ERR(TAG, "rpc_send_CONN_B1_pdu error!"); @@ -96,6 +119,8 @@ BOOL rts_connect(rdpRpc* rpc) rpc_client_virtual_connection_transition_to_state(rpc, rpc->VirtualConnection, VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT); + /* Receive OUT channel response */ + response = http_response_recv(rpc->TlsOut); if (!response) @@ -134,25 +159,6 @@ BOOL rts_connect(rdpRpc* rpc) return TRUE; } -const char* const RTS_CMD_STRINGS[] = -{ - "ReceiveWindowSize", - "FlowControlAck", - "ConnectionTimeout", - "Cookie", - "ChannelLifetime", - "ClientKeepalive", - "Version", - "Empty", - "Padding", - "NegativeANCE", - "ANCE", - "ClientAddress", - "AssociationGroupId", - "Destination", - "PingTrafficSentNotify" -}; - /** * RTS PDU Header * @@ -530,6 +536,7 @@ void rts_generate_cookie(BYTE* cookie) int rts_send_CONN_A1_pdu(rdpRpc* rpc) { + int status; BYTE* buffer; rpcconn_rts_hdr_t header; UINT32 ReceiveWindowSize; @@ -561,11 +568,11 @@ int rts_send_CONN_A1_pdu(rdpRpc* rpc) rts_cookie_command_write(&buffer[48], OUTChannelCookie); /* OUTChannelCookie (20 bytes) */ rts_receive_window_size_command_write(&buffer[68], ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */ - rpc_out_write(rpc, buffer, header.frag_length); + status = rpc_out_write(rpc, buffer, header.frag_length); free(buffer); - return 0; + return (status > 0) ? 1 : -1; } int rts_recv_CONN_A3_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) @@ -578,7 +585,7 @@ int rts_recv_CONN_A3_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) rpc->VirtualConnection->DefaultInChannel->PingOriginator.ConnectionTimeout = ConnectionTimeout; - return 0; + return 1; } /* CONN/B Sequence */ @@ -626,7 +633,7 @@ int rts_send_CONN_B1_pdu(rdpRpc* rpc) free(buffer); - return status; + return (status > 0) ? 1 : -1; } /* CONN/C Sequence */ @@ -653,13 +660,14 @@ int rts_recv_CONN_C2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) rpc->VirtualConnection->DefaultInChannel->State = CLIENT_IN_CHANNEL_STATE_OPENED; rpc->VirtualConnection->DefaultOutChannel->State = CLIENT_OUT_CHANNEL_STATE_OPENED; - return 0; + return 1; } /* Out-of-Sequence PDUs */ int rts_send_keep_alive_pdu(rdpRpc* rpc) { + int status; BYTE* buffer; UINT32 length; rpcconn_rts_hdr_t header; @@ -681,18 +689,16 @@ int rts_send_keep_alive_pdu(rdpRpc* rpc) length = header.frag_length; - if (rpc_in_write(rpc, buffer, length) < 0) - { - free (buffer); - return -1; - } + status = rpc_in_write(rpc, buffer, length); + free(buffer); - return length; + return (status > 0) ? 1 : -1; } int rts_send_flow_control_ack_pdu(rdpRpc* rpc) { + int status; BYTE* buffer; UINT32 length; rpcconn_rts_hdr_t header; @@ -727,15 +733,11 @@ int rts_send_flow_control_ack_pdu(rdpRpc* rpc) length = header.frag_length; - if (rpc_in_write(rpc, buffer, length) < 0) - { - free(buffer); - return -1; - } + status = rpc_in_write(rpc, buffer, length); free(buffer); - return 0; + return (status > 0) ? 1 : -1; } int rts_recv_flow_control_ack_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) @@ -750,15 +752,15 @@ int rts_recv_flow_control_ack_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) &BytesReceived, &AvailableWindow, (BYTE*) &ChannelCookie) + 4; #if 0 - WLog_ERR(TAG, "BytesReceived: %d AvailableWindow: %d", + WLog_ERR(TAG, "BytesReceived: %d AvailableWindow: %d", BytesReceived, AvailableWindow); - WLog_ERR(TAG, "ChannelCookie: " RPC_UUID_FORMAT_STRING "", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie)); + WLog_ERR(TAG, "ChannelCookie: " RPC_UUID_FORMAT_STRING "", RPC_UUID_FORMAT_ARGUMENTS(ChannelCookie)); #endif rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow = AvailableWindow - (rpc->VirtualConnection->DefaultInChannel->BytesSent - BytesReceived); - return 0; + return 1; } int rts_recv_flow_control_ack_with_destination_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) @@ -799,11 +801,12 @@ int rts_recv_flow_control_ack_with_destination_pdu(rdpRpc* rpc, BYTE* buffer, UI rpc->VirtualConnection->DefaultInChannel->SenderAvailableWindow = AvailableWindow - (rpc->VirtualConnection->DefaultInChannel->BytesSent - BytesReceived); - return 0; + return 1; } int rts_send_ping_pdu(rdpRpc* rpc) { + int status; BYTE* buffer; UINT32 length; rpcconn_rts_hdr_t header; @@ -824,14 +827,11 @@ int rts_send_ping_pdu(rdpRpc* rpc) length = header.frag_length; - if (rpc_in_write(rpc, buffer, length) < 0) - { - free (buffer); - return -1; - } + status = rpc_in_write(rpc, buffer, length); + free(buffer); - return length; + return (status > 0) ? 1 : -1; } int rts_command_length(rdpRpc* rpc, UINT32 CommandType, BYTE* buffer, UINT32 length) @@ -901,7 +901,7 @@ int rts_command_length(rdpRpc* rpc, UINT32 CommandType, BYTE* buffer, UINT32 len break; default: - WLog_ERR(TAG, "Error: Unknown RTS Command Type: 0x%x", CommandType); + WLog_ERR(TAG, "Error: Unknown RTS Command Type: 0x%x", CommandType); return -1; break; } @@ -911,6 +911,7 @@ int rts_command_length(rdpRpc* rpc, UINT32 CommandType, BYTE* buffer, UINT32 len int rts_send_OUT_R1_A3_pdu(rdpRpc* rpc) { + int status; BYTE* buffer; rpcconn_rts_hdr_t header; UINT32 ReceiveWindowSize; @@ -944,15 +945,16 @@ int rts_send_OUT_R1_A3_pdu(rdpRpc* rpc) rts_cookie_command_write(&buffer[68], SuccessorChannelCookie); /* SuccessorChannelCookie (20 bytes) */ rts_receive_window_size_command_write(&buffer[88], ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */ - rpc_out_write(rpc, buffer, header.frag_length); + status = rpc_out_write(rpc, buffer, header.frag_length); free(buffer); - return 0; + return (status > 0) ? 1 : -1; } int rts_recv_OUT_R1_A2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) { + int status; UINT32 offset; UINT32 Destination = 0; @@ -963,15 +965,22 @@ int rts_recv_OUT_R1_A2_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) WLog_ERR(TAG, "TS Gateway channel recycling is incomplete"); - rpc_http_send_replacement_out_channel_request(rpc); + status = rpc_http_send_replacement_out_channel_request(rpc); - rts_send_OUT_R1_A3_pdu(rpc); + if (status < 0) + return -1; - return 0; + status = rts_send_OUT_R1_A3_pdu(rpc); + + if (status < 0) + return -1; + + return 1; } int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) { + int status = -1; UINT32 SignatureId; rpcconn_rts_hdr_t* rts; RtsPduSignature signature; @@ -984,16 +993,20 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) switch (SignatureId) { case RTS_PDU_FLOW_CONTROL_ACK: - return rts_recv_flow_control_ack_pdu(rpc, buffer, length); + status = rts_recv_flow_control_ack_pdu(rpc, buffer, length); + break; case RTS_PDU_FLOW_CONTROL_ACK_WITH_DESTINATION: - return rts_recv_flow_control_ack_with_destination_pdu(rpc, buffer, length); + status = rts_recv_flow_control_ack_with_destination_pdu(rpc, buffer, length); + break; case RTS_PDU_PING: - return rts_send_ping_pdu(rpc); + status = rts_send_ping_pdu(rpc); + break; case RTS_PDU_OUT_R1_A2: - return rts_recv_OUT_R1_A2_pdu(rpc, buffer, length); + status = rts_recv_OUT_R1_A2_pdu(rpc, buffer, length); + break; default: WLog_ERR(TAG, "unimplemented signature id: 0x%08X", SignatureId); @@ -1001,5 +1014,5 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) break; } - return 0; + return status; }