diff --git a/libfreerdp/core/gateway/http.c b/libfreerdp/core/gateway/http.c index 98ace5027..c1957da40 100644 --- a/libfreerdp/core/gateway/http.c +++ b/libfreerdp/core/gateway/http.c @@ -267,6 +267,10 @@ void http_request_free(HttpRequest* http_request) { if (http_request != NULL) { + free(http_request->AuthParam); + free(http_request->AuthScheme); + free(http_request->Authorization); + free(http_request->Content); free(http_request->Method); free(http_request->URI); free(http_request); @@ -397,10 +401,12 @@ HttpResponse* http_response_recv(rdpTls* tls) nbytes = 0; length = 10000; + content = NULL; buffer = malloc(length); http_response = http_response_new(); p = buffer; + http_response->ContentLength = 0; while (TRUE) { diff --git a/libfreerdp/core/gateway/rpc.c b/libfreerdp/core/gateway/rpc.c index 75c149419..0adbfcb4f 100644 --- a/libfreerdp/core/gateway/rpc.c +++ b/libfreerdp/core/gateway/rpc.c @@ -345,15 +345,6 @@ int rpc_in_write(rdpRpc* rpc, BYTE* data, int length) return status; } -RPC_PDU* rpc_recv_pdu(rdpRpc* rpc) -{ - RPC_PDU* pdu; - - pdu = rpc_recv_dequeue_pdu(rpc); - - return pdu; -} - int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) { BYTE* buffer; @@ -382,13 +373,13 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) request_pdu->ptype = PTYPE_REQUEST; request_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG; request_pdu->auth_length = ntlm->ContextSizes.cbMaxSignature; - request_pdu->call_id = rpc->call_id++; + request_pdu->call_id = rpc->CallId++; request_pdu->alloc_hint = length; request_pdu->p_cont_id = 0x0000; request_pdu->opnum = opnum; client_call = rpc_client_call_new(request_pdu->call_id, request_pdu->opnum); - ArrayList_Add(rpc->ClientCalls, client_call); + ArrayList_Add(rpc->client->ClientCallList, client_call); if (request_pdu->opnum == TsProxySetupReceivePipeOpnum) rpc->PipeCallId = request_pdu->call_id; @@ -439,7 +430,7 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) Message.ulVersion = SECBUFFER_VERSION; Message.pBuffers = (PSecBuffer) &Buffers; - encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, rpc->send_seq_num++); + encrypt_status = ntlm->table->EncryptMessage(&ntlm->context, 0, &Message, rpc->SendSeqNum++); if (encrypt_status != SEC_E_OK) { @@ -452,12 +443,9 @@ int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) rpc_send_enqueue_pdu(rpc, buffer, request_pdu->frag_length); - return length; -} + free(request_pdu); -int rpc_recv(rdpRpc* rpc, RPC_PDU* pdu) -{ - return 0; + return length; } BOOL rpc_connect(rdpRpc* rpc) @@ -526,39 +514,6 @@ void rpc_client_virtual_connection_free(RpcVirtualConnection* virtual_connection } } -/* Virtual Connection Cookie Table */ - -RpcVirtualConnectionCookieTable* rpc_virtual_connection_cookie_table_new(rdpRpc* rpc) -{ - RpcVirtualConnectionCookieTable* table; - - table = (RpcVirtualConnectionCookieTable*) malloc(sizeof(RpcVirtualConnectionCookieTable)); - - if (table != NULL) - { - ZeroMemory(table, sizeof(RpcVirtualConnectionCookieTable)); - - table->Count = 0; - table->ArraySize = 32; - - table->Entries = (RpcVirtualConnectionCookieEntry*) malloc(sizeof(RpcVirtualConnectionCookieEntry) * table->ArraySize); - ZeroMemory(table->Entries, sizeof(RpcVirtualConnectionCookieEntry) * table->ArraySize); - } - - return table; -} - -void rpc_virtual_connection_cookie_table_free(RpcVirtualConnectionCookieTable* table) -{ - if (table != NULL) - { - free(table->Entries); - free(table); - } -} - -/* RPC Core Module */ - rdpRpc* rpc_new(rdpTransport* transport) { rdpRpc* rpc = (rdpRpc*) malloc(sizeof(rdpRpc)); @@ -572,7 +527,7 @@ rdpRpc* rpc_new(rdpTransport* transport) rpc->transport = transport; rpc->settings = transport->settings; - rpc->send_seq_num = 0; + rpc->SendSeqNum = 0; rpc->ntlm = ntlm_new(); rpc->NtlmHttpIn = ntlm_http_new(); @@ -581,16 +536,13 @@ rdpRpc* rpc_new(rdpTransport* transport) rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpIn, TSG_CHANNEL_IN); rpc_ntlm_http_init_channel(rpc, rpc->NtlmHttpOut, TSG_CHANNEL_OUT); - rpc->FragBufferSize = 20; - rpc->FragBuffer = (BYTE*) malloc(rpc->FragBufferSize); - rpc->PipeCallId = 0; rpc->StubOffset = 0; rpc->StubBufferSize = 20; rpc->StubLength = 0; rpc->StubFragCount = 0; - rpc->StubBuffer = (BYTE*) malloc(rpc->FragBufferSize); + rpc->StubBuffer = (BYTE*) malloc(0x0FF8); rpc->StubCallId = 0; rpc->rpc_vers = 5; @@ -607,13 +559,8 @@ rdpRpc* rpc_new(rdpTransport* transport) rpc->pdu = (RPC_PDU*) malloc(sizeof(RPC_PDU)); - rpc->SendQueue = Queue_New(TRUE, -1, -1); - rpc->ReceiveQueue = Queue_New(TRUE, -1, -1); - rpc->RecvFrag = Stream_New(NULL, rpc->max_recv_frag); - rpc->ClientCalls = ArrayList_New(TRUE); - rpc->ReceiveWindow = 0x00010000; rpc->ChannelLifetime = 0x40000000; @@ -624,9 +571,9 @@ rdpRpc* rpc_new(rdpTransport* transport) rpc->CurrentKeepAliveTime = 0; rpc->VirtualConnection = rpc_client_virtual_connection_new(rpc); - rpc->VirtualConnectionCookieTable = rpc_virtual_connection_cookie_table_new(rpc); + rpc->VirtualConnectionCookieTable = ArrayList_New(TRUE); - rpc->call_id = 2; + rpc->CallId = 2; rpc_client_new(rpc); @@ -646,17 +593,10 @@ void rpc_free(rdpRpc* rpc) free(rpc->pdu); - Queue_Clear(rpc->SendQueue); - Queue_Free(rpc->SendQueue); - - Queue_Clear(rpc->ReceiveQueue); - Queue_Free(rpc->ReceiveQueue); - - ArrayList_Clear(rpc->ClientCalls); - ArrayList_Free(rpc->ClientCalls); - rpc_client_virtual_connection_free(rpc->VirtualConnection); - rpc_virtual_connection_cookie_table_free(rpc->VirtualConnectionCookieTable); + + ArrayList_Clear(rpc->VirtualConnectionCookieTable); + ArrayList_Free(rpc->VirtualConnectionCookieTable); free(rpc); } diff --git a/libfreerdp/core/gateway/rpc.h b/libfreerdp/core/gateway/rpc.h index 927381528..ccd84a184 100644 --- a/libfreerdp/core/gateway/rpc.h +++ b/libfreerdp/core/gateway/rpc.h @@ -453,77 +453,62 @@ typedef struct { DEFINE_RPC_COMMON_FIELDS(); - /* needed for request, response, fault */ + UINT32 alloc_hint; + p_context_id_t p_cont_id; - UINT32 alloc_hint; /* 16:04 allocation hint */ - p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */ + BYTE cancel_count; + BYTE reserved; - /* needed for response or fault */ + UINT32 status; - BYTE cancel_count; /* 22:01 received cancel count */ - BYTE reserved; /* 23:01 reserved, m.b.z. */ + /* align(8) */ - /* fault code */ - - UINT32 status; /* 24:04 run-time fault code or zero */ - - /* always pad to next 8-octet boundary */ - - BYTE reserved2[4]; /* 28:04 reserved padding, m.b.z. */ - - /* stub data here, 8-octet aligned */ BYTE* stub_data; - auth_verifier_co_t auth_verifier; /* xx:yy */ + auth_verifier_co_t auth_verifier; } rpcconn_fault_hdr_t; typedef struct { DEFINE_RPC_COMMON_FIELDS(); - auth_verifier_co_t auth_verifier; /* xx:yy */ + auth_verifier_co_t auth_verifier; } rpcconn_orphaned_hdr_t; typedef struct { DEFINE_RPC_COMMON_FIELDS(); - /* needed on request, response, fault */ + UINT32 alloc_hint; - UINT32 alloc_hint; /* 16:04 allocation hint */ - - p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */ - UINT16 opnum; /* 22:02 operation number within the interface */ + p_context_id_t p_cont_id; + UINT16 opnum; /* optional field for request, only present if the PFC_OBJECT_UUID field is non-zero */ + p_uuid_t object; - p_uuid_t object; /* 24:16 object UUID */ - - /* stub data, 8-octet aligned */ + /* align(8) */ BYTE* stub_data; - auth_verifier_co_t auth_verifier; /* xx:yy */ + auth_verifier_co_t auth_verifier; } rpcconn_request_hdr_t; typedef struct { DEFINE_RPC_COMMON_FIELDS(); - /* needed for request, response, fault */ + UINT32 alloc_hint; + p_context_id_t p_cont_id; - UINT32 alloc_hint; /* 16:04 allocation hint */ - p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */ + BYTE cancel_count; + BYTE reserved; - /* needed for response or fault */ + /* align(8) */ - BYTE cancel_count; /* 22:01 cancel count */ - BYTE reserved; /* 23:01 reserved, m.b.z. */ - - /* stub data here, 8-octet aligned */ BYTE* stub_data; - auth_verifier_co_t auth_verifier; /* xx:yy */ + auth_verifier_co_t auth_verifier; } rpcconn_response_hdr_t; typedef struct @@ -711,24 +696,20 @@ struct rpc_virtual_connection_cookie_entry }; typedef struct rpc_virtual_connection_cookie_entry RpcVirtualConnectionCookieEntry; -struct rpc_virtual_connection_cookie_table -{ - UINT32 Count; - UINT32 ArraySize; - RpcVirtualConnectionCookieEntry* Entries; -}; -typedef struct rpc_virtual_connection_cookie_table RpcVirtualConnectionCookieTable; - struct rpc_client { HANDLE Thread; HANDLE StopEvent; + wQueue* SendQueue; + wQueue* ReceiveQueue; + wQueue* FragmentPool; wQueue* FragmentQueue; + wArrayList* ClientCallList; + HANDLE PduSentEvent; - HANDLE SendSemaphore; BOOL SynchronousSend; BOOL SynchronousReceive; @@ -743,7 +724,7 @@ struct rdp_rpc rdpTls* TlsOut; rdpNtlm* ntlm; - int send_seq_num; + int SendSeqNum; RpcClient* client; @@ -753,14 +734,11 @@ struct rdp_rpc rdpSettings* settings; rdpTransport* transport; - UINT32 call_id; + UINT32 CallId; UINT32 PipeCallId; RPC_PDU* pdu; - BYTE* FragBuffer; - UINT32 FragBufferSize; - BYTE* StubBuffer; UINT32 StubBufferSize; UINT32 StubLength; @@ -777,11 +755,6 @@ struct rdp_rpc wStream* RecvFrag; - wQueue* SendQueue; - wQueue* ReceiveQueue; - - wArrayList* ClientCalls; - UINT32 ReceiveWindow; UINT32 ChannelLifetime; @@ -792,11 +765,13 @@ struct rdp_rpc UINT32 CurrentKeepAliveInterval; RpcVirtualConnection* VirtualConnection; - RpcVirtualConnectionCookieTable* VirtualConnectionCookieTable; + + wArrayList* VirtualConnectionCookieTable; }; BOOL rpc_connect(rdpRpc* rpc); +void rpc_pdu_header_print(rpcconn_hdr_t* header); void rpc_pdu_header_init(rdpRpc* rpc, rpcconn_hdr_t* header); UINT32 rpc_offset_align(UINT32* offset, UINT32 alignment); @@ -808,13 +783,9 @@ int rpc_out_write(rdpRpc* rpc, BYTE* data, int length); int rpc_in_write(rdpRpc* rpc, BYTE* data, int length); BOOL rpc_get_stub_data_info(rdpRpc* rpc, BYTE* header, UINT32* offset, UINT32* length); -int rpc_recv_pdu_header(rdpRpc* rpc, BYTE* header); -RPC_PDU* rpc_recv_pdu(rdpRpc* rpc); int rpc_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum); -int rpc_recv(rdpRpc* rpc, RPC_PDU* pdu); - rdpRpc* rpc_new(rdpTransport* transport); void rpc_free(rdpRpc* rpc); diff --git a/libfreerdp/core/gateway/rpc_client.c b/libfreerdp/core/gateway/rpc_client.c index 867be009f..2e18bd609 100644 --- a/libfreerdp/core/gateway/rpc_client.c +++ b/libfreerdp/core/gateway/rpc_client.c @@ -66,7 +66,8 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) buffer = (BYTE*) Stream_Buffer(fragment); header = (rpcconn_hdr_t*) Stream_Buffer(fragment); - rpc->FragBuffer = fragment->buffer; + + rpc_pdu_header_print(header); if (rpc->State < RPC_CLIENT_STATE_CONTEXT_NEGOTIATED) { @@ -76,45 +77,21 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) rpc->pdu->Length = Stream_Length(fragment); rpc->pdu->CallId = header->common.call_id; - Queue_Enqueue(rpc->ReceiveQueue, rpc->pdu); + Queue_Enqueue(rpc->client->ReceiveQueue, rpc->pdu); rpc->pdu = (RPC_PDU*) malloc(sizeof(RPC_PDU)); return 0; } - if (header->common.ptype != PTYPE_RESPONSE) + if (header->common.ptype == PTYPE_RTS) { - printf("unexpected ptype: %d\n", header->common.ptype); - return 0; - } - - if (header->common.ptype == PTYPE_RESPONSE) - { - rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->common.frag_length; - rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->common.frag_length; - - if (!rpc_get_stub_data_info(rpc, buffer, &StubOffset, &StubLength)) + if (rpc->VirtualConnection->State >= VIRTUAL_CONNECTION_STATE_OPENED) { - printf("rpc_recv_pdu_fragment: expected stub\n"); - return -1; - } + printf("Receiving Out-of-Sequence RTS PDU\n"); + rts_recv_out_of_sequence_pdu(rpc, buffer, header->common.frag_length); - if (StubLength == 4) - { - printf("Ignoring TsProxySendToServer Response\n"); rpc_client_fragment_pool_return(rpc, fragment); - return 0; } - } - else if (header->common.ptype == PTYPE_RTS) - { - if (rpc->VirtualConnection->State < VIRTUAL_CONNECTION_STATE_OPENED) - return header->common.frag_length; - - printf("Receiving Out-of-Sequence RTS PDU\n"); - rts_recv_out_of_sequence_pdu(rpc, buffer, header->common.frag_length); - - rpc_client_fragment_pool_return(rpc, fragment); return 0; } @@ -124,6 +101,28 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) return -1; } + if (header->common.ptype != PTYPE_RESPONSE) + { + printf("Unexpected RPC PDU type: %d\n", header->common.ptype); + return -1; + } + + rpc->VirtualConnection->DefaultOutChannel->BytesReceived += header->common.frag_length; + rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow -= header->common.frag_length; + + if (!rpc_get_stub_data_info(rpc, buffer, &StubOffset, &StubLength)) + { + printf("rpc_recv_pdu_fragment: expected stub\n"); + return -1; + } + + if (StubLength == 4) + { + printf("Ignoring TsProxySendToServer Response\n"); + rpc_client_fragment_pool_return(rpc, fragment); + return 0; + } + if (header->response.alloc_hint > rpc->StubBufferSize) { rpc->StubBufferSize = header->response.alloc_hint; @@ -174,7 +173,7 @@ int rpc_client_on_fragment_received_event(rdpRpc* rpc) rpc->StubBufferSize = rpc->max_recv_frag; rpc->StubBuffer = (BYTE*) malloc(rpc->StubBufferSize); - Queue_Enqueue(rpc->ReceiveQueue, rpc->pdu); + Queue_Enqueue(rpc->client->ReceiveQueue, rpc->pdu); rpc->pdu = (RPC_PDU*) malloc(sizeof(RPC_PDU)); return 0; @@ -267,20 +266,20 @@ RpcClientCall* rpc_client_call_find_by_id(rdpRpc* rpc, UINT32 CallId) int count; RpcClientCall* client_call; - ArrayList_Lock(rpc->ClientCalls); + ArrayList_Lock(rpc->client->ClientCallList); client_call = NULL; - count = ArrayList_Count(rpc->ClientCalls); + count = ArrayList_Count(rpc->client->ClientCallList); for (index = 0; index < count; index++) { - client_call = (RpcClientCall*) ArrayList_GetItem(rpc->ClientCalls, index); + client_call = (RpcClientCall*) ArrayList_GetItem(rpc->client->ClientCallList, index); if (client_call->CallId == CallId) break; } - ArrayList_Unlock(rpc->ClientCalls); + ArrayList_Unlock(rpc->client->ClientCallList); return client_call; } @@ -314,7 +313,7 @@ int rpc_send_enqueue_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) pdu->Buffer = buffer; pdu->Length = length; - Queue_Enqueue(rpc->SendQueue, pdu); + Queue_Enqueue(rpc->client->SendQueue, pdu); if (rpc->client->SynchronousSend) { @@ -332,7 +331,7 @@ int rpc_send_dequeue_pdu(rdpRpc* rpc) RpcClientCall* client_call; rpcconn_common_hdr_t* header; - pdu = (RPC_PDU*) Queue_Dequeue(rpc->SendQueue); + pdu = (RPC_PDU*) Queue_Dequeue(rpc->client->SendQueue); if (!pdu) return 0; @@ -373,9 +372,9 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc) pdu = NULL; dwMilliseconds = rpc->client->SynchronousReceive ? INFINITE : 0; - if (WaitForSingleObject(Queue_Event(rpc->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0) + if (WaitForSingleObject(Queue_Event(rpc->client->ReceiveQueue), dwMilliseconds) == WAIT_OBJECT_0) { - pdu = (RPC_PDU*) Queue_Dequeue(rpc->ReceiveQueue); + pdu = (RPC_PDU*) Queue_Dequeue(rpc->client->ReceiveQueue); return pdu; } @@ -396,7 +395,7 @@ static void* rpc_client_thread(void* arg) nCount = 0; events[nCount++] = rpc->client->StopEvent; - events[nCount++] = Queue_Event(rpc->SendQueue); + events[nCount++] = Queue_Event(rpc->client->SendQueue); events[nCount++] = ReadEvent; while (1) @@ -410,10 +409,11 @@ static void* rpc_client_thread(void* arg) if (WaitForSingleObject(ReadEvent, 0) == WAIT_OBJECT_0) { - rpc_client_on_read_event(rpc); + if (rpc_client_on_read_event(rpc) < 0) + break; } - if (WaitForSingleObject(Queue_Event(rpc->SendQueue), 0) == WAIT_OBJECT_0) + if (WaitForSingleObject(Queue_Event(rpc->client->SendQueue), 0) == WAIT_OBJECT_0) { rpc_send_dequeue_pdu(rpc); } @@ -421,9 +421,22 @@ static void* rpc_client_thread(void* arg) CloseHandle(ReadEvent); + rpc_client_free(rpc); + return NULL; } +static void rpc_pdu_free(RPC_PDU* pdu) +{ + free(pdu->Buffer); + free(pdu); +} + +static void rpc_fragment_free(wStream* fragment) +{ + Stream_Free(fragment, TRUE); +} + int rpc_client_new(rdpRpc* rpc) { rpc->client = (RpcClient*) malloc(sizeof(RpcClient)); @@ -435,9 +448,21 @@ int rpc_client_new(rdpRpc* rpc) rpc->client->StopEvent = CreateEvent(NULL, TRUE, FALSE, NULL); rpc->client->PduSentEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + rpc->client->SendQueue = Queue_New(TRUE, -1, -1); + rpc->client->ReceiveQueue = Queue_New(TRUE, -1, -1); + + Queue_Object(rpc->client->SendQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free; + Queue_Object(rpc->client->ReceiveQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_pdu_free; + rpc->client->FragmentPool = Queue_New(TRUE, -1, -1); rpc->client->FragmentQueue = Queue_New(TRUE, -1, -1); + Queue_Object(rpc->client->FragmentPool)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free; + Queue_Object(rpc->client->FragmentQueue)->fnObjectFree = (OBJECT_FREE_FN) rpc_fragment_free; + + rpc->client->ClientCallList = ArrayList_New(TRUE); + ArrayList_Object(rpc->client->ClientCallList)->fnObjectFree = (OBJECT_FREE_FN) rpc_client_call_free; + return 0; } @@ -447,3 +472,24 @@ int rpc_client_start(rdpRpc* rpc) return 0; } + +int rpc_client_stop(rdpRpc* rpc) +{ + SetEvent(rpc->client->StopEvent); + + return 0; +} + +int rpc_client_free(rdpRpc* rpc) +{ + Queue_Clear(rpc->client->SendQueue); + Queue_Free(rpc->client->SendQueue); + + Queue_Clear(rpc->client->ReceiveQueue); + Queue_Free(rpc->client->ReceiveQueue); + + ArrayList_Clear(rpc->client->ClientCallList); + ArrayList_Free(rpc->client->ClientCallList); + + return 0; +} diff --git a/libfreerdp/core/gateway/rpc_client.h b/libfreerdp/core/gateway/rpc_client.h index 857bc515f..7432992a5 100644 --- a/libfreerdp/core/gateway/rpc_client.h +++ b/libfreerdp/core/gateway/rpc_client.h @@ -40,5 +40,7 @@ RPC_PDU* rpc_recv_dequeue_pdu(rdpRpc* rpc); int rpc_client_new(rdpRpc* rpc); int rpc_client_start(rdpRpc* rpc); +int rpc_client_stop(rdpRpc* rpc); +int rpc_client_free(rdpRpc* rpc); #endif /* FREERDP_CORE_RPC_CLIENT_H */ diff --git a/libfreerdp/core/gateway/rts.c b/libfreerdp/core/gateway/rts.c index 5f868501c..5a5d46f7f 100644 --- a/libfreerdp/core/gateway/rts.c +++ b/libfreerdp/core/gateway/rts.c @@ -981,6 +981,10 @@ int rts_recv_out_of_sequence_pdu(rdpRpc* rpc, BYTE* buffer, UINT32 length) { return rts_recv_flow_control_ack_with_destination_pdu(rpc, buffer, length); } + else + { + printf("Unimplemented signature id: 0x%08X\n", SignatureId); + } return 0; } diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index 37118b4d3..aaeb0f5ea 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -160,14 +160,17 @@ void rdp_write_share_data_header(STREAM* s, UINT16 length, BYTE type, UINT32 sha stream_write_UINT16(s, 0); /* compressedLength (2 bytes) */ } -static int RdpSecurity_stream_init(rdpRdp* rdp, STREAM* s) +static int rdp_security_stream_init(rdpRdp* rdp, STREAM* s) { if (rdp->do_crypt) { stream_seek(s, 12); + if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS) stream_seek(s, 4); + rdp->sec_flags |= SEC_ENCRYPT; + if (rdp->do_secure_checksum) rdp->sec_flags |= SEC_SECURE_CHECKSUM; } @@ -175,6 +178,7 @@ static int RdpSecurity_stream_init(rdpRdp* rdp, STREAM* s) { stream_seek(s, 4); } + return 0; } @@ -190,7 +194,7 @@ STREAM* rdp_send_stream_init(rdpRdp* rdp) s = transport_send_stream_init(rdp->transport, 2048); stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); - RdpSecurity_stream_init(rdp, s); + rdp_security_stream_init(rdp, s); return s; } @@ -200,7 +204,7 @@ STREAM* rdp_pdu_init(rdpRdp* rdp) STREAM* s; s = transport_send_stream_init(rdp->transport, 2048); stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); - RdpSecurity_stream_init(rdp, s); + rdp_security_stream_init(rdp, s); stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH); return s; } @@ -210,7 +214,7 @@ STREAM* rdp_data_pdu_init(rdpRdp* rdp) STREAM* s; s = transport_send_stream_init(rdp->transport, 2048); stream_seek(s, RDP_PACKET_HEADER_MAX_LENGTH); - RdpSecurity_stream_init(rdp, s); + rdp_security_stream_init(rdp, s); stream_seek(s, RDP_SHARE_CONTROL_HEADER_LENGTH); stream_seek(s, RDP_SHARE_DATA_HEADER_LENGTH); return s; @@ -284,6 +288,7 @@ void rdp_write_header(rdpRdp* rdp, STREAM* s, UINT16 length, UINT16 channel_id) body_length = length - RDP_PACKET_HEADER_MAX_LENGTH - 16; pad = 8 - (body_length % 8); + if (pad != 8) length += pad; } @@ -302,7 +307,7 @@ void rdp_write_header(rdpRdp* rdp, STREAM* s, UINT16 length, UINT16 channel_id) stream_write_UINT16_be(s, length); /* userData (OCTET_STRING) */ } -static UINT32 RdpSecurity_stream_out(rdpRdp* rdp, STREAM* s, int length) +static UINT32 rdp_security_stream_out(rdpRdp* rdp, STREAM* s, int length) { BYTE* data; UINT32 sec_flags; @@ -403,7 +408,7 @@ BOOL rdp_send(rdpRdp* rdp, STREAM* s, UINT16 channel_id) stream_seek(s, sec_bytes); s->p = sec_hold; - length += RdpSecurity_stream_out(rdp, s, length); + length += rdp_security_stream_out(rdp, s, length); stream_set_pos(s, length); if (transport_write(rdp->transport, s) < 0) @@ -430,7 +435,7 @@ BOOL rdp_send_pdu(rdpRdp* rdp, STREAM* s, UINT16 type, UINT16 channel_id) rdp_write_share_control_header(s, length - sec_bytes, type, channel_id); s->p = sec_hold; - length += RdpSecurity_stream_out(rdp, s, length); + length += rdp_security_stream_out(rdp, s, length); stream_set_pos(s, length); if (transport_write(rdp->transport, s) < 0) @@ -458,7 +463,7 @@ BOOL rdp_send_data_pdu(rdpRdp* rdp, STREAM* s, BYTE type, UINT16 channel_id) rdp_write_share_data_header(s, length - sec_bytes, type, rdp->settings->ShareId); s->p = sec_hold; - length += RdpSecurity_stream_out(rdp, s, length); + length += rdp_security_stream_out(rdp, s, length); stream_set_pos(s, length); if (transport_write(rdp->transport, s) < 0) diff --git a/winpr/include/winpr/collections.h b/winpr/include/winpr/collections.h index 8a08e321d..f092255d7 100644 --- a/winpr/include/winpr/collections.h +++ b/winpr/include/winpr/collections.h @@ -29,6 +29,16 @@ #include +typedef void (*OBJECT_EQUALS_FN)(void* objA, void* objB); +typedef void (*OBJECT_FREE_FN)(void* obj); + +struct _wObject +{ + OBJECT_EQUALS_FN fnObjectEquals; + OBJECT_FREE_FN fnObjectFree; +}; +typedef struct _wObject wObject; + /* System.Collections.Queue */ struct _wQueue @@ -43,6 +53,8 @@ struct _wQueue void** array; HANDLE mutex; HANDLE event; + + wObject object; }; typedef struct _wQueue wQueue; @@ -51,7 +63,10 @@ WINPR_API BOOL Queue_IsSynchronized(wQueue* queue); WINPR_API HANDLE Queue_SyncRoot(wQueue* queue); WINPR_API HANDLE Queue_Event(wQueue* queue); +#define Queue_Object(_queue) (&_queue->object) + WINPR_API void Queue_Clear(wQueue* queue); + WINPR_API BOOL Queue_Contains(wQueue* queue, void* obj); WINPR_API void Queue_Enqueue(wQueue* queue, void* obj); @@ -67,12 +82,15 @@ WINPR_API void Queue_Free(wQueue* queue); struct _wStack { BOOL synchronized; + wObject object; }; typedef struct _wStack wStack; WINPR_API int Stack_Count(wStack* stack); WINPR_API BOOL Stack_IsSynchronized(wStack* stack); +#define Stack_Object(_stack) (&_stack->object) + WINPR_API void Stack_Clear(wStack* stack); WINPR_API BOOL Stack_Contains(wStack* stack, void* obj); @@ -95,6 +113,8 @@ struct _wArrayList int size; void** array; HANDLE mutex; + + wObject object; }; typedef struct _wArrayList wArrayList; @@ -110,6 +130,8 @@ WINPR_API BOOL ArrayList_Unlock(wArrayList* arrayList); WINPR_API void* ArrayList_GetItem(wArrayList* arrayList, int index); WINPR_API void ArrayList_SetItem(wArrayList* arrayList, int index, void* obj); +#define ArrayList_Object(_arrayList) (&_arrayList->object) + WINPR_API void ArrayList_Clear(wArrayList* arrayList); WINPR_API BOOL ArrayList_Contains(wArrayList* arrayList, void* obj); diff --git a/winpr/libwinpr/utils/collections/ArrayList.c b/winpr/libwinpr/utils/collections/ArrayList.c index 1700c77f4..b65bb2868 100644 --- a/winpr/libwinpr/utils/collections/ArrayList.c +++ b/winpr/libwinpr/utils/collections/ArrayList.c @@ -377,6 +377,8 @@ wArrayList* ArrayList_New(BOOL synchronized) arrayList->array = (void**) malloc(sizeof(void*) * arrayList->capacity); arrayList->mutex = CreateMutex(NULL, FALSE, NULL); + + ZeroMemory(&arrayList->object, sizeof(wObject)); } return arrayList; diff --git a/winpr/libwinpr/utils/collections/Queue.c b/winpr/libwinpr/utils/collections/Queue.c index 2b1b22b49..75dc81543 100644 --- a/winpr/libwinpr/utils/collections/Queue.c +++ b/winpr/libwinpr/utils/collections/Queue.c @@ -87,6 +87,9 @@ void Queue_Clear(wQueue* queue) for (index = 0; index < queue->size; index++) { + if (queue->object.fnObjectFree) + queue->object.fnObjectFree(queue->array[index]); + queue->array[index] = NULL; } @@ -228,6 +231,8 @@ wQueue* Queue_New(BOOL synchronized, int capacity, int growthFactor) queue->mutex = CreateMutex(NULL, FALSE, NULL); queue->event = CreateEvent(NULL, TRUE, FALSE, NULL); + + ZeroMemory(&queue->object, sizeof(wObject)); } return queue;