07b789c880
* Implemented missing TSG debug functions * Refactored RPC gateway parser Utilize wStream instead of custom binary parsing code, add proper input validation. Reported by Sunglin from the Knownsec 404 team & 0103 sec team
801 lines
18 KiB
C
801 lines
18 KiB
C
/**
|
|
* FreeRDP: A Remote Desktop Protocol Implementation
|
|
* RPC over HTTP
|
|
*
|
|
* Copyright 2012 Fujitsu Technology Solutions GmbH
|
|
* Copyright 2012 Dmitrij Jasnov <dmitrij.jasnov@ts.fujitsu.com>
|
|
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef FREERDP_LIB_CORE_GATEWAY_RPC_H
|
|
#define FREERDP_LIB_CORE_GATEWAY_RPC_H
|
|
|
|
#include <winpr/wtypes.h>
|
|
#include <winpr/stream.h>
|
|
#include <winpr/collections.h>
|
|
#include <winpr/interlocked.h>
|
|
|
|
#include <freerdp/log.h>
|
|
#include <freerdp/utils/ringbuffer.h>
|
|
|
|
typedef struct rdp_rpc rdpRpc;
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
typedef struct
|
|
{
|
|
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;
|
|
} rpcconn_common_hdr_t;
|
|
|
|
#define RPC_COMMON_FIELDS_LENGTH sizeof(rpcconn_common_hdr_t)
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
UINT16 Flags;
|
|
UINT16 NumberOfCommands;
|
|
} rpcconn_rts_hdr_t;
|
|
|
|
#define RTS_PDU_HEADER_LENGTH 20
|
|
|
|
#define RPC_PDU_FLAG_STUB 0x00000001
|
|
|
|
typedef struct _RPC_PDU
|
|
{
|
|
wStream* s;
|
|
UINT32 Type;
|
|
UINT32 Flags;
|
|
UINT32 CallId;
|
|
} RPC_PDU, *PRPC_PDU;
|
|
|
|
#pragma pack(pop)
|
|
|
|
#include "../tcp.h"
|
|
#include "../transport.h"
|
|
|
|
#include "http.h"
|
|
#include "ntlm.h"
|
|
|
|
#include <time.h>
|
|
|
|
#include <winpr/sspi.h>
|
|
#include <winpr/interlocked.h>
|
|
|
|
#include <freerdp/types.h>
|
|
#include <freerdp/settings.h>
|
|
#include <freerdp/crypto/tls.h>
|
|
#include <freerdp/crypto/crypto.h>
|
|
#include <freerdp/api.h>
|
|
|
|
#include <winpr/print.h>
|
|
|
|
/**
|
|
* CAE Specification
|
|
* DCE 1.1: Remote Procedure Call
|
|
* Document Number: C706
|
|
* http://pubs.opengroup.org/onlinepubs/9629399/
|
|
*/
|
|
|
|
#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_SUPPORT_HEADER_SIGN 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
|
|
* to contain either the RPC common fields
|
|
* or all fields up to the stub data in PDUs
|
|
* that use it (request, response, fault)
|
|
*/
|
|
#define RPC_PDU_HEADER_MAX_LENGTH 32
|
|
|
|
#pragma pack(push, 1)
|
|
|
|
typedef UINT16 p_context_id_t;
|
|
typedef UINT16 p_reject_reason_t;
|
|
|
|
typedef struct
|
|
{
|
|
UINT32 time_low;
|
|
UINT16 time_mid;
|
|
UINT16 time_hi_and_version;
|
|
BYTE clock_seq_hi_and_reserved;
|
|
BYTE clock_seq_low;
|
|
BYTE node[6];
|
|
} p_uuid_t;
|
|
|
|
#define ndr_c_int_big_endian 0
|
|
#define ndr_c_int_little_endian 1
|
|
#define ndr_c_float_ieee 0
|
|
#define ndr_c_float_vax 1
|
|
#define ndr_c_float_cray 2
|
|
#define ndr_c_float_ibm 3
|
|
#define ndr_c_char_ascii 0
|
|
#define ndr_c_char_ebcdic 1
|
|
|
|
typedef struct
|
|
{
|
|
BYTE int_rep;
|
|
BYTE char_rep;
|
|
BYTE float_rep;
|
|
BYTE reserved;
|
|
} ndr_format_t, *ndr_format_p_t;
|
|
|
|
typedef struct ndr_context_handle
|
|
{
|
|
UINT32 context_handle_attributes;
|
|
p_uuid_t context_handle_uuid;
|
|
} ndr_context_handle;
|
|
|
|
typedef struct
|
|
{
|
|
p_uuid_t 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) */
|
|
} 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) */
|
|
} p_cont_list_t;
|
|
|
|
typedef enum
|
|
{
|
|
acceptance,
|
|
user_rejection,
|
|
provider_rejection
|
|
} p_cont_def_result_t;
|
|
|
|
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;
|
|
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) */
|
|
} p_result_list_t;
|
|
|
|
typedef struct
|
|
{
|
|
BYTE major;
|
|
BYTE minor;
|
|
} 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) */
|
|
} p_rt_versions_supported_t;
|
|
|
|
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
|
|
#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;
|
|
|
|
typedef struct
|
|
{
|
|
BYTE rpc_vers;
|
|
BYTE rpc_vers_minor;
|
|
BYTE reserved[2];
|
|
BYTE packed_drep[4];
|
|
UINT32 reject_status;
|
|
BYTE reserved2[4];
|
|
} rpcrt_optional_data_t;
|
|
|
|
typedef struct
|
|
{
|
|
rpcrt_reason_code_t reason_code;
|
|
rpcrt_optional_data_t rpc_info;
|
|
} rpcconn_reject_optional_data_t;
|
|
|
|
typedef struct
|
|
{
|
|
rpcrt_reason_code_t reason_code;
|
|
rpcrt_optional_data_t rpc_info;
|
|
} rpcconn_disc_optional_data_t;
|
|
|
|
typedef struct
|
|
{
|
|
BYTE signature[8];
|
|
} rpc_sec_verification_trailer;
|
|
|
|
struct auth_verifier_co_s
|
|
{
|
|
/* restore 4-byte alignment */
|
|
|
|
BYTE auth_type;
|
|
BYTE auth_level;
|
|
BYTE auth_pad_length;
|
|
BYTE auth_reserved;
|
|
UINT32 auth_context_id;
|
|
|
|
BYTE* auth_value;
|
|
};
|
|
|
|
typedef struct auth_verifier_co_s rpc_sec_trailer;
|
|
typedef struct auth_verifier_co_s auth_verifier_co_t;
|
|
|
|
/* Connection-oriented PDU Definitions */
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
UINT16 max_xmit_frag;
|
|
UINT16 max_recv_frag;
|
|
UINT32 assoc_group_id;
|
|
|
|
p_cont_list_t p_context_elem;
|
|
|
|
auth_verifier_co_t auth_verifier;
|
|
|
|
} rpcconn_alter_context_hdr_t;
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
UINT16 max_xmit_frag;
|
|
UINT16 max_recv_frag;
|
|
UINT32 assoc_group_id;
|
|
port_any_t sec_addr;
|
|
|
|
/* restore 4-octet alignment */
|
|
|
|
p_result_list_t p_result_list;
|
|
|
|
auth_verifier_co_t auth_verifier;
|
|
} rpcconn_alter_context_response_hdr_t;
|
|
|
|
/* bind header */
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
UINT16 max_xmit_frag;
|
|
UINT16 max_recv_frag;
|
|
UINT32 assoc_group_id;
|
|
|
|
p_cont_list_t p_context_elem;
|
|
|
|
auth_verifier_co_t auth_verifier;
|
|
} rpcconn_bind_hdr_t;
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
UINT16 max_xmit_frag;
|
|
UINT16 max_recv_frag;
|
|
UINT32 assoc_group_id;
|
|
|
|
port_any_t sec_addr;
|
|
|
|
/* restore 4-octet alignment */
|
|
|
|
p_result_list_t p_result_list;
|
|
|
|
auth_verifier_co_t auth_verifier;
|
|
} rpcconn_bind_ack_hdr_t;
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
UINT16 max_xmit_frag;
|
|
UINT16 max_recv_frag;
|
|
|
|
auth_verifier_co_t auth_verifier;
|
|
} rpcconn_rpc_auth_3_hdr_t;
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
p_reject_reason_t provider_reject_reason;
|
|
|
|
p_rt_versions_supported_t versions;
|
|
} rpcconn_bind_nak_hdr_t;
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
auth_verifier_co_t auth_verifier;
|
|
|
|
} rpcconn_cancel_hdr_t;
|
|
|
|
/* fault codes */
|
|
|
|
struct _RPC_FAULT_CODE
|
|
{
|
|
UINT32 code;
|
|
const char* name;
|
|
const char* category;
|
|
};
|
|
typedef struct _RPC_FAULT_CODE RPC_FAULT_CODE;
|
|
|
|
#define DEFINE_RPC_FAULT_CODE(_code, cat) \
|
|
{ \
|
|
_code, #_code, cat \
|
|
}
|
|
|
|
#define nca_s_comm_failure 0x1C010001
|
|
#define nca_s_op_rng_error 0x1C010002
|
|
#define nca_s_unk_if 0x1C010003
|
|
#define nca_s_wrong_boot_time 0x1C010006
|
|
#define nca_s_you_crashed 0x1C010009
|
|
#define nca_s_proto_error 0x1C01000B
|
|
#define nca_s_out_args_too_big 0x1C010013
|
|
#define nca_s_server_too_busy 0x1C010014
|
|
#define nca_s_fault_string_too_long 0x1C010015
|
|
#define nca_s_unsupported_type 0x1C010017
|
|
#define nca_s_fault_int_div_by_zero 0x1C000001
|
|
#define nca_s_fault_addr_error 0x1C000002
|
|
#define nca_s_fault_fp_div_zero 0x1C000003
|
|
#define nca_s_fault_fp_underflow 0x1C000004
|
|
#define nca_s_fault_fp_overflow 0x1C000005
|
|
#define nca_s_fault_invalid_tag 0x1C000006
|
|
#define nca_s_fault_invalid_bound 0x1C000007
|
|
#define nca_s_rpc_version_mismatch 0x1C000008
|
|
#define nca_s_unspec_reject 0x1C000009
|
|
#define nca_s_bad_actid 0x1C00000A
|
|
#define nca_s_who_are_you_failed 0x1C00000B
|
|
#define nca_s_manager_not_entered 0x1C00000C
|
|
#define nca_s_fault_cancel 0x1C00000D
|
|
#define nca_s_fault_ill_inst 0x1C00000E
|
|
#define nca_s_fault_fp_error 0x1C00000F
|
|
#define nca_s_fault_int_overflow 0x1C000010
|
|
#define nca_s_fault_unspec 0x1C000012
|
|
#define nca_s_fault_remote_comm_failure 0x1C000013
|
|
#define nca_s_fault_pipe_empty 0x1C000014
|
|
#define nca_s_fault_pipe_closed 0x1C000015
|
|
#define nca_s_fault_pipe_order 0x1C000016
|
|
#define nca_s_fault_pipe_discipline 0x1C000017
|
|
#define nca_s_fault_pipe_comm_error 0x1C000018
|
|
#define nca_s_fault_pipe_memory 0x1C000019
|
|
#define nca_s_fault_context_mismatch 0x1C00001A
|
|
#define nca_s_fault_remote_no_memory 0x1C00001B
|
|
#define nca_s_invalid_pres_context_id 0x1C00001C
|
|
#define nca_s_unsupported_authn_level 0x1C00001D
|
|
#define nca_s_invalid_checksum 0x1C00001F
|
|
#define nca_s_invalid_crc 0x1C000020
|
|
#define nca_s_fault_user_defined 0x1C000021
|
|
#define nca_s_fault_tx_open_failed 0x1C000022
|
|
#define nca_s_fault_codeset_conv_error 0x1C000023
|
|
#define nca_s_fault_object_not_found 0x1C000024
|
|
#define nca_s_fault_no_client_stub 0x1C000025
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
UINT32 alloc_hint;
|
|
p_context_id_t p_cont_id;
|
|
|
|
BYTE cancel_count;
|
|
BYTE reserved;
|
|
|
|
UINT32 status;
|
|
|
|
/* align(8) */
|
|
|
|
BYTE* stub_data;
|
|
|
|
auth_verifier_co_t auth_verifier;
|
|
} rpcconn_fault_hdr_t;
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
auth_verifier_co_t auth_verifier;
|
|
} rpcconn_orphaned_hdr_t;
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
UINT32 alloc_hint;
|
|
|
|
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;
|
|
|
|
/* align(8) */
|
|
|
|
BYTE* stub_data;
|
|
|
|
auth_verifier_co_t auth_verifier;
|
|
} rpcconn_request_hdr_t;
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
|
|
UINT32 alloc_hint;
|
|
p_context_id_t p_cont_id;
|
|
|
|
BYTE cancel_count;
|
|
BYTE reserved;
|
|
|
|
/* align(8) */
|
|
|
|
BYTE* stub_data;
|
|
|
|
auth_verifier_co_t auth_verifier;
|
|
} rpcconn_response_hdr_t;
|
|
|
|
typedef struct
|
|
{
|
|
rpcconn_common_hdr_t header;
|
|
} 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_rts_hdr_t rts;
|
|
} rpcconn_hdr_t;
|
|
|
|
#pragma pack(pop)
|
|
|
|
struct _RPC_SECURITY_PROVIDER_INFO
|
|
{
|
|
UINT32 Id;
|
|
LONG EvenLegs;
|
|
LONG NumLegs;
|
|
};
|
|
typedef struct _RPC_SECURITY_PROVIDER_INFO RPC_SECURITY_PROVIDER_INFO;
|
|
|
|
enum _RPC_CLIENT_STATE
|
|
{
|
|
RPC_CLIENT_STATE_INITIAL,
|
|
RPC_CLIENT_STATE_ESTABLISHED,
|
|
RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK,
|
|
RPC_CLIENT_STATE_WAIT_UNSECURE_BIND_ACK,
|
|
RPC_CLIENT_STATE_WAIT_SECURE_ALTER_CONTEXT_RESPONSE,
|
|
RPC_CLIENT_STATE_CONTEXT_NEGOTIATED,
|
|
RPC_CLIENT_STATE_WAIT_RESPONSE,
|
|
RPC_CLIENT_STATE_FINAL
|
|
};
|
|
typedef enum _RPC_CLIENT_STATE RPC_CLIENT_STATE;
|
|
|
|
enum _RPC_CLIENT_CALL_STATE
|
|
{
|
|
RPC_CLIENT_CALL_STATE_INITIAL,
|
|
RPC_CLIENT_CALL_STATE_SEND_PDUS,
|
|
RPC_CLIENT_CALL_STATE_DISPATCHED,
|
|
RPC_CLIENT_CALL_STATE_RECEIVE_PDU,
|
|
RPC_CLIENT_CALL_STATE_COMPLETE,
|
|
RPC_CLIENT_CALL_STATE_FAULT,
|
|
RPC_CLIENT_CALL_STATE_FINAL
|
|
};
|
|
typedef enum _RPC_CLIENT_CALL_STATE RPC_CLIENT_CALL_STATE;
|
|
|
|
struct rpc_client_call
|
|
{
|
|
UINT32 CallId;
|
|
UINT32 OpNum;
|
|
RPC_CLIENT_CALL_STATE State;
|
|
};
|
|
typedef struct rpc_client_call RpcClientCall;
|
|
|
|
struct rpc_client
|
|
{
|
|
rdpContext* context;
|
|
RPC_PDU* pdu;
|
|
HANDLE PipeEvent;
|
|
RingBuffer ReceivePipe;
|
|
wStream* ReceiveFragment;
|
|
CRITICAL_SECTION PipeLock;
|
|
wArrayList* ClientCallList;
|
|
char* host;
|
|
UINT16 port;
|
|
BOOL isProxy;
|
|
};
|
|
typedef struct rpc_client RpcClient;
|
|
|
|
struct rpc_channel
|
|
{
|
|
RpcClient* client;
|
|
BIO* bio;
|
|
rdpTls* tls;
|
|
rdpNtlm* ntlm;
|
|
HttpContext* http;
|
|
BYTE Cookie[16];
|
|
};
|
|
typedef struct rpc_channel RpcChannel;
|
|
|
|
/* Ping Originator */
|
|
|
|
struct rpc_ping_originator
|
|
{
|
|
UINT32 ConnectionTimeout;
|
|
UINT32 LastPacketSentTimestamp;
|
|
UINT32 KeepAliveInterval;
|
|
};
|
|
typedef struct rpc_ping_originator RpcPingOriginator;
|
|
|
|
/* Client In Channel */
|
|
|
|
enum _CLIENT_IN_CHANNEL_STATE
|
|
{
|
|
CLIENT_IN_CHANNEL_STATE_INITIAL,
|
|
CLIENT_IN_CHANNEL_STATE_CONNECTED,
|
|
CLIENT_IN_CHANNEL_STATE_SECURITY,
|
|
CLIENT_IN_CHANNEL_STATE_NEGOTIATED,
|
|
CLIENT_IN_CHANNEL_STATE_OPENED,
|
|
CLIENT_IN_CHANNEL_STATE_OPENED_A4W,
|
|
CLIENT_IN_CHANNEL_STATE_FINAL
|
|
};
|
|
typedef enum _CLIENT_IN_CHANNEL_STATE CLIENT_IN_CHANNEL_STATE;
|
|
|
|
struct rpc_in_channel
|
|
{
|
|
/* Sending Channel */
|
|
|
|
RpcChannel common;
|
|
|
|
CLIENT_IN_CHANNEL_STATE State;
|
|
|
|
UINT32 PlugState;
|
|
void* SendQueue;
|
|
UINT32 BytesSent;
|
|
UINT32 SenderAvailableWindow;
|
|
UINT32 PeerReceiveWindow;
|
|
|
|
/* Ping Originator */
|
|
|
|
RpcPingOriginator PingOriginator;
|
|
};
|
|
typedef struct rpc_in_channel RpcInChannel;
|
|
|
|
/* Client Out Channel */
|
|
|
|
enum _CLIENT_OUT_CHANNEL_STATE
|
|
{
|
|
CLIENT_OUT_CHANNEL_STATE_INITIAL,
|
|
CLIENT_OUT_CHANNEL_STATE_CONNECTED,
|
|
CLIENT_OUT_CHANNEL_STATE_SECURITY,
|
|
CLIENT_OUT_CHANNEL_STATE_NEGOTIATED,
|
|
CLIENT_OUT_CHANNEL_STATE_OPENED,
|
|
CLIENT_OUT_CHANNEL_STATE_OPENED_A6W,
|
|
CLIENT_OUT_CHANNEL_STATE_OPENED_A10W,
|
|
CLIENT_OUT_CHANNEL_STATE_OPENED_B3W,
|
|
CLIENT_OUT_CHANNEL_STATE_RECYCLED,
|
|
CLIENT_OUT_CHANNEL_STATE_FINAL
|
|
};
|
|
typedef enum _CLIENT_OUT_CHANNEL_STATE CLIENT_OUT_CHANNEL_STATE;
|
|
|
|
struct rpc_out_channel
|
|
{
|
|
/* Receiving Channel */
|
|
|
|
RpcChannel common;
|
|
|
|
CLIENT_OUT_CHANNEL_STATE State;
|
|
|
|
UINT32 ReceiveWindow;
|
|
UINT32 ReceiveWindowSize;
|
|
UINT32 ReceiverAvailableWindow;
|
|
UINT32 BytesReceived;
|
|
UINT32 AvailableWindowAdvertised;
|
|
};
|
|
typedef struct rpc_out_channel RpcOutChannel;
|
|
|
|
/* Client Virtual Connection */
|
|
|
|
enum _VIRTUAL_CONNECTION_STATE
|
|
{
|
|
VIRTUAL_CONNECTION_STATE_INITIAL,
|
|
VIRTUAL_CONNECTION_STATE_OUT_CHANNEL_WAIT,
|
|
VIRTUAL_CONNECTION_STATE_WAIT_A3W,
|
|
VIRTUAL_CONNECTION_STATE_WAIT_C2,
|
|
VIRTUAL_CONNECTION_STATE_OPENED,
|
|
VIRTUAL_CONNECTION_STATE_FINAL
|
|
};
|
|
typedef enum _VIRTUAL_CONNECTION_STATE VIRTUAL_CONNECTION_STATE;
|
|
|
|
struct rpc_virtual_connection
|
|
{
|
|
BYTE Cookie[16];
|
|
BYTE AssociationGroupId[16];
|
|
VIRTUAL_CONNECTION_STATE State;
|
|
RpcInChannel* DefaultInChannel;
|
|
RpcInChannel* NonDefaultInChannel;
|
|
RpcOutChannel* DefaultOutChannel;
|
|
RpcOutChannel* NonDefaultOutChannel;
|
|
};
|
|
typedef struct rpc_virtual_connection RpcVirtualConnection;
|
|
|
|
/* Virtual Connection Cookie Table */
|
|
|
|
#define RPC_UUID_FORMAT_STRING \
|
|
"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x"
|
|
#define RPC_UUID_FORMAT_ARGUMENTS(_rpc_uuid) \
|
|
_rpc_uuid[0], _rpc_uuid[1], _rpc_uuid[2], _rpc_uuid[3], _rpc_uuid[4], _rpc_uuid[5], \
|
|
_rpc_uuid[6], _rpc_uuid[7], _rpc_uuid[8], _rpc_uuid[9], _rpc_uuid[10], _rpc_uuid[11], \
|
|
_rpc_uuid[12], _rpc_uuid[13], _rpc_uuid[14], _rpc_uuid[15]
|
|
|
|
struct rpc_virtual_connection_cookie_entry
|
|
{
|
|
BYTE Cookie[16];
|
|
UINT32 ReferenceCount;
|
|
RpcVirtualConnection* Reference;
|
|
};
|
|
typedef struct rpc_virtual_connection_cookie_entry RpcVirtualConnectionCookieEntry;
|
|
|
|
struct rdp_rpc
|
|
{
|
|
RPC_CLIENT_STATE State;
|
|
|
|
UINT32 result;
|
|
|
|
rdpNtlm* ntlm;
|
|
size_t SendSeqNum;
|
|
|
|
RpcClient* client;
|
|
|
|
rdpTransport* transport;
|
|
|
|
UINT32 CallId;
|
|
UINT32 PipeCallId;
|
|
|
|
UINT32 StubCallId;
|
|
UINT32 StubFragCount;
|
|
|
|
BYTE rpc_vers;
|
|
BYTE rpc_vers_minor;
|
|
BYTE packed_drep[4];
|
|
|
|
UINT16 max_xmit_frag;
|
|
UINT16 max_recv_frag;
|
|
|
|
UINT32 ReceiveWindow;
|
|
UINT32 ChannelLifetime;
|
|
UINT32 KeepAliveInterval;
|
|
UINT32 CurrentKeepAliveTime;
|
|
UINT32 CurrentKeepAliveInterval;
|
|
|
|
RpcVirtualConnection* VirtualConnection;
|
|
};
|
|
|
|
FREERDP_LOCAL void rpc_pdu_header_print(const rpcconn_hdr_t* header);
|
|
FREERDP_LOCAL rpcconn_common_hdr_t rpc_pdu_header_init(const rdpRpc* rpc);
|
|
|
|
FREERDP_LOCAL size_t rpc_offset_align(size_t* offset, size_t alignment);
|
|
FREERDP_LOCAL size_t rpc_offset_pad(size_t* offset, size_t pad);
|
|
|
|
FREERDP_LOCAL BOOL rpc_get_stub_data_info(const rpcconn_hdr_t* header, size_t* offset,
|
|
size_t* length);
|
|
|
|
FREERDP_LOCAL SSIZE_T rpc_channel_write(RpcChannel* channel, const BYTE* data, size_t length);
|
|
|
|
FREERDP_LOCAL SSIZE_T rpc_channel_read(RpcChannel* channel, wStream* s, size_t length);
|
|
|
|
FREERDP_LOCAL void rpc_channel_free(RpcChannel* channel);
|
|
|
|
FREERDP_LOCAL RpcOutChannel* rpc_out_channel_new(rdpRpc* rpc);
|
|
FREERDP_LOCAL int rpc_out_channel_replacement_connect(RpcOutChannel* outChannel, int timeout);
|
|
|
|
FREERDP_LOCAL BOOL rpc_in_channel_transition_to_state(RpcInChannel* inChannel,
|
|
CLIENT_IN_CHANNEL_STATE state);
|
|
FREERDP_LOCAL BOOL rpc_out_channel_transition_to_state(RpcOutChannel* outChannel,
|
|
CLIENT_OUT_CHANNEL_STATE state);
|
|
|
|
FREERDP_LOCAL BOOL rpc_virtual_connection_transition_to_state(rdpRpc* rpc,
|
|
RpcVirtualConnection* connection,
|
|
VIRTUAL_CONNECTION_STATE state);
|
|
|
|
FREERDP_LOCAL BOOL rpc_connect(rdpRpc* rpc, UINT32 timeout);
|
|
|
|
FREERDP_LOCAL rdpRpc* rpc_new(rdpTransport* transport);
|
|
FREERDP_LOCAL void rpc_free(rdpRpc* rpc);
|
|
|
|
#endif /* FREERDP_LIB_CORE_GATEWAY_RPC_H */
|