From 187147d399226bc263928127662ae384ac4e3d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 29 Oct 2012 15:02:35 -0400 Subject: [PATCH] libfreerdp-core: cleanup of TSG definitions --- CMakeLists.txt | 12 +- cmake/FindCmockery.cmake | 41 ++ include/freerdp/api.h | 6 + libfreerdp/core/CMakeLists.txt | 7 + libfreerdp/core/rpc.c | 113 +++--- libfreerdp/core/rpc.h | 575 +++++++++++----------------- libfreerdp/core/rts.c | 15 +- libfreerdp/core/rts.h | 1 + libfreerdp/core/test/.gitignore | 2 + libfreerdp/core/test/CMakeLists.txt | 40 ++ libfreerdp/core/test/TestCoreRts.c | 66 ++++ libfreerdp/crypto/tls.c | 1 - 12 files changed, 462 insertions(+), 417 deletions(-) create mode 100644 cmake/FindCmockery.cmake create mode 100644 libfreerdp/core/test/.gitignore create mode 100644 libfreerdp/core/test/CMakeLists.txt create mode 100644 libfreerdp/core/test/TestCoreRts.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 503d7458f..aafdbaea3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -137,8 +137,6 @@ if(MSVC) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_X86_") endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_UNICODE") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_WIN32_WINNT=0x0501") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN") @@ -146,6 +144,9 @@ if(MSVC) SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}) endif() +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWINPR_EXPORTS") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_EXPORTS") + # Include files check_include_files(fcntl.h HAVE_FCNTL_H) check_include_files(unistd.h HAVE_UNISTD_H) @@ -245,10 +246,15 @@ set(CMAKE_INSTALL_RPATH "\$ORIGIN/../${CMAKE_INSTALL_LIBDIR}") # Unit Tests -INCLUDE(CTest) +include(CTest) if(BUILD_TESTING) + find_suggested_package(Cmockery) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREERDP_TEST_EXPORTS") + enable_testing() + if(MSVC) set(TESTING_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}") else() diff --git a/cmake/FindCmockery.cmake b/cmake/FindCmockery.cmake new file mode 100644 index 000000000..d7c8c2d13 --- /dev/null +++ b/cmake/FindCmockery.cmake @@ -0,0 +1,41 @@ +# - Find Cmockery +# Find the Cmockery libraries +# +# This module defines the following variables: +# CMOCKERY_FOUND - true if CMOCKERY_INCLUDE_DIR & CMOCKERY_LIBRARY are found +# CMOCKERY_LIBRARIES - Set when CMOCKERY_LIBRARY is found +# CMOCKERY_INCLUDE_DIRS - Set when CMOCKERY_INCLUDE_DIR is found +# + +#============================================================================= +# Copyright 2012 Marc-Andre Moreau +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +#============================================================================= + +find_path(CMOCKERY_INCLUDE_DIR NAMES cmockery.h + PATH_SUFFIXES google) + +find_library(CMOCKERY_LIBRARY NAMES cmockery + DOC "The Cmockery library") + +include(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Cmockery DEFAULT_MSG CMOCKERY_LIBRARY CMOCKERY_INCLUDE_DIR) + +if(CMOCKERY_FOUND) + set(CMOCKERY_LIBRARIES ${CMOCKERY_LIBRARY}) + set(CMOCKERY_INCLUDE_DIRS ${CMOCKERY_INCLUDE_DIR}) +endif() + +mark_as_advanced(CMOCKERY_INCLUDE_DIR CMOCKERY_LIBRARY) + diff --git a/include/freerdp/api.h b/include/freerdp/api.h index 5804715f6..b10538a9f 100644 --- a/include/freerdp/api.h +++ b/include/freerdp/api.h @@ -54,6 +54,12 @@ #endif #endif +#ifdef FREERDP_TEST_EXPORTS +#define FREERDP_TEST_API FREERDP_API +#else +#define FREERDP_TEST_API +#endif + #define IFCALL(_cb, ...) do { if (_cb != NULL) { _cb( __VA_ARGS__ ); } } while (0) #define IFCALLRET(_cb, _ret, ...) do { if (_cb != NULL) { _ret = _cb( __VA_ARGS__ ); } } while (0) diff --git a/libfreerdp/core/CMakeLists.txt b/libfreerdp/core/CMakeLists.txt index 4efe3e00b..002279615 100644 --- a/libfreerdp/core/CMakeLists.txt +++ b/libfreerdp/core/CMakeLists.txt @@ -124,3 +124,10 @@ else() endif() set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "FreeRDP/libfreerdp") + +if(BUILD_TESTING) + if(CMOCKERY_FOUND) + add_subdirectory(test) + endif() +endif() + diff --git a/libfreerdp/core/rpc.c b/libfreerdp/core/rpc.c index ca8067379..000aa0ae4 100644 --- a/libfreerdp/core/rpc.c +++ b/libfreerdp/core/rpc.c @@ -415,7 +415,7 @@ void rpc_pdu_header_read(STREAM* s, RPC_PDU_HEADER* header) { stream_read_BYTE(s, header->rpc_vers); /* rpc_vers (1 byte) */ stream_read_BYTE(s, header->rpc_vers_minor); /* rpc_vers_minor (1 byte) */ - stream_read_BYTE(s, header->ptype); /* PTYPE (1 byte) */ + stream_read_BYTE(s, header->ptype); /* ptype (1 byte) */ stream_read_BYTE(s, header->pfc_flags); /* pfc_flags (1 byte) */ stream_read_BYTE(s, header->packed_drep[0]); /* packet_drep[0] (1 byte) */ stream_read_BYTE(s, header->packed_drep[1]); /* packet_drep[1] (1 byte) */ @@ -426,6 +426,21 @@ void rpc_pdu_header_read(STREAM* s, RPC_PDU_HEADER* header) stream_read_UINT32(s, header->call_id); /* call_id (4 bytes) */ } +void rpc_pdu_header_write(STREAM* s, RPC_PDU_HEADER* header) +{ + stream_write_BYTE(s, header->rpc_vers); /* rpc_vers (1 byte) */ + stream_write_BYTE(s, header->rpc_vers_minor); /* rpc_vers_minor (1 byte) */ + stream_write_BYTE(s, header->ptype); /* PTYPE (1 byte) */ + stream_write_BYTE(s, header->pfc_flags); /* pfc_flags (1 byte) */ + stream_write_BYTE(s, header->packed_drep[0]); /* packet_drep[0] (1 byte) */ + stream_write_BYTE(s, header->packed_drep[1]); /* packet_drep[1] (1 byte) */ + stream_write_BYTE(s, header->packed_drep[2]); /* packet_drep[2] (1 byte) */ + stream_write_BYTE(s, header->packed_drep[3]); /* packet_drep[3] (1 byte) */ + stream_write_UINT16(s, header->frag_length); /* frag_length (2 bytes) */ + stream_write_UINT16(s, header->auth_length); /* auth_length (2 bytes) */ + stream_write_UINT32(s, header->call_id); /* call_id (4 bytes) */ +} + int rpc_out_write(rdpRpc* rpc, BYTE* data, int length) { int status; @@ -477,9 +492,10 @@ BOOL rpc_send_bind_pdu(rdpRpc* rpc) ntlm_stream->p = ntlm_stream->data = rpc->ntlm->outputBuffer.pvBuffer; bind_pdu = xnew(rpcconn_bind_hdr_t); + bind_pdu->rpc_vers = 5; bind_pdu->rpc_vers_minor = 0; - bind_pdu->PTYPE = PTYPE_BIND; + bind_pdu->ptype = PTYPE_BIND; bind_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_PENDING_CANCEL | PFC_CONC_MPX; bind_pdu->packed_drep[0] = 0x10; bind_pdu->packed_drep[1] = 0x00; @@ -488,9 +504,11 @@ BOOL rpc_send_bind_pdu(rdpRpc* rpc) bind_pdu->frag_length = 124 + ntlm_stream->size; bind_pdu->auth_length = ntlm_stream->size; bind_pdu->call_id = 2; + bind_pdu->max_xmit_frag = 0x0FF8; bind_pdu->max_recv_frag = 0x0FF8; bind_pdu->assoc_group_id = 0; + bind_pdu->p_context_elem.n_context_elem = 2; bind_pdu->p_context_elem.reserved = 0; bind_pdu->p_context_elem.reserved2 = 0; @@ -498,27 +516,27 @@ BOOL rpc_send_bind_pdu(rdpRpc* rpc) bind_pdu->p_context_elem.p_cont_elem[0].p_cont_id = 0; bind_pdu->p_context_elem.p_cont_elem[0].n_transfer_syn = 1; bind_pdu->p_context_elem.p_cont_elem[0].reserved = 0; - bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_low = 0x44e265dd; - bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_mid = 0x7daf; - bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_hi_and_version = 0x42cd; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_low = 0x44E265DD; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_mid = 0x7DAF; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.time_hi_and_version = 0x42CD; bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.clock_seq_hi_and_reserved = 0x85; bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.clock_seq_low = 0x60; - bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[0] = 0x3c; - bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[1] = 0xdb; - bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[2] = 0x6e; - bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[3] = 0x7a; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[0] = 0x3C; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[1] = 0xDB; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[2] = 0x6E; + bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[3] = 0x7A; bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[4] = 0x27; bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_uuid.node[5] = 0x29; bind_pdu->p_context_elem.p_cont_elem[0].abstract_syntax.if_version = 0x00030001; bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes = malloc(sizeof(p_syntax_id_t)); - bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_low = 0x8a885d04; - bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_mid = 0x1ceb; - bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_hi_and_version = 0x11c9; - bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.clock_seq_hi_and_reserved = 0x9f; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_low = 0x8A885D04; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_mid = 0x1CEB; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.time_hi_and_version = 0x11C9; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.clock_seq_hi_and_reserved = 0x9F; bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.clock_seq_low = 0xe8; bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[0] = 0x08; bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[1] = 0x00; - bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[2] = 0x2b; + bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[2] = 0x2B; bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[3] = 0x10; bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[4] = 0x48; bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_uuid.node[5] = 0x60; @@ -526,20 +544,20 @@ BOOL rpc_send_bind_pdu(rdpRpc* rpc) bind_pdu->p_context_elem.p_cont_elem[1].p_cont_id = 1; bind_pdu->p_context_elem.p_cont_elem[1].n_transfer_syn = 1; bind_pdu->p_context_elem.p_cont_elem[1].reserved = 0; - bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_low = 0x44e265dd; - bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_mid = 0x7daf; - bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_hi_and_version = 0x42cd; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_low = 0x44E265DD; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_mid = 0x7DAF; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.time_hi_and_version = 0x42CD; bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.clock_seq_hi_and_reserved = 0x85; bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.clock_seq_low = 0x60; - bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[0] = 0x3c; - bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[1] = 0xdb; - bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[2] = 0x6e; - bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[3] = 0x7a; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[0] = 0x3C; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[1] = 0xDB; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[2] = 0x6E; + bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[3] = 0x7A; bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[4] = 0x27; bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_uuid.node[5] = 0x29; bind_pdu->p_context_elem.p_cont_elem[1].abstract_syntax.if_version = 0x00030001; bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes = malloc(sizeof(p_syntax_id_t)); - bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.time_low = 0x6cb71c2c; + bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.time_low = 0x6CB71C2C; bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.time_mid = 0x9812; bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.time_hi_and_version = 0x4540; bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.clock_seq_hi_and_reserved = 0x03; @@ -551,13 +569,14 @@ BOOL rpc_send_bind_pdu(rdpRpc* rpc) bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[4] = 0x00; bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[5] = 0x00; bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_version = 0x00000001; - bind_pdu->auth_verifier.auth_pad = NULL; /* align(4); size_is(auth_pad_length) p*/ - bind_pdu->auth_verifier.auth_type = 0x0a; /* :01 which authent service */ - bind_pdu->auth_verifier.auth_level = 0x05; /* :01 which level within service */ - bind_pdu->auth_verifier.auth_pad_length = 0x00; /* :01 */ - bind_pdu->auth_verifier.auth_reserved = 0x00; /* :01 reserved, m.b.z. */ - bind_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */ - bind_pdu->auth_verifier.auth_value = malloc(bind_pdu->auth_length); /* credentials; size_is(auth_length) p*/; + + bind_pdu->auth_verifier.auth_pad = NULL; + bind_pdu->auth_verifier.auth_type = 0x0A; + bind_pdu->auth_verifier.auth_level = 0x05; + bind_pdu->auth_verifier.auth_pad_length = 0x00; + bind_pdu->auth_verifier.auth_reserved = 0x00; + bind_pdu->auth_verifier.auth_context_id = 0x00000000; + bind_pdu->auth_verifier.auth_value = malloc(bind_pdu->auth_length); memcpy(bind_pdu->auth_verifier.auth_value, ntlm_stream->data, bind_pdu->auth_length); stream_free(ntlm_stream); @@ -580,7 +599,7 @@ BOOL rpc_send_bind_pdu(rdpRpc* rpc) rpc_in_write(rpc, pdu->data, pdu->size); - stream_free(pdu) ; + stream_free(pdu); free(bind_pdu); return TRUE; @@ -644,9 +663,10 @@ BOOL rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) s->p = s->data = rpc->ntlm->outputBuffer.pvBuffer; rpc_auth_3_pdu = xnew(rpcconn_rpc_auth_3_hdr_t); + rpc_auth_3_pdu->rpc_vers = 5; rpc_auth_3_pdu->rpc_vers_minor = 0; - rpc_auth_3_pdu->PTYPE = PTYPE_RPC_AUTH_3; + rpc_auth_3_pdu->ptype = PTYPE_RPC_AUTH_3; rpc_auth_3_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_CONC_MPX; rpc_auth_3_pdu->packed_drep[0] = 0x10; rpc_auth_3_pdu->packed_drep[1] = 0x00; @@ -658,13 +678,13 @@ BOOL rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) rpc_auth_3_pdu->max_xmit_frag = 0x0FF8; rpc_auth_3_pdu->max_recv_frag = 0x0FF8; - rpc_auth_3_pdu->auth_verifier.auth_pad = NULL; /* align(4); size_is(auth_pad_length) p */ - rpc_auth_3_pdu->auth_verifier.auth_type = 0x0a; /* :01 which authent service */ - rpc_auth_3_pdu->auth_verifier.auth_level = 0x05; /* :01 which level within service */ - rpc_auth_3_pdu->auth_verifier.auth_pad_length = 0x00; /* :01 */ - rpc_auth_3_pdu->auth_verifier.auth_reserved = 0x00; /* :01 reserved, m.b.z. */ - rpc_auth_3_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */ - rpc_auth_3_pdu->auth_verifier.auth_value = malloc(rpc_auth_3_pdu->auth_length); /* credentials; size_is(auth_length) p */ + rpc_auth_3_pdu->auth_verifier.auth_pad = NULL; + rpc_auth_3_pdu->auth_verifier.auth_type = 0x0A; + rpc_auth_3_pdu->auth_verifier.auth_level = 0x05; + rpc_auth_3_pdu->auth_verifier.auth_pad_length = 0x00; + rpc_auth_3_pdu->auth_verifier.auth_reserved = 0x00; + rpc_auth_3_pdu->auth_verifier.auth_context_id = 0x00000000; + rpc_auth_3_pdu->auth_verifier.auth_value = malloc(rpc_auth_3_pdu->auth_length); memcpy(rpc_auth_3_pdu->auth_verifier.auth_value, s->data, rpc_auth_3_pdu->auth_length); stream_free(s); @@ -782,9 +802,10 @@ int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) auth_pad_length = 0; request_pdu = xnew(rpcconn_request_hdr_t); + request_pdu->rpc_vers = 5; request_pdu->rpc_vers_minor = 0; - request_pdu->PTYPE = PTYPE_REQUEST; + request_pdu->ptype = PTYPE_REQUEST; request_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG; request_pdu->packed_drep[0] = 0x10; request_pdu->packed_drep[1] = 0x00; @@ -803,19 +824,19 @@ int rpc_tsg_write(rdpRpc* rpc, BYTE* data, int length, UINT16 opnum) request_pdu->p_cont_id = 0x0000; request_pdu->opnum = opnum; request_pdu->stub_data = data; - request_pdu->auth_verifier.auth_type = 0x0A; /* :01 which authentication service */ - request_pdu->auth_verifier.auth_level = 0x05; /* :01 which level within service */ - request_pdu->auth_verifier.auth_pad_length = auth_pad_length; /* :01 */ - request_pdu->auth_verifier.auth_pad = malloc(auth_pad_length); /* align(4); size_is(auth_pad_length) p */ + request_pdu->auth_verifier.auth_type = 0x0A; + request_pdu->auth_verifier.auth_level = 0x05; + request_pdu->auth_verifier.auth_pad_length = auth_pad_length; + request_pdu->auth_verifier.auth_pad = malloc(auth_pad_length); for (i = 0; i < auth_pad_length; i++) { request_pdu->auth_verifier.auth_pad[i] = 0x00; } - request_pdu->auth_verifier.auth_reserved = 0x00; /* :01 reserved, m.b.z. */ - request_pdu->auth_verifier.auth_context_id = 0x00000000; /* :04 */ - request_pdu->auth_verifier.auth_value = malloc(request_pdu->auth_length); /* credentials; size_is(auth_length) p */ + request_pdu->auth_verifier.auth_reserved = 0x00; + request_pdu->auth_verifier.auth_context_id = 0x00000000; + request_pdu->auth_verifier.auth_value = malloc(request_pdu->auth_length); pdu = stream_new(request_pdu->frag_length); diff --git a/libfreerdp/core/rpc.h b/libfreerdp/core/rpc.h index a166f8451..ebfb03754 100644 --- a/libfreerdp/core/rpc.h +++ b/libfreerdp/core/rpc.h @@ -42,490 +42,341 @@ typedef struct rdp_ntlm_http rdpNtlmHttp; #include #include +/** + * CAE Specification + * DCE 1.1: Remote Procedure Call + * Document Number: C706 + * 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 + struct _rpc_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(); }; typedef struct _rpc_pdu_header RPC_PDU_HEADER; -typedef UINT16 p_context_id_t; +typedef UINT16 p_context_id_t; +typedef UINT16 p_reject_reason_t; -typedef struct { - uuid if_uuid; - UINT32 if_version; +typedef struct +{ + uuid if_uuid; + UINT32 if_version; } p_syntax_id_t; -typedef struct { - p_context_id_t p_cont_id; - BYTE n_transfer_syn; /* number of items */ - BYTE reserved; /* alignment pad, m.b.z. */ - p_syntax_id_t abstract_syntax; /* transfer syntax list */ - p_syntax_id_t* transfer_syntaxes; /*size_is(n_transfer_syn)*/ +typedef struct +{ + p_context_id_t p_cont_id; + BYTE n_transfer_syn; /* number of items */ + BYTE reserved; /* alignment pad, m.b.z. */ + p_syntax_id_t abstract_syntax; /* transfer syntax list */ + p_syntax_id_t* transfer_syntaxes; /* size_is(n_transfer_syn) */ } p_cont_elem_t; -typedef struct { - BYTE n_context_elem; /* number of items */ - BYTE reserved; /* alignment pad, m.b.z. */ - UINT16 reserved2; /* alignment pad, m.b.z. */ - p_cont_elem_t* p_cont_elem; /*size_is(n_cont_elem)*/ +typedef struct +{ + BYTE n_context_elem; /* number of items */ + BYTE reserved; /* alignment pad, m.b.z. */ + UINT16 reserved2; /* alignment pad, m.b.z. */ + p_cont_elem_t* p_cont_elem; /* size_is(n_cont_elem) */ } p_cont_list_t; -typedef enum { - acceptance, user_rejection, provider_rejection +typedef enum +{ + acceptance, + user_rejection, + provider_rejection } p_cont_def_result_t; -typedef enum { +typedef enum +{ reason_not_specified, abstract_syntax_not_supported, proposed_transfer_syntaxes_not_supported, local_limit_exceeded } p_provider_reason_t; - -typedef struct { - p_cont_def_result_t result; - p_provider_reason_t reason; /* only relevant if result != - * acceptance */ - p_syntax_id_t transfer_syntax;/* tr syntax selected - * 0 if result not - * accepted */ +typedef struct +{ + p_cont_def_result_t result; + p_provider_reason_t reason; + p_syntax_id_t transfer_syntax; } p_result_t; /* Same order and number of elements as in bind request */ -typedef struct { - BYTE n_results; /* count */ - BYTE reserved; /* alignment pad, m.b.z. */ - UINT16 reserved2; /* alignment pad, m.b.z. */ - p_result_t* p_results; /*size_is(n_results)*/ +typedef struct +{ + BYTE n_results; /* count */ + BYTE reserved; /* alignment pad, m.b.z. */ + UINT16 reserved2; /* alignment pad, m.b.z. */ + p_result_t* p_results; /* size_is(n_results) */ } p_result_list_t; -typedef struct { - BYTE major; - BYTE minor; +typedef struct +{ + BYTE major; + BYTE minor; } version_t; -typedef version_t p_rt_version_t; +typedef version_t p_rt_version_t; -typedef struct { - BYTE n_protocols; /* count */ - p_rt_version_t* p_protocols; /* size_is(n_protocols) */ +typedef struct +{ + BYTE n_protocols; /* count */ + p_rt_version_t* p_protocols; /* size_is(n_protocols) */ } p_rt_versions_supported_t; -typedef struct { - UINT16 length; - char* port_spec; /* port string spec; size_is(length) */ +typedef struct +{ + UINT16 length; + char* port_spec; /* port string spec; size_is(length) */ } port_any_t; -#define REASON_NOT_SPECIFIED 0 -#define TEMPORARY_CONGESTION 1 -#define LOCAL_LIMIT_EXCEEDED 2 -#define CALLED_PADDR_UNKNOWN 3 /* not used */ -#define PROTOCOL_VERSION_NOT_SUPPORTED 4 -#define DEFAULT_CONTEXT_NOT_SUPPORTED 5 /* not used */ -#define USER_DATA_NOT_READABLE 6 /* not used */ -#define NO_PSAP_AVAILABLE 7 /* not used */ +#define REASON_NOT_SPECIFIED 0 +#define TEMPORARY_CONGESTION 1 +#define LOCAL_LIMIT_EXCEEDED 2 +#define CALLED_PADDR_UNKNOWN 3 +#define PROTOCOL_VERSION_NOT_SUPPORTED 4 +#define DEFAULT_CONTEXT_NOT_SUPPORTED 5 +#define USER_DATA_NOT_READABLE 6 +#define NO_PSAP_AVAILABLE 7 -typedef UINT16 rpcrt_reason_code_t;/* 0..65535 */ +typedef UINT16 rpcrt_reason_code_t; -typedef struct { - BYTE rpc_vers; - BYTE rpc_vers_minor; - BYTE reserved[2];/* must be zero */ - BYTE packed_drep[4]; - UINT32 reject_status; - BYTE reserved2[4]; +typedef struct +{ + BYTE rpc_vers; + BYTE rpc_vers_minor; + BYTE reserved[2]; /* must be zero */ + BYTE packed_drep[4]; + UINT32 reject_status; + BYTE reserved2[4]; } rpcrt_optional_data_t; -typedef struct { - rpcrt_reason_code_t reason_code; /* 0..65535 */ - rpcrt_optional_data_t rpc_info; /* may be RPC specific */ +typedef struct +{ + rpcrt_reason_code_t reason_code; /* 0..65535 */ + rpcrt_optional_data_t rpc_info; /* may be RPC specific */ } rpcconn_reject_optional_data_t; -typedef struct { - rpcrt_reason_code_t reason_code; /* 0..65535 */ - rpcrt_optional_data_t rpc_info; /* may be RPC-specific */ +typedef struct +{ + rpcrt_reason_code_t reason_code; /* 0..65535 */ + rpcrt_optional_data_t rpc_info; /* may be RPC-specific */ } rpcconn_disc_optional_data_t; -typedef struct{ +typedef struct +{ /* restore 4 byte alignment */ - - BYTE* auth_pad; /* align(4); size_is(auth_pad_length) */ - BYTE auth_type; /* :01 which authent service */ - BYTE auth_level; /* :01 which level within service */ - BYTE auth_pad_length; /* :01 */ - BYTE auth_reserved; /* :01 reserved, m.b.z. */ - UINT32 auth_context_id; /* :04 */ - BYTE* auth_value; /* credentials; size_is(auth_length) */ + BYTE* auth_pad; /* align(4); size_is(auth_pad_length) */ + BYTE auth_type; /* :01 which authent service */ + BYTE auth_level; /* :01 which level within service */ + BYTE auth_pad_length; /* :01 */ + BYTE auth_reserved; /* :01 reserved, m.b.z. */ + UINT32 auth_context_id; /* :04 */ + BYTE* auth_value; /* credentials; size_is(auth_length) */ } auth_verifier_co_t; /* Connection-oriented PDU Definitions */ -typedef struct { - /* start 8-octet aligned */ +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor ; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 alter context PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 length of auth_value */ - UINT32 call_id; /* 12:04 call identifier */ - - /* end common fields */ - - UINT16 max_xmit_frag; /* ignored */ - UINT16 max_recv_frag; /* ignored */ - UINT32 assoc_group_id; /* ignored */ + UINT16 max_xmit_frag; /* ignored */ + UINT16 max_recv_frag; /* ignored */ + UINT32 assoc_group_id; /* ignored */ /* presentation context list */ - p_cont_list_t p_context_elem; /* variable size */ + p_cont_list_t p_context_elem; /* variable size */ /* optional authentication verifier */ - /* following fields present iff auth_length != 0 */ - auth_verifier_co_t auth_verifier; + /* following fields present if auth_length != 0 */ + + auth_verifier_co_t auth_verifier; } rpcconn_alter_context_hdr_t; -typedef struct { - /* start 8-octet aligned */ +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 alter - context response PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 length of auth_value */ - UINT32 call_id; /* 12:04 call identifier */ + UINT16 max_xmit_frag; + UINT16 max_recv_frag; + UINT32 assoc_group_id; + port_any_t sec_addr; - /* end common fields */ - - UINT16 max_xmit_frag; /* ignored */ - UINT16 max_recv_frag; /* ignored */ - UINT32 assoc_group_id; /* ignored */ - port_any_t sec_addr; /* ignored */ - - /* restore 4-octet alignment */ - - BYTE* pad2; /* size_is(align(4)) */ - - /* presentation context result list, including hints */ - - p_result_list_t p_result_list; /* variable size */ - - /* optional authentication verifier */ - /* following fields present iff auth_length != 0 */ - - auth_verifier_co_t auth_verifier; /* xx:yy */ -} rpcconn_alter_context_response_hdr_t; - -/* bind header */ -typedef struct { - /* start 8-octet aligned */ - - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 bind PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 length of auth_value */ - UINT32 call_id; /* 12:04 call identifier */ - - /* end common fields */ - - UINT16 max_xmit_frag; /* 16:02 max transmit frag size, bytes */ - UINT16 max_recv_frag; /* 18:02 max receive frag size, bytes */ - UINT32 assoc_group_id; /* 20:04 incarnation of client-server - * assoc group */ - /* presentation context list */ - - p_cont_list_t p_context_elem; /* variable size */ - - /* optional authentication verifier */ - /* following fields present iff auth_length != 0 */ - - auth_verifier_co_t auth_verifier; -} rpcconn_bind_hdr_t; - -typedef struct { - /* start 8-octet aligned */ - - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor ; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 bind ack PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 length of auth_value */ - UINT32 call_id; /* 12:04 call identifier */ - - /* end common fields */ - - UINT16 max_xmit_frag; /* 16:02 max transmit frag size */ - UINT16 max_recv_frag; /* 18:02 max receive frag size */ - UINT32 assoc_group_id; /* 20:04 returned assoc_group_id */ - port_any_t sec_addr; /* 24:yy optional secondary address - * for process incarnation; local port - * part of address only */ /* restore 4-octet alignment */ BYTE* pad2; /* size_is(align(4)) */ /* presentation context result list, including hints */ - p_result_list_t p_result_list; /* variable size */ + p_result_list_t p_result_list; /* variable size */ /* optional authentication verifier */ /* following fields present iff auth_length != 0 */ - auth_verifier_co_t auth_verifier; /* xx:yy */ + auth_verifier_co_t auth_verifier; /* xx:yy */ +} rpcconn_alter_context_response_hdr_t; + +/* bind header */ +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); + + UINT16 max_xmit_frag; /* 16:02 max transmit frag size, bytes */ + UINT16 max_recv_frag; /* 18:02 max receive frag size, bytes */ + UINT32 assoc_group_id; /* 20:04 incarnation of client-server assoc group */ + + /* presentation context list */ + + p_cont_list_t p_context_elem; /* variable size */ + + /* optional authentication verifier */ + /* following fields present if auth_length != 0 */ + + auth_verifier_co_t auth_verifier; +} rpcconn_bind_hdr_t; + +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); + + UINT16 max_xmit_frag; /* 16:02 max transmit frag size */ + UINT16 max_recv_frag; /* 18:02 max receive frag size */ + UINT32 assoc_group_id; /* 20:04 returned assoc_group_id */ + port_any_t sec_addr; /* 24:yy optional secondary address for process incarnation; local port part of address only */ + + /* restore 4-octet alignment */ + + BYTE* pad2; /* size_is(align(4)) */ + + /* presentation context result list, including hints */ + + p_result_list_t p_result_list; /* variable size */ + + auth_verifier_co_t auth_verifier; /* xx:yy */ } rpcconn_bind_ack_hdr_t; -typedef struct { - /* start 8-octet aligned */ +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor ; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 bind ack PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 length of auth_value */ - UINT32 call_id; /* 12:04 call identifier */ + UINT16 max_xmit_frag; /* 16:02 max transmit frag size */ + UINT16 max_recv_frag; /* 18:02 max receive frag size */ - /* end common fields */ - - UINT16 max_xmit_frag; /* 16:02 max transmit frag size */ - UINT16 max_recv_frag; /* 18:02 max receive frag size */ - - /* optional authentication verifier */ - /* following fields present iff auth_length != 0 */ - - auth_verifier_co_t auth_verifier; /* xx:yy */ + auth_verifier_co_t auth_verifier; /* xx:yy */ } rpcconn_rpc_auth_3_hdr_t; -typedef struct { - /* start 8-octet aligned */ +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor ; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 bind nak PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 length of auth_value */ - UINT32 call_id; /* 12:04 call identifier */ + p_reject_reason_t provider_reject_reason; - /* end common fields */ - - /*p_reject_reason_t*/UINT16 provider_reject_reason; /* 16:02 presentation (TODO search definition of p_reject_reason_t) - context reject */ - - p_rt_versions_supported_t versions; /* 18:yy array of protocol - * versions supported */ + p_rt_versions_supported_t versions; /* 18:yy array of protocol versions supported */ } rpcconn_bind_nak_hdr_t; +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); -typedef struct { - /* start 8-octet aligned */ - - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 CO cancel PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 length of auth_value */ - UINT32 call_id; /* 12:04 call identifier */ - - /* end common fields */ - - /* optional authentication verifier - * following fields present iff auth_length != 0 */ - - auth_verifier_co_t auth_verifier; /* xx:yy */ + auth_verifier_co_t auth_verifier; /* xx:yy */ } rpcconn_cancel_hdr_t; -typedef struct { - /* start 8-octet aligned */ - - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 fault PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 length of auth_value */ - UINT32 call_id; /* 12:04 call identifier */ - - /* end common fields */ +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); /* needed for request, response, fault */ - UINT32 alloc_hint; /* 16:04 allocation hint */ + UINT32 alloc_hint; /* 16:04 allocation hint */ p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */ /* needed for response or fault */ - BYTE cancel_count; /* 22:01 received cancel count */ - BYTE reserved; /* 23:01 reserved, m.b.z. */ + BYTE cancel_count; /* 22:01 received cancel count */ + BYTE reserved; /* 23:01 reserved, m.b.z. */ - /* fault code */ + /* fault code */ - UINT32 status; /* 24:04 run-time fault code or zero */ + 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. */ + BYTE reserved2[4]; /* 28:04 reserved padding, m.b.z. */ - /* stub data here, 8-octet aligned - . - . - . */ + /* stub data here, 8-octet aligned */ BYTE* stub_data; - /* optional authentication verifier */ - /* following fields present iff auth_length != 0 */ - - auth_verifier_co_t auth_verifier; /* xx:yy */ + auth_verifier_co_t auth_verifier; /* xx:yy */ } rpcconn_fault_hdr_t; +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); -typedef struct { - /* start 8-octet aligned */ - - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 orphaned PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 length of auth_value */ - UINT32 call_id; /* 12:04 call identifier */ - - /* end common fields */ - - /* optional authentication verifier - * following fields present iff auth_length != 0 */ - - auth_verifier_co_t auth_verifier; /* xx:yy */ + auth_verifier_co_t auth_verifier; /* xx:yy */ } rpcconn_orphaned_hdr_t; - -typedef struct { - /* start 8-octet aligned */ - - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 request PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 length of auth_value */ - UINT32 call_id; /* 12:04 call identifier */ - - /* end common fields */ +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); /* needed on request, response, fault */ - 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 # - * within the interface */ + 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 */ - /* optional field for request, only present if the PFC_OBJECT_UUID - * field is non-zero */ + /* optional field for request, only present if the PFC_OBJECT_UUID field is non-zero */ - uuid object; /* 24:16 object UID */ + uuid object; /* 24:16 object UID */ + + /* stub data, 8-octet aligned */ - /* stub data, 8-octet aligned - . - . - . */ BYTE* stub_data; - /* optional authentication verifier */ - /* following fields present iff auth_length != 0 */ - - auth_verifier_co_t auth_verifier; /* xx:yy */ + auth_verifier_co_t auth_verifier; /* xx:yy */ } rpcconn_request_hdr_t; -typedef struct { - /* start 8-octet aligned */ - - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 response PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 length of auth_value */ - UINT32 call_id; /* 12:04 call identifier */ - - /* end common fields */ +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); /* needed for request, response, fault */ - UINT32 alloc_hint; /* 16:04 allocation hint */ - p_context_id_t p_cont_id; /* 20:02 pres context, i.e. - * data rep */ + UINT32 alloc_hint; /* 16:04 allocation hint */ + p_context_id_t p_cont_id; /* 20:02 pres context, i.e. data rep */ /* needed for response or fault */ - BYTE cancel_count; /* 22:01 cancel count */ - BYTE reserved; /* 23:01 reserved, m.b.z. */ + BYTE cancel_count; /* 22:01 cancel count */ + BYTE reserved; /* 23:01 reserved, m.b.z. */ - /* stub data here, 8-octet aligned - . - . - . */ + /* stub data here, 8-octet aligned */ BYTE* stub_data; - /* optional authentication verifier */ - /* following fields present iff auth_length != 0 */ - - auth_verifier_co_t auth_verifier; /* xx:yy */ + auth_verifier_co_t auth_verifier; /* xx:yy */ } rpcconn_response_hdr_t; - -typedef struct { - /* start 8-octet aligned */ - - /* common fields */ - BYTE rpc_vers; /* 00:01 RPC version */ - BYTE rpc_vers_minor; /* 01:01 minor version */ - BYTE PTYPE; /* 02:01 shutdown PDU */ - BYTE pfc_flags; /* 03:01 flags */ - BYTE packed_drep[4]; /* 04:04 NDR data rep format label*/ - UINT16 frag_length; /* 08:02 total length of fragment */ - UINT16 auth_length; /* 10:02 */ - UINT32 call_id; /* 12:04 call identifier */ - - /* end common fields */ +typedef struct +{ + DEFINE_RPC_COMMON_FIELDS(); } rpcconn_shutdown_hdr_t; struct rdp_ntlm diff --git a/libfreerdp/core/rts.c b/libfreerdp/core/rts.c index 04d99bc70..27c3439e2 100644 --- a/libfreerdp/core/rts.c +++ b/libfreerdp/core/rts.c @@ -45,6 +45,11 @@ * */ +/** + * [MS-RPCH]: Remote Procedure Call over HTTP Protocol Specification: + * http://msdn.microsoft.com/en-us/library/cc243950/ + */ + BOOL rts_connect(rdpRpc* rpc) { int status; @@ -352,7 +357,7 @@ void rts_ping_traffic_sent_notify_command_write(STREAM* s, UINT32 PingTrafficSen stream_write_UINT32(s, PingTrafficSent); /* PingTrafficSent (4 bytes) */ } -void rpc_generate_cookie(BYTE* cookie) +void rts_generate_cookie(BYTE* cookie) { RAND_pseudo_bytes(cookie, 16); } @@ -383,8 +388,8 @@ BOOL rts_send_CONN_A1_pdu(rdpRpc* rpc) s = stream_new(header.frag_length); - rpc_generate_cookie((BYTE*) &(rpc->VirtualConnection->Cookie)); - rpc_generate_cookie((BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie)); + rts_generate_cookie((BYTE*) &(rpc->VirtualConnection->Cookie)); + rts_generate_cookie((BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie)); VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie); OUTChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie); @@ -430,8 +435,8 @@ BOOL rts_send_CONN_B1_pdu(rdpRpc* rpc) s = stream_new(header.frag_length); - rpc_generate_cookie((BYTE*) &(rpc->VirtualConnection->DefaultInChannelCookie)); - rpc_generate_cookie((BYTE*) &(rpc->VirtualConnection->AssociationGroupId)); + rts_generate_cookie((BYTE*) &(rpc->VirtualConnection->DefaultInChannelCookie)); + rts_generate_cookie((BYTE*) &(rpc->VirtualConnection->AssociationGroupId)); VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie); INChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultInChannelCookie); diff --git a/libfreerdp/core/rts.h b/libfreerdp/core/rts.h index 7cab90011..c87b1ddb1 100644 --- a/libfreerdp/core/rts.h +++ b/libfreerdp/core/rts.h @@ -26,6 +26,7 @@ #include "config.h" #endif +#include #include #include #include diff --git a/libfreerdp/core/test/.gitignore b/libfreerdp/core/test/.gitignore new file mode 100644 index 000000000..6c68d0825 --- /dev/null +++ b/libfreerdp/core/test/.gitignore @@ -0,0 +1,2 @@ +TestCore +TestCore.c diff --git a/libfreerdp/core/test/CMakeLists.txt b/libfreerdp/core/test/CMakeLists.txt new file mode 100644 index 000000000..940a25516 --- /dev/null +++ b/libfreerdp/core/test/CMakeLists.txt @@ -0,0 +1,40 @@ + +set(MODULE_NAME "TestCore") +set(MODULE_PREFIX "TEST_CORE") + +set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c) + +set(${MODULE_PREFIX}_TESTS + TestCoreRts.c) + +create_test_sourcelist(${MODULE_PREFIX}_SRCS + ${${MODULE_PREFIX}_DRIVER} + ${${MODULE_PREFIX}_TESTS}) + +include_directories(..) + +add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS}) + +set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${CMOCKERY_LIBRARIES}) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE freerdp + MODULES freerdp-core) + +set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS + MONOLITHIC ${MONOLITHIC_BUILD} + MODULE winpr + MODULES winpr-crt winpr-utils) + +target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) + +set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}") + +foreach(test ${${MODULE_PREFIX}_TESTS}) + get_filename_component(TestName ${test} NAME_WE) + add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName}) +endforeach() + +set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test") + diff --git a/libfreerdp/core/test/TestCoreRts.c b/libfreerdp/core/test/TestCoreRts.c new file mode 100644 index 000000000..fb30c7e5c --- /dev/null +++ b/libfreerdp/core/test/TestCoreRts.c @@ -0,0 +1,66 @@ + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "rts.h" + +/* mocks */ + +extern void rts_generate_cookie(BYTE* cookie); +extern int rpc_in_write(rdpRpc* rpc, BYTE* data, int length); +extern int rpc_out_write(rdpRpc* rpc, BYTE* data, int length); + +BYTE testCookie[16] = "\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC"; + +void rts_generate_cookie(BYTE* cookie) +{ + CopyMemory(cookie, testCookie, 16); +} + +int rpc_in_write(rdpRpc* rpc, BYTE* data, int length) +{ + printf("rpc_in_write: %d\n", length); + //winpr_HexDump(data, length); + return length; +} + +int rpc_out_write(rdpRpc* rpc, BYTE* data, int length) +{ + printf("rpc_out_write: %d\n", length); + //winpr_HexDump(data, length); + return length; +} + +/* tests */ + +void test_rts_generate_cookie(void **state) +{ + BYTE cookie[16]; + rts_generate_cookie(cookie); + assert_memory_equal(cookie, testCookie, 16); +} + +void test_rpc_in_write(void **state) +{ + int status; + status = rpc_in_write(NULL, NULL, 64); + assert_int_equal(status, 64); +} + +int TestCoreRts(int argc, char* argv[]) +{ + const UnitTest tests[] = + { + unit_test(test_rts_generate_cookie), + unit_test(test_rpc_in_write), + }; + + return run_tests(tests); +} diff --git a/libfreerdp/crypto/tls.c b/libfreerdp/crypto/tls.c index acaf4243c..2f0ab1b5c 100644 --- a/libfreerdp/crypto/tls.c +++ b/libfreerdp/crypto/tls.c @@ -349,7 +349,6 @@ int tls_write(rdpTls* tls, BYTE* data, int length) return status; } - int tls_write_all(rdpTls* tls, BYTE* data, int length) { int status;