From 90188e16ad66e805365e7ff8ecf6f9793c856da6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Thu, 15 Nov 2012 16:25:22 -0500 Subject: [PATCH] libfreerdp-core: refactor all RTS command write functions not to use STREAM utils --- libfreerdp/core/ntlm.h | 2 + libfreerdp/core/rpc.c | 207 ++++++++++++++++++----------------------- libfreerdp/core/rpc.h | 83 ++++++++++++++--- libfreerdp/core/rts.c | 183 +++++++++++++++++++++++------------- libfreerdp/core/rts.h | 94 +++++++------------ libfreerdp/core/tsg.c | 4 +- 6 files changed, 317 insertions(+), 256 deletions(-) diff --git a/libfreerdp/core/ntlm.h b/libfreerdp/core/ntlm.h index 435e1c9f2..1156e4d14 100644 --- a/libfreerdp/core/ntlm.h +++ b/libfreerdp/core/ntlm.h @@ -77,6 +77,8 @@ BOOL ntlm_authenticate(rdpNtlm* ntlm); BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL confidentiality, char* user, char* domain, char* password); void ntlm_client_uninit(rdpNtlm* ntlm); +BOOL ntlm_client_make_spn(rdpNtlm* ntlm, LPCTSTR ServiceClass, char* hostname); + rdpNtlm* ntlm_new(); void ntlm_free(rdpNtlm* ntlm); diff --git a/libfreerdp/core/rpc.c b/libfreerdp/core/rpc.c index 28c3d2a2e..6439d616b 100644 --- a/libfreerdp/core/rpc.c +++ b/libfreerdp/core/rpc.c @@ -214,50 +214,47 @@ const RPC_FAULT_CODE RPC_FAULT_CODES[] = { 0, NULL } }; -void rpc_pdu_header_print(RPC_PDU_HEADER* header) +void rpc_pdu_header_print(rpcconn_hdr_t* header) { - printf("rpc_vers: %d\n", header->rpc_vers); - printf("rpc_vers_minor: %d\n", header->rpc_vers_minor); + printf("rpc_vers: %d\n", header->common.rpc_vers); + printf("rpc_vers_minor: %d\n", header->common.rpc_vers_minor); - if (header->ptype > PTYPE_RTS) - printf("ptype: %s (%d)\n", "PTYPE_UNKNOWN", header->ptype); + if (header->common.ptype > PTYPE_RTS) + printf("ptype: %s (%d)\n", "PTYPE_UNKNOWN", header->common.ptype); else - printf("ptype: %s (%d)\n", PTYPE_STRINGS[header->ptype], header->ptype); + printf("ptype: %s (%d)\n", PTYPE_STRINGS[header->common.ptype], header->common.ptype); - printf("pfc_flags (0x%02X) = {", header->pfc_flags); - if (header->pfc_flags & PFC_FIRST_FRAG) + printf("pfc_flags (0x%02X) = {", header->common.pfc_flags); + if (header->common.pfc_flags & PFC_FIRST_FRAG) printf(" PFC_FIRST_FRAG"); - if (header->pfc_flags & PFC_LAST_FRAG) + if (header->common.pfc_flags & PFC_LAST_FRAG) printf(" PFC_LAST_FRAG"); - if (header->pfc_flags & PFC_PENDING_CANCEL) + if (header->common.pfc_flags & PFC_PENDING_CANCEL) printf(" PFC_PENDING_CANCEL"); - if (header->pfc_flags & PFC_RESERVED_1) + if (header->common.pfc_flags & PFC_RESERVED_1) printf(" PFC_RESERVED_1"); - if (header->pfc_flags & PFC_CONC_MPX) + if (header->common.pfc_flags & PFC_CONC_MPX) printf(" PFC_CONC_MPX"); - if (header->pfc_flags & PFC_DID_NOT_EXECUTE) + if (header->common.pfc_flags & PFC_DID_NOT_EXECUTE) printf(" PFC_DID_NOT_EXECUTE"); - if (header->pfc_flags & PFC_OBJECT_UUID) + if (header->common.pfc_flags & PFC_OBJECT_UUID) printf(" PFC_OBJECT_UUID"); printf(" }\n"); printf("packed_drep[4]: %02X %02X %02X %02X\n", - header->packed_drep[0], header->packed_drep[1], - header->packed_drep[2], header->packed_drep[3]); + header->common.packed_drep[0], header->common.packed_drep[1], + header->common.packed_drep[2], header->common.packed_drep[3]); - printf("frag_length: %d\n", header->frag_length); - printf("auth_length: %d\n", header->auth_length); - printf("call_id: %d\n", header->call_id); + printf("frag_length: %d\n", header->common.frag_length); + printf("auth_length: %d\n", header->common.auth_length); + printf("call_id: %d\n", header->common.call_id); - if (header->ptype == PTYPE_RESPONSE) + if (header->common.ptype == PTYPE_RESPONSE) { - rpcconn_response_hdr_t* response; - - response = (rpcconn_response_hdr_t*) header; - printf("alloc_hint: %d\n", response->alloc_hint); - printf("p_cont_id: %d\n", response->p_cont_id); - printf("cancel_count: %d\n", response->cancel_count); - printf("reserved: %d\n", response->reserved); + printf("alloc_hint: %d\n", header->response.alloc_hint); + printf("p_cont_id: %d\n", header->response.p_cont_id); + printf("cancel_count: %d\n", header->response.cancel_count); + printf("reserved: %d\n", header->response.reserved); } } @@ -426,21 +423,21 @@ BOOL rpc_ntlm_http_in_connect(rdpRpc* rpc) return TRUE; } -void rpc_pdu_header_init(rdpRpc* rpc, RPC_PDU_HEADER* header) +void rpc_pdu_header_init(rdpRpc* rpc, rpcconn_hdr_t* header) { - header->rpc_vers = rpc->rpc_vers; - header->rpc_vers_minor = rpc->rpc_vers_minor; - header->packed_drep[0] = rpc->packed_drep[0]; - header->packed_drep[1] = rpc->packed_drep[1]; - header->packed_drep[2] = rpc->packed_drep[2]; - header->packed_drep[3] = rpc->packed_drep[3]; + header->common.rpc_vers = rpc->rpc_vers; + header->common.rpc_vers_minor = rpc->rpc_vers_minor; + header->common.packed_drep[0] = rpc->packed_drep[0]; + header->common.packed_drep[1] = rpc->packed_drep[1]; + header->common.packed_drep[2] = rpc->packed_drep[2]; + header->common.packed_drep[3] = rpc->packed_drep[3]; } int rpc_out_write(rdpRpc* rpc, BYTE* data, int length) { int status; - rpc_pdu_header_print((RPC_PDU_HEADER*) data); + rpc_pdu_header_print((rpcconn_hdr_t*) data); #ifdef WITH_DEBUG_RPC printf("rpc_out_write(): length: %d\n", length); @@ -457,7 +454,7 @@ int rpc_in_write(rdpRpc* rpc, BYTE* data, int length) { int status; - rpc_pdu_header_print((RPC_PDU_HEADER*) data); + rpc_pdu_header_print((rpcconn_hdr_t*) data); #ifdef WITH_DEBUG_RPC printf("rpc_in_write() length: %d\n", length); @@ -509,7 +506,7 @@ BOOL rpc_send_bind_pdu(rdpRpc* rpc) bind_pdu = (rpcconn_bind_hdr_t*) malloc(sizeof(rpcconn_bind_hdr_t)); ZeroMemory(bind_pdu, sizeof(rpcconn_bind_hdr_t)); - rpc_pdu_header_init(rpc, (RPC_PDU_HEADER*) bind_pdu); + rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) bind_pdu); bind_pdu->auth_length = rpc->ntlm->outputBuffer.cbBuffer; bind_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer.pvBuffer; @@ -518,8 +515,8 @@ BOOL rpc_send_bind_pdu(rdpRpc* rpc) bind_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_PENDING_CANCEL | PFC_CONC_MPX; bind_pdu->call_id = 2; - bind_pdu->max_xmit_frag = 0x0FF8; - bind_pdu->max_recv_frag = 0x0FF8; + bind_pdu->max_xmit_frag = rpc->max_xmit_frag; + bind_pdu->max_recv_frag = rpc->max_recv_frag; bind_pdu->assoc_group_id = 0; bind_pdu->p_context_elem.n_context_elem = 2; @@ -594,19 +591,19 @@ int rpc_recv_bind_ack_pdu(rdpRpc* rpc) { int status; BYTE* auth_data; - RPC_PDU_HEADER* header; + rpcconn_hdr_t* header; status = rpc_recv_pdu(rpc); if (status > 0) { - header = (RPC_PDU_HEADER*) rpc->buffer; + header = (rpcconn_hdr_t*) rpc->buffer; - rpc->ntlm->inputBuffer.cbBuffer = header->auth_length; - rpc->ntlm->inputBuffer.pvBuffer = malloc(header->auth_length); + rpc->ntlm->inputBuffer.cbBuffer = header->common.auth_length; + rpc->ntlm->inputBuffer.pvBuffer = malloc(header->common.auth_length); - auth_data = rpc->buffer + (header->frag_length - header->auth_length); - CopyMemory(rpc->ntlm->inputBuffer.pvBuffer, auth_data, header->auth_length); + auth_data = rpc->buffer + (header->common.frag_length - header->common.auth_length); + CopyMemory(rpc->ntlm->inputBuffer.pvBuffer, auth_data, header->common.auth_length); ntlm_authenticate(rpc->ntlm); } @@ -625,7 +622,7 @@ BOOL rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) auth_3_pdu = (rpcconn_rpc_auth_3_hdr_t*) malloc(sizeof(rpcconn_rpc_auth_3_hdr_t)); ZeroMemory(auth_3_pdu, sizeof(rpcconn_rpc_auth_3_hdr_t)); - rpc_pdu_header_init(rpc, (RPC_PDU_HEADER*) auth_3_pdu); + rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) auth_3_pdu); auth_3_pdu->auth_length = rpc->ntlm->outputBuffer.cbBuffer; auth_3_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer.pvBuffer; @@ -636,8 +633,8 @@ BOOL rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) offset = 20; - auth_3_pdu->max_xmit_frag = 0x0FF8; - auth_3_pdu->max_recv_frag = 0x0FF8; + auth_3_pdu->max_xmit_frag = rpc->max_xmit_frag; + auth_3_pdu->max_recv_frag = rpc->max_recv_frag; offset += 4; auth_3_pdu->auth_verifier.auth_pad_length = rpc_offset_align(&offset, 4); @@ -672,7 +669,7 @@ BOOL rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) int rpc_out_read(rdpRpc* rpc, BYTE* data, int length) { int status; - RPC_PDU_HEADER* header; + rpcconn_hdr_t* header; //if (rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow < 0x00008FFF) /* Just a simple workaround */ // rts_send_flow_control_ack_pdu(rpc); /* Send FlowControlAck every time AvailableWindow reaches the half */ @@ -683,16 +680,16 @@ int rpc_out_read(rdpRpc* rpc, BYTE* data, int length) if (status <= 0) return status; - header = (RPC_PDU_HEADER*) data; + header = (rpcconn_hdr_t*) data; rpc_pdu_header_print(header); - status = tls_read(rpc->TlsOut, &data[20], header->frag_length - 20); + status = tls_read(rpc->TlsOut, &data[20], header->common.frag_length - 20); if (status < 0) return status; - if (header->ptype == PTYPE_RTS) /* RTS PDU */ + if (header->common.ptype == PTYPE_RTS) /* RTS PDU */ { printf("rpc_out_read error: Unexpected RTS PDU\n"); return -1; @@ -700,76 +697,74 @@ int rpc_out_read(rdpRpc* rpc, BYTE* data, int length) else { /* RTS PDUs are not subject to flow control */ - rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->frag_length; - rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->frag_length; + rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->common.frag_length; + rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->common.frag_length; } - if (length < header->frag_length) + if (length < header->common.frag_length) { - printf("rpc_out_read error! receive buffer is not large enough: %d < %d\n", length, header->frag_length); + printf("rpc_out_read error! receive buffer is not large enough: %d < %d\n", + length, header->common.frag_length); return -1; } #ifdef WITH_DEBUG_RPC - printf("rpc_out_read(): length: %d\n", header->frag_length); - freerdp_hexdump(data, header->frag_length); + printf("rpc_out_read(): length: %d\n", header->common.frag_length); + freerdp_hexdump(data, header->common.frag_length); printf("\n"); #endif - return header->frag_length; + return header->common.frag_length; } -int rpc_recv_fault_pdu(RPC_PDU_HEADER* header) +int rpc_recv_fault_pdu(rpcconn_hdr_t* header) { int index; - rpcconn_fault_hdr_t* fault_pdu; - - fault_pdu = (rpcconn_fault_hdr_t*) header; printf("RPC Fault PDU:\n"); for (index = 0; RPC_FAULT_CODES[index].name != NULL; index++) { - if (RPC_FAULT_CODES[index].code == fault_pdu->status) + if (RPC_FAULT_CODES[index].code == header->fault.status) { - printf("status: %s (0x%08X)\n", RPC_FAULT_CODES[index].name, fault_pdu->status); + printf("status: %s (0x%08X)\n", RPC_FAULT_CODES[index].name, header->fault.status); return 0; } } for (index = 0; RPC_FAULT_CODES[index].name != NULL; index++) { - if (RPC_TSG_FAULT_CODES[index].code == fault_pdu->status) + if (RPC_TSG_FAULT_CODES[index].code == header->fault.status) { - printf("status: %s (0x%08X)\n", RPC_TSG_FAULT_CODES[index].name, fault_pdu->status); + printf("status: %s (0x%08X)\n", RPC_TSG_FAULT_CODES[index].name, header->fault.status); return 0; } } - printf("status: %s (0x%08X)\n", "UNKNOWN", fault_pdu->status); + printf("status: %s (0x%08X)\n", "UNKNOWN", header->fault.status); return 0; } -BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* length) +BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* buffer, UINT32* offset, UINT32* length) { UINT32 alloc_hint = 0; - RPC_PDU_HEADER* pCommonFields; + rpcconn_hdr_t* header; *offset = RPC_COMMON_FIELDS_LENGTH; - pCommonFields = ((RPC_PDU_HEADER*) header); + header = ((rpcconn_hdr_t*) buffer); - if (pCommonFields->ptype == PTYPE_RESPONSE) + if (header->common.ptype == PTYPE_RESPONSE) { *offset += 4; rpc_offset_align(offset, 8); - alloc_hint = *((UINT32*) &header[16]); + alloc_hint = header->response.alloc_hint; } - else if (pCommonFields->ptype == PTYPE_REQUEST) + else if (header->common.ptype == PTYPE_REQUEST) { *offset += 4; rpc_offset_align(offset, 8); - alloc_hint = *((UINT32*) &header[16]); + alloc_hint = header->request.alloc_hint; } else { @@ -778,15 +773,10 @@ BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* l if (length) { - UINT16 frag_length; - UINT16 auth_length; BYTE auth_pad_length; - frag_length = pCommonFields->frag_length; - auth_length = pCommonFields->auth_length; - auth_pad_length = *(header + frag_length - auth_length - 6); - - *length = frag_length - (auth_length + *offset + 8 + auth_pad_length); + auth_pad_length = *(buffer + header->common.frag_length - header->common.auth_length - 6); + *length = header->common.frag_length - (header->common.auth_length + *offset + 8 + auth_pad_length); } return TRUE; @@ -815,7 +805,7 @@ int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header) bytesRead += status; } - rpc_pdu_header_print((RPC_PDU_HEADER*) header); + rpc_pdu_header_print((rpcconn_hdr_t*) header); rpc_get_stub_data_info(rpc, header, &offset, NULL); @@ -837,7 +827,7 @@ int rpc_recv_pdu(rdpRpc* rpc) int status; int headerLength; int bytesRead = 0; - RPC_PDU_HEADER* header; + rpcconn_hdr_t* header; status = rpc_recv_pdu_header(rpc, rpc->buffer); @@ -848,19 +838,19 @@ int rpc_recv_pdu(rdpRpc* rpc) } headerLength = status; - header = (RPC_PDU_HEADER*) rpc->buffer; + header = (rpcconn_hdr_t*) rpc->buffer; bytesRead += status; - if (header->frag_length > rpc->length) + if (header->common.frag_length > rpc->length) { - rpc->length = header->frag_length; + rpc->length = header->common.frag_length; rpc->buffer = (BYTE*) realloc(rpc->buffer, rpc->length); - header = (RPC_PDU_HEADER*) rpc->buffer; + header = (rpcconn_hdr_t*) rpc->buffer; } - while (bytesRead < header->frag_length) + while (bytesRead < header->common.frag_length) { - status = tls_read(rpc->TlsOut, &rpc->buffer[bytesRead], header->frag_length - bytesRead); + status = tls_read(rpc->TlsOut, &rpc->buffer[bytesRead], header->common.frag_length - bytesRead); if (status < 0) { @@ -871,17 +861,17 @@ int rpc_recv_pdu(rdpRpc* rpc) bytesRead += status; } - if (!(header->pfc_flags & PFC_LAST_FRAG)) + if (!(header->common.pfc_flags & PFC_LAST_FRAG)) { printf("Fragmented PDU\n"); } - if (header->ptype == PTYPE_RTS) /* RTS PDU */ + if (header->common.ptype == PTYPE_RTS) /* RTS PDU */ { printf("rpc_recv_pdu error: Unexpected RTS PDU\n"); return -1; } - else if (header->ptype == PTYPE_FAULT) + else if (header->common.ptype == PTYPE_FAULT) { rpc_recv_fault_pdu(header); return -1; @@ -889,17 +879,17 @@ int rpc_recv_pdu(rdpRpc* rpc) else { /* RTS PDUs are not subject to flow control */ - rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->frag_length; - rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->frag_length; + rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->common.frag_length; + rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->common.frag_length; } #ifdef WITH_DEBUG_RPC - printf("rpc_recv_pdu: length: %d\n", header->frag_length); - freerdp_hexdump(rpc->buffer, header->frag_length); + printf("rpc_recv_pdu: length: %d\n", header->common.frag_length); + freerdp_hexdump(rpc->buffer, header->common.frag_length); printf("\n"); #endif - return header->frag_length; + return header->common.frag_length; } int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) @@ -925,7 +915,7 @@ int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) request_pdu = (rpcconn_request_hdr_t*) malloc(sizeof(rpcconn_request_hdr_t)); ZeroMemory(request_pdu, sizeof(rpcconn_request_hdr_t)); - rpc_pdu_header_init(rpc, (RPC_PDU_HEADER*) request_pdu); + rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) request_pdu); request_pdu->ptype = PTYPE_REQUEST; request_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG; @@ -1013,22 +1003,6 @@ int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) return length; } -int rpc_read(rdpRpc* rpc, BYTE* data, int length) -{ - int status; - RPC_PDU_HEADER header; - - status = rpc_out_read(rpc, data, length); - - if (status > 0) - { - CopyMemory(&header, data, 20); - status = rpc_out_read(rpc, data, header.frag_length - 20); - } - - return status; -} - BOOL rpc_connect(rdpRpc* rpc) { rpc->TlsIn = rpc->transport->TlsIn; @@ -1183,6 +1157,9 @@ rdpRpc* rpc_new(rdpTransport* transport) rpc->packed_drep[2] = 0x00; rpc->packed_drep[3] = 0x00; + rpc->max_xmit_frag = 0x0FF8; + rpc->max_recv_frag = 0x0FF8; + rpc->ReceiveWindow = 0x00010000; rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc); diff --git a/libfreerdp/core/rpc.h b/libfreerdp/core/rpc.h index 167640f72..89d54e897 100644 --- a/libfreerdp/core/rpc.h +++ b/libfreerdp/core/rpc.h @@ -24,6 +24,18 @@ typedef struct rdp_rpc rdpRpc; +#define DEFINE_RPC_COMMON_FIELDS() \ + BYTE rpc_vers; \ + BYTE rpc_vers_minor; \ + BYTE ptype; \ + BYTE pfc_flags; \ + BYTE packed_drep[4]; \ + UINT16 frag_length; \ + UINT16 auth_length; \ + UINT32 call_id + +#define RPC_COMMON_FIELDS_LENGTH 20 + #include "tcp.h" #include "rts.h" #include "http.h" @@ -50,17 +62,40 @@ typedef struct rdp_rpc rdpRpc; * http://pubs.opengroup.org/onlinepubs/9629399/ */ -#define DEFINE_RPC_COMMON_FIELDS() \ - BYTE rpc_vers; \ - BYTE rpc_vers_minor; \ - BYTE ptype; \ - BYTE pfc_flags; \ - BYTE packed_drep[4]; \ - UINT16 frag_length; \ - UINT16 auth_length; \ - UINT32 call_id +#define PTYPE_REQUEST 0x00 +#define PTYPE_PING 0x01 +#define PTYPE_RESPONSE 0x02 +#define PTYPE_FAULT 0x03 +#define PTYPE_WORKING 0x04 +#define PTYPE_NOCALL 0x05 +#define PTYPE_REJECT 0x06 +#define PTYPE_ACK 0x07 +#define PTYPE_CL_CANCEL 0x08 +#define PTYPE_FACK 0x09 +#define PTYPE_CANCEL_ACK 0x0A +#define PTYPE_BIND 0x0B +#define PTYPE_BIND_ACK 0x0C +#define PTYPE_BIND_NAK 0x0D +#define PTYPE_ALTER_CONTEXT 0x0E +#define PTYPE_ALTER_CONTEXT_RESP 0x0F +#define PTYPE_RPC_AUTH_3 0x10 +#define PTYPE_SHUTDOWN 0x11 +#define PTYPE_CO_CANCEL 0x12 +#define PTYPE_ORPHANED 0x13 +#define PTYPE_RTS 0x14 -#define RPC_COMMON_FIELDS_LENGTH 20 +#define PFC_FIRST_FRAG 0x01 +#define PFC_LAST_FRAG 0x02 +#define PFC_PENDING_CANCEL 0x04 +#define PFC_RESERVED_1 0x08 +#define PFC_CONC_MPX 0x10 +#define PFC_DID_NOT_EXECUTE 0x20 +#define PFC_MAYBE 0x40 +#define PFC_OBJECT_UUID 0x80 + +/* Minimum fragment sizes */ +#define RPC_CO_MUST_RECV_FRAG_SIZE 1432 +#define RPC_CL_MUST_RECV_FRAG_SIZE 1464 /** * The PDU maximum header length is enough @@ -70,11 +105,10 @@ typedef struct rdp_rpc rdpRpc; */ #define RPC_PDU_HEADER_MAX_LENGTH 32 -struct _rpc_pdu_header +typedef struct { DEFINE_RPC_COMMON_FIELDS(); -}; -typedef struct _rpc_pdu_header RPC_PDU_HEADER; +} rpcconn_common_hdr_t; typedef UINT16 p_context_id_t; typedef UINT16 p_reject_reason_t; @@ -464,6 +498,23 @@ typedef struct DEFINE_RPC_COMMON_FIELDS(); } rpcconn_shutdown_hdr_t; +typedef union +{ + rpcconn_common_hdr_t common; + rpcconn_alter_context_hdr_t alter_context; + rpcconn_alter_context_response_hdr_t alter_context_response; + rpcconn_bind_hdr_t bind; + rpcconn_bind_ack_hdr_t bind_ack; + rpcconn_rpc_auth_3_hdr_t rpc_auth_3; + rpcconn_bind_nak_hdr_t bind_nak; + rpcconn_cancel_hdr_t cancel; + rpcconn_fault_hdr_t fault; + rpcconn_orphaned_hdr_t orphaned; + rpcconn_request_hdr_t request; + rpcconn_response_hdr_t response; + rpcconn_shutdown_hdr_t shutdown; +} rpcconn_hdr_t; + enum _TSG_CHANNEL { TSG_CHANNEL_IN, @@ -566,6 +617,9 @@ struct rdp_rpc BYTE rpc_vers_minor; BYTE packed_drep[4]; + UINT16 max_xmit_frag; + UINT16 max_recv_frag; + UINT32 ReceiveWindow; RpcVirtualConnection* VirtualConnection; @@ -576,7 +630,7 @@ BOOL rpc_connect(rdpRpc* rpc); BOOL rpc_ntlm_http_out_connect(rdpRpc* rpc); BOOL rpc_ntlm_http_in_connect(rdpRpc* rpc); -void rpc_pdu_header_init(rdpRpc* rpc, RPC_PDU_HEADER* header); +void rpc_pdu_header_init(rdpRpc* rpc, rpcconn_hdr_t* header); UINT32 rpc_offset_align(UINT32* offset, UINT32 alignment); UINT32 rpc_offset_pad(UINT32* offset, UINT32 pad); @@ -591,7 +645,6 @@ int rpc_recv_pdu(rdpRpc* rpc); int rpc_out_read(rdpRpc* rpc, BYTE* data, int length); int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum); -int rpc_read(rdpRpc* rpc, BYTE* data, int length); rdpRpc* rpc_new(rdpTransport* transport); void rpc_free(rdpRpc* rpc); diff --git a/libfreerdp/core/rts.c b/libfreerdp/core/rts.c index 0023f3e66..17aa85ab5 100644 --- a/libfreerdp/core/rts.c +++ b/libfreerdp/core/rts.c @@ -21,6 +21,8 @@ #include "config.h" #endif +#include + #include "rts.h" /** @@ -127,6 +129,37 @@ static const char* const RTS_CMD_STRINGS[] = #endif +/** + * RTS PDU Header + * + * The RTS PDU Header has the same layout as the common header of the connection-oriented RPC + * PDU as specified in [C706] section 12.6.1, with a few additional requirements around the contents + * of the header fields. The additional requirements are as follows: + * + * All fields MUST use little-endian byte order. + * + * Fragmentation MUST NOT occur for an RTS PDU. + * + * PFC_FIRST_FRAG and PFC_LAST_FRAG MUST be present in all RTS PDUs, and all other PFC flags + * MUST NOT be present. + * + * The rpc_vers and rpc_vers_minor fields MUST contain version information as described in + * [MS-RPCE] section 1.7. + * + * PTYPE MUST be set to a value of 20 (0x14). This field differentiates RTS packets from other RPC packets. + * + * The packed_drep MUST indicate little-endian integer and floating-pointer byte order, IEEE float-point + * format representation, and ASCII character format as specified in [C706] section 12.6. + * + * The auth_length MUST be set to 0. + * + * The frag_length field MUST reflect the size of the header plus the size of all commands, including + * the variable portion of variable-sized commands. + * + * The call_id MUST be set to 0 by senders and MUST be 0 on receipt. + * + */ + void rts_pdu_header_init(rdpRpc* rpc, RTS_PDU_HEADER* header) { header->rpc_vers = rpc->rpc_vers; @@ -142,10 +175,11 @@ void rts_receive_window_size_command_read(rdpRpc* rpc, STREAM* s) stream_seek_UINT32(s); /* ReceiveWindowSize (4 bytes) */ } -void rts_receive_window_size_command_write(STREAM* s, UINT32 ReceiveWindowSize) +int rts_receive_window_size_command_write(BYTE* buffer, UINT32 ReceiveWindowSize) { - stream_write_UINT32(s, RTS_CMD_RECEIVE_WINDOW_SIZE); /* CommandType (4 bytes) */ - stream_write_UINT32(s, ReceiveWindowSize); /* ReceiveWindowSize (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_RECEIVE_WINDOW_SIZE; /* CommandType (4 bytes) */ + *((UINT32*) &buffer[4]) = ReceiveWindowSize; /* ReceiveWindowSize (4 bytes) */ + return 8; } void rts_flow_control_ack_command_read(rdpRpc* rpc, STREAM* s) @@ -156,14 +190,16 @@ void rts_flow_control_ack_command_read(rdpRpc* rpc, STREAM* s) stream_seek(s, 16); /* ChannelCookie (16 bytes) */ } -void rts_flow_control_ack_command_write(STREAM* s, UINT32 BytesReceived, UINT32 AvailableWindow, BYTE* ChannelCookie) +int rts_flow_control_ack_command_write(BYTE* buffer, UINT32 BytesReceived, UINT32 AvailableWindow, BYTE* ChannelCookie) { - stream_write_UINT32(s, RTS_CMD_FLOW_CONTROL_ACK); /* CommandType (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_FLOW_CONTROL_ACK; /* CommandType (4 bytes) */ /* Ack (24 bytes) */ - stream_write_UINT32(s, BytesReceived); /* BytesReceived (4 bytes) */ - stream_write_UINT32(s, AvailableWindow); /* AvailableWindow (4 bytes) */ - stream_write(s, ChannelCookie, 16); /* ChannelCookie (16 bytes) */ + *((UINT32*) &buffer[4]) = BytesReceived; /* BytesReceived (4 bytes) */ + *((UINT32*) &buffer[8]) = AvailableWindow; /* AvailableWindow (4 bytes) */ + CopyMemory(&buffer[12], ChannelCookie, 16); /* ChannelCookie (16 bytes) */ + + return 28; } void rts_connection_timeout_command_read(rdpRpc* rpc, STREAM* s) @@ -171,10 +207,11 @@ void rts_connection_timeout_command_read(rdpRpc* rpc, STREAM* s) stream_seek_UINT32(s); /* ConnectionTimeout (4 bytes) */ } -void rts_connection_timeout_command_write(STREAM* s, UINT32 ConnectionTimeout) +int rts_connection_timeout_command_write(BYTE* buffer, UINT32 ConnectionTimeout) { - stream_write_UINT32(s, RTS_CMD_CONNECTION_TIMEOUT); /* CommandType (4 bytes) */ - stream_write_UINT32(s, ConnectionTimeout); /* ConnectionTimeout (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_CONNECTION_TIMEOUT; /* CommandType (4 bytes) */ + *((UINT32*) &buffer[4]) = ConnectionTimeout; /* ConnectionTimeout (4 bytes) */ + return 8; } void rts_cookie_command_read(rdpRpc* rpc, STREAM* s) @@ -182,10 +219,11 @@ void rts_cookie_command_read(rdpRpc* rpc, STREAM* s) stream_seek(s, 16); /* Cookie (16 bytes) */ } -void rts_cookie_command_write(STREAM* s, BYTE* Cookie) +int rts_cookie_command_write(BYTE* buffer, BYTE* Cookie) { - stream_write_UINT32(s, RTS_CMD_COOKIE); /* CommandType (4 bytes) */ - stream_write(s, Cookie, 16); /* Cookie (16 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_COOKIE; /* CommandType (4 bytes) */ + CopyMemory(&buffer[4], Cookie, 16); /* Cookie (16 bytes) */ + return 20; } void rts_channel_lifetime_command_read(rdpRpc* rpc, STREAM* s) @@ -193,10 +231,11 @@ void rts_channel_lifetime_command_read(rdpRpc* rpc, STREAM* s) stream_seek_UINT32(s); /* ChannelLifetime (4 bytes) */ } -void rts_channel_lifetime_command_write(STREAM* s, UINT32 ChannelLifetime) +int rts_channel_lifetime_command_write(BYTE* buffer, UINT32 ChannelLifetime) { - stream_write_UINT32(s, RTS_CMD_CHANNEL_LIFETIME); /* CommandType (4 bytes) */ - stream_write_UINT32(s, ChannelLifetime); /* ChannelLifetime (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_CHANNEL_LIFETIME; /* CommandType (4 bytes) */ + *((UINT32*) &buffer[4]) = ChannelLifetime; /* ChannelLifetime (4 bytes) */ + return 8; } void rts_client_keepalive_command_read(rdpRpc* rpc, STREAM* s) @@ -204,10 +243,11 @@ void rts_client_keepalive_command_read(rdpRpc* rpc, STREAM* s) stream_seek_UINT32(s); /* ClientKeepalive (4 bytes) */ } -void rts_client_keepalive_command_write(STREAM* s, UINT32 ClientKeepalive) +int rts_client_keepalive_command_write(BYTE* buffer, UINT32 ClientKeepalive) { - stream_write_UINT32(s, RTS_CMD_CLIENT_KEEPALIVE); /* CommandType (4 bytes) */ - stream_write_UINT32(s, ClientKeepalive); /* ClientKeepalive (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_CLIENT_KEEPALIVE; /* CommandType (4 bytes) */ + *((UINT32*) &buffer[4]) = ClientKeepalive; /* ClientKeepalive (4 bytes) */ + return 8; } void rts_version_command_read(rdpRpc* rpc, STREAM* s) @@ -215,10 +255,11 @@ void rts_version_command_read(rdpRpc* rpc, STREAM* s) stream_seek_UINT32(s); /* Version (4 bytes) */ } -void rts_version_command_write(STREAM* s) +int rts_version_command_write(BYTE* buffer) { - stream_write_UINT32(s, RTS_CMD_VERSION); /* CommandType (4 bytes) */ - stream_write_UINT32(s, 1); /* Version (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_VERSION; /* CommandType (4 bytes) */ + *((UINT32*) &buffer[4]) = 1; /* Version (4 bytes) */ + return 8; } void rts_empty_command_read(rdpRpc* rpc, STREAM* s) @@ -226,9 +267,10 @@ void rts_empty_command_read(rdpRpc* rpc, STREAM* s) } -void rts_empty_command_write(STREAM* s) +int rts_empty_command_write(BYTE* buffer) { - stream_write_UINT32(s, RTS_CMD_EMPTY); /* CommandType (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_EMPTY; /* CommandType (4 bytes) */ + return 4; } void rts_padding_command_read(rdpRpc* rpc, STREAM* s) @@ -239,10 +281,12 @@ void rts_padding_command_read(rdpRpc* rpc, STREAM* s) stream_seek(s, ConformanceCount); /* Padding (variable) */ } -void rts_padding_command_write(STREAM* s, UINT32 ConformanceCount) +int rts_padding_command_write(BYTE* buffer, UINT32 ConformanceCount) { - stream_write_UINT32(s, ConformanceCount); /* ConformanceCount (4 bytes) */ - stream_write_zero(s, ConformanceCount); /* Padding (variable) */ + *((UINT32*) &buffer[0]) = RTS_CMD_PADDING; /* CommandType (4 bytes) */ + *((UINT32*) &buffer[4]) = ConformanceCount; /* ConformanceCount (4 bytes) */ + ZeroMemory(&buffer[8], ConformanceCount); /* Padding (variable) */ + return 8 + ConformanceCount; } void rts_negative_ance_command_read(rdpRpc* rpc, STREAM* s) @@ -250,9 +294,10 @@ void rts_negative_ance_command_read(rdpRpc* rpc, STREAM* s) } -void rts_negative_ance_command_write(STREAM* s) +int rts_negative_ance_command_write(BYTE* buffer) { - stream_write_UINT32(s, RTS_CMD_NEGATIVE_ANCE); /* CommandType (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_NEGATIVE_ANCE; /* CommandType (4 bytes) */ + return 4; } void rts_ance_command_read(rdpRpc* rpc, STREAM* s) @@ -260,9 +305,10 @@ void rts_ance_command_read(rdpRpc* rpc, STREAM* s) } -void rts_ance_command_write(STREAM* s) +int rts_ance_command_write(BYTE* buffer) { - stream_write_UINT32(s, RTS_CMD_ANCE); /* CommandType (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_ANCE; /* CommandType (4 bytes) */ + return 4; } void rts_client_address_command_read(rdpRpc* rpc, STREAM* s) @@ -283,21 +329,23 @@ void rts_client_address_command_read(rdpRpc* rpc, STREAM* s) stream_seek(s, 12); /* padding (12 bytes) */ } -void rts_client_address_command_write(STREAM* s, UINT32 AddressType, BYTE* ClientAddress) +int rts_client_address_command_write(BYTE* buffer, UINT32 AddressType, BYTE* ClientAddress) { - stream_write_UINT32(s, RTS_CMD_CLIENT_ADDRESS); /* CommandType (4 bytes) */ - stream_write_UINT32(s, AddressType); /* AddressType (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_CLIENT_ADDRESS; /* CommandType (4 bytes) */ + *((UINT32*) &buffer[4]) = AddressType; /* AddressType (4 bytes) */ if (AddressType == 0) { - stream_write(s, ClientAddress, 4); /* ClientAddress (4 bytes) */ + CopyMemory(&buffer[8], ClientAddress, 4); /* ClientAddress (4 bytes) */ + ZeroMemory(&buffer[12], 12); /* padding (12 bytes) */ + return 24; } else { - stream_write(s, ClientAddress, 16); /* ClientAddress (16 bytes) */ + CopyMemory(&buffer[8], ClientAddress, 16); /* ClientAddress (16 bytes) */ + ZeroMemory(&buffer[24], 12); /* padding (12 bytes) */ + return 36; } - - stream_write_zero(s, 12); /* padding (12 bytes) */ } void rts_association_group_id_command_read(rdpRpc* rpc, STREAM* s) @@ -305,10 +353,11 @@ void rts_association_group_id_command_read(rdpRpc* rpc, STREAM* s) stream_seek(s, 16); /* AssociationGroupId (16 bytes) */ } -void rts_association_group_id_command_write(STREAM* s, BYTE* associationGroupId) +int rts_association_group_id_command_write(BYTE* buffer, BYTE* AssociationGroupId) { - stream_write_UINT32(s, RTS_CMD_ASSOCIATION_GROUP_ID); /* CommandType (4 bytes) */ - stream_write(s, associationGroupId, 16); /* AssociationGroupId (16 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_ASSOCIATION_GROUP_ID; /* CommandType (4 bytes) */ + CopyMemory(&buffer[4], AssociationGroupId, 16); /* AssociationGroupId (16 bytes) */ + return 20; } void rts_destination_command_read(rdpRpc* rpc, STREAM* s) @@ -316,10 +365,11 @@ void rts_destination_command_read(rdpRpc* rpc, STREAM* s) stream_seek_UINT32(s); /* Destination (4 bytes) */ } -void rts_destination_command_write(STREAM* s, UINT32 Destination) +int rts_destination_command_write(BYTE* buffer, UINT32 Destination) { - stream_write_UINT32(s, RTS_CMD_DESTINATION); /* CommandType (4 bytes) */ - stream_write_UINT32(s, Destination); /* Destination (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_DESTINATION; /* CommandType (4 bytes) */ + *((UINT32*) &buffer[4]) = Destination; /* Destination (4 bytes) */ + return 8; } void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s) @@ -327,10 +377,11 @@ void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s) stream_seek_UINT32(s); /* PingTrafficSent (4 bytes) */ } -void rts_ping_traffic_sent_notify_command_write(STREAM* s, UINT32 PingTrafficSent) +int rts_ping_traffic_sent_notify_command_write(BYTE* buffer, UINT32 PingTrafficSent) { - stream_write_UINT32(s, RTS_CMD_PING_TRAFFIC_SENT_NOTIFY); /* CommandType (4 bytes) */ - stream_write_UINT32(s, PingTrafficSent); /* PingTrafficSent (4 bytes) */ + *((UINT32*) &buffer[0]) = RTS_CMD_PING_TRAFFIC_SENT_NOTIFY; /* CommandType (4 bytes) */ + *((UINT32*) &buffer[4]) = PingTrafficSent; /* PingTrafficSent (4 bytes) */ + return 8; } void rts_generate_cookie(BYTE* cookie) @@ -368,10 +419,10 @@ BOOL rts_send_CONN_A1_pdu(rdpRpc* rpc) ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow; stream_write(s, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */ - rts_version_command_write(s); /* Version (8 bytes) */ - rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ - rts_cookie_command_write(s, OUTChannelCookie); /* OUTChannelCookie (20 bytes) */ - rts_receive_window_size_command_write(s, ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */ + s->p += rts_version_command_write(s->p); /* Version (8 bytes) */ + s->p += rts_cookie_command_write(s->p, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ + s->p += rts_cookie_command_write(s->p, OUTChannelCookie); /* OUTChannelCookie (20 bytes) */ + s->p += rts_receive_window_size_command_write(s->p, ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */ stream_seal(s); rpc_out_write(rpc, s->data, s->size); @@ -411,12 +462,12 @@ BOOL rts_send_CONN_B1_pdu(rdpRpc* rpc) AssociationGroupId = (BYTE*) &(rpc->VirtualConnection->AssociationGroupId); stream_write(s, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */ - rts_version_command_write(s); /* Version (8 bytes) */ - rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ - rts_cookie_command_write(s, INChannelCookie); /* INChannelCookie (20 bytes) */ - rts_channel_lifetime_command_write(s, 0x40000000); /* ChannelLifetime (8 bytes) */ - rts_client_keepalive_command_write(s, 0x000493E0); /* ClientKeepalive (8 bytes) */ - rts_association_group_id_command_write(s, AssociationGroupId); /* AssociationGroupId (20 bytes) */ + s->p += rts_version_command_write(s->p); /* Version (8 bytes) */ + s->p += rts_cookie_command_write(s->p, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ + s->p += rts_cookie_command_write(s->p, INChannelCookie); /* INChannelCookie (20 bytes) */ + s->p += rts_channel_lifetime_command_write(s->p, 0x40000000); /* ChannelLifetime (8 bytes) */ + s->p += rts_client_keepalive_command_write(s->p, 0x000493E0); /* ClientKeepalive (8 bytes) */ + s->p += rts_association_group_id_command_write(s->p, AssociationGroupId); /* AssociationGroupId (20 bytes) */ stream_seal(s); rpc_in_write(rpc, s->data, s->size); @@ -429,6 +480,7 @@ BOOL rts_send_CONN_B1_pdu(rdpRpc* rpc) BOOL rts_send_keep_alive_pdu(rdpRpc* rpc) { STREAM* s; + BYTE* buffer; RTS_PDU_HEADER header; rts_pdu_header_init(rpc, &header); @@ -443,14 +495,13 @@ BOOL rts_send_keep_alive_pdu(rdpRpc* rpc) DEBUG_RPC("Sending Keep-Alive RTS PDU"); - s = stream_new(header.frag_length); - stream_write(s, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */ - rts_client_keepalive_command_write(s, 0x00007530); /* ClientKeepalive (8 bytes) */ - stream_seal(s); + buffer = (BYTE*) malloc(header.frag_length); + CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */ + rts_client_keepalive_command_write(&buffer[20], 0x00007530); /* ClientKeepalive (8 bytes) */ - rpc_in_write(rpc, s->data, s->size); + rpc_in_write(rpc, buffer, header.frag_length); - stream_free(s); + free(buffer); return TRUE; } @@ -481,10 +532,10 @@ BOOL rts_send_flow_control_ack_pdu(rdpRpc* rpc) s = stream_new(header.frag_length); stream_write(s, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */ - rts_destination_command_write(s, FDOutProxy); /* Destination Command (8 bytes) */ + s->p += rts_destination_command_write(s->p, FDOutProxy); /* Destination Command (8 bytes) */ /* FlowControlAck Command (28 bytes) */ - rts_flow_control_ack_command_write(s, BytesReceived, AvailableWindow, ChannelCookie); + s->p += rts_flow_control_ack_command_write(s->p, BytesReceived, AvailableWindow, ChannelCookie); stream_seal(s); diff --git a/libfreerdp/core/rts.h b/libfreerdp/core/rts.h index d07f6f917..3d5a1f941 100644 --- a/libfreerdp/core/rts.h +++ b/libfreerdp/core/rts.h @@ -20,48 +20,20 @@ #ifndef FREERDP_CORE_RTS_H #define FREERDP_CORE_RTS_H -#include "rpc.h" - #ifdef HAVE_CONFIG_H #include "config.h" #endif +typedef struct _rts_pdu RTS_PDU; +typedef struct _rts_pdu_header RTS_PDU_HEADER; + +#include "rpc.h" + #include #include #include #include -#define PTYPE_REQUEST 0x00 -#define PTYPE_PING 0x01 -#define PTYPE_RESPONSE 0x02 -#define PTYPE_FAULT 0x03 -#define PTYPE_WORKING 0x04 -#define PTYPE_NOCALL 0x05 -#define PTYPE_REJECT 0x06 -#define PTYPE_ACK 0x07 -#define PTYPE_CL_CANCEL 0x08 -#define PTYPE_FACK 0x09 -#define PTYPE_CANCEL_ACK 0x0A -#define PTYPE_BIND 0x0B -#define PTYPE_BIND_ACK 0x0C -#define PTYPE_BIND_NAK 0x0D -#define PTYPE_ALTER_CONTEXT 0x0E -#define PTYPE_ALTER_CONTEXT_RESP 0x0F -#define PTYPE_RPC_AUTH_3 0x10 -#define PTYPE_SHUTDOWN 0x11 -#define PTYPE_CO_CANCEL 0x12 -#define PTYPE_ORPHANED 0x13 -#define PTYPE_RTS 0x14 - -#define PFC_FIRST_FRAG 0x01 -#define PFC_LAST_FRAG 0x02 -#define PFC_PENDING_CANCEL 0x04 -#define PFC_RESERVED_1 0x08 -#define PFC_CONC_MPX 0x10 -#define PFC_DID_NOT_EXECUTE 0x20 -#define PFC_MAYBE 0x40 -#define PFC_OBJECT_UUID 0x80 - #define RTS_FLAG_NONE 0x0000 #define RTS_FLAG_PING 0x0001 #define RTS_FLAG_OTHER_CMD 0x0002 @@ -94,58 +66,64 @@ struct _rts_pdu_header { - BYTE rpc_vers; - BYTE rpc_vers_minor; - BYTE ptype; - BYTE pfc_flags; - BYTE packed_drep[4]; - UINT16 frag_length; - UINT16 auth_length; - UINT32 call_id; + DEFINE_RPC_COMMON_FIELDS(); + UINT16 flags; UINT16 numberOfCommands; }; -typedef struct _rts_pdu_header RTS_PDU_HEADER; struct _rts_pdu { RTS_PDU_HEADER header; BYTE* content; }; -typedef struct _rts_pdu RTS_PDU; BOOL rts_connect(rdpRpc* rpc); void rts_receive_window_size_command_read(rdpRpc* rpc, STREAM* s); -void rts_receive_window_size_command_write(STREAM* s, UINT32 ReceiveWindowSize); +int rts_receive_window_size_command_write(BYTE* buffer, UINT32 ReceiveWindowSize); + void rts_flow_control_ack_command_read(rdpRpc* rpc, STREAM* s); -void rts_flow_control_ack_command_write(STREAM* s, UINT32 BytesReceived, UINT32 AvailableWindow, BYTE* ChannelCookie); +int rts_flow_control_ack_command_write(BYTE* buffer, UINT32 BytesReceived, UINT32 AvailableWindow, BYTE* ChannelCookie); + void rts_connection_timeout_command_read(rdpRpc* rpc, STREAM* s); -void rts_connection_timeout_command_write(STREAM* s, UINT32 ConnectionTimeout); +int rts_connection_timeout_command_write(BYTE* buffer, UINT32 ConnectionTimeout); + void rts_cookie_command_read(rdpRpc* rpc, STREAM* s); -void rts_cookie_command_write(STREAM* s, BYTE* Cookie); +int rts_cookie_command_write(BYTE* buffer, BYTE* Cookie); + void rts_channel_lifetime_command_read(rdpRpc* rpc, STREAM* s); -void rts_channel_lifetime_command_write(STREAM* s, UINT32 ChannelLifetime); +int rts_channel_lifetime_command_write(BYTE* buffer, UINT32 ChannelLifetime); + void rts_client_keepalive_command_read(rdpRpc* rpc, STREAM* s); -void rts_client_keepalive_command_write(STREAM* s, UINT32 ClientKeepalive); +int rts_client_keepalive_command_write(BYTE* buffer, UINT32 ClientKeepalive); + void rts_version_command_read(rdpRpc* rpc, STREAM* s); -void rts_version_command_write(STREAM* s); +int rts_version_command_write(BYTE* buffer); + void rts_empty_command_read(rdpRpc* rpc, STREAM* s); -void rts_empty_command_write(STREAM* s); +int rts_empty_command_write(BYTE* buffer); + void rts_padding_command_read(rdpRpc* rpc, STREAM* s); -void rts_padding_command_write(STREAM* s, UINT32 ConformanceCount); +int rts_padding_command_write(BYTE* buffer, UINT32 ConformanceCount); + void rts_negative_ance_command_read(rdpRpc* rpc, STREAM* s); -void rts_negative_ance_command_write(STREAM* s); +int rts_negative_ance_command_write(BYTE* buffer); + void rts_ance_command_read(rdpRpc* rpc, STREAM* s); -void rts_ance_command_write(STREAM* s); +int rts_ance_command_write(BYTE* buffer); + void rts_client_address_command_read(rdpRpc* rpc, STREAM* s); -void rts_client_address_command_write(STREAM* s, UINT32 AddressType, BYTE* ClientAddress); +int rts_client_address_command_write(BYTE* buffer, UINT32 AddressType, BYTE* ClientAddress); + void rts_association_group_id_command_read(rdpRpc* rpc, STREAM* s); -void rts_association_group_id_command_write(STREAM* s, BYTE* AssociationGroupId); +int rts_association_group_id_command_write(BYTE* buffer, BYTE* AssociationGroupId); + void rts_destination_command_read(rdpRpc* rpc, STREAM* s); -void rts_destination_command_write(STREAM* s, UINT32 Destination); +int rts_destination_command_write(BYTE* buffer, UINT32 Destination); + void rts_ping_traffic_sent_notify_command_read(rdpRpc* rpc, STREAM* s); -void rts_ping_traffic_sent_notify_command_write(STREAM* s, UINT32 PingTrafficSent); +int rts_ping_traffic_sent_notify_command_write(BYTE* buffer, UINT32 PingTrafficSent); BOOL rts_send_CONN_A1_pdu(rdpRpc* rpc); BOOL rts_send_CONN_B1_pdu(rdpRpc* rpc); diff --git a/libfreerdp/core/tsg.c b/libfreerdp/core/tsg.c index f877cc49c..c6ded7729 100644 --- a/libfreerdp/core/tsg.c +++ b/libfreerdp/core/tsg.c @@ -1115,14 +1115,14 @@ int tsg_read(rdpTsg* tsg, BYTE* data, UINT32 length) { int status; int CopyLength; - RPC_PDU_HEADER* header; + rpcconn_common_hdr_t* header; rdpRpc* rpc = tsg->rpc; printf("tsg_read: %d, pending: %d\n", length, tsg->PendingPdu); if (tsg->PendingPdu) { - header = (RPC_PDU_HEADER*) rpc->buffer; + header = (rpcconn_common_hdr_t*) rpc->buffer; CopyLength = (tsg->BytesAvailable > length) ? length : tsg->BytesAvailable;