mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
libfreerdp-core: split code from rpc.c to rpc_bind.c and rpc_fault.c
This commit is contained in:
@@ -29,10 +29,14 @@ include_directories(".")
|
||||
include_directories(${${MODULE_PREFIX}_GATEWAY_DIR})
|
||||
|
||||
set(${MODULE_PREFIX}_GATEWAY_SRCS
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/rpc.c
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/rpc.h
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/tsg.c
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/tsg.h
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/rpc.c
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/rpc.h
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/rpc_bind.c
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/rpc_bind.h
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/rpc_fault.c
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/rpc_fault.h
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/rts.c
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/rts.h
|
||||
${${MODULE_PREFIX}_GATEWAY_DIR}/rts_signature.c
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
#include "http.h"
|
||||
#include "ntlm.h"
|
||||
#include "ncacn_http.h"
|
||||
#include "rpc_bind.h"
|
||||
#include "rpc_fault.h"
|
||||
|
||||
#include "rpc.h"
|
||||
|
||||
@@ -44,46 +46,6 @@
|
||||
rpc_sec_verification_trailer RPC_SEC_VERIFICATION_TRAILER =
|
||||
{ { 0x8a, 0xe3, 0x13, 0x71, 0x02, 0xf4, 0x36, 0x71 } };
|
||||
|
||||
/* Syntax UUIDs */
|
||||
|
||||
const p_uuid_t TSGU_UUID =
|
||||
{
|
||||
0x44E265DD, /* time_low */
|
||||
0x7DAF, /* time_mid */
|
||||
0x42CD, /* time_hi_and_version */
|
||||
0x85, /* clock_seq_hi_and_reserved */
|
||||
0x60, /* clock_seq_low */
|
||||
{ 0x3C, 0xDB, 0x6E, 0x7A, 0x27, 0x29 } /* node[6] */
|
||||
};
|
||||
|
||||
#define TSGU_SYNTAX_IF_VERSION 0x00030001
|
||||
|
||||
const p_uuid_t NDR_UUID =
|
||||
{
|
||||
0x8A885D04, /* time_low */
|
||||
0x1CEB, /* time_mid */
|
||||
0x11C9, /* time_hi_and_version */
|
||||
0x9F, /* clock_seq_hi_and_reserved */
|
||||
0xE8, /* clock_seq_low */
|
||||
{ 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60 } /* node[6] */
|
||||
};
|
||||
|
||||
#define NDR_SYNTAX_IF_VERSION 0x00000002
|
||||
|
||||
const p_uuid_t BTFN_UUID =
|
||||
{
|
||||
0x6CB71C2C, /* time_low */
|
||||
0x9812, /* time_mid */
|
||||
0x4540, /* time_hi_and_version */
|
||||
0x03, /* clock_seq_hi_and_reserved */
|
||||
0x00, /* clock_seq_low */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } /* node[6] */
|
||||
};
|
||||
|
||||
#define BTFN_SYNTAX_IF_VERSION 0x00000001
|
||||
|
||||
extern const RPC_FAULT_CODE RPC_TSG_FAULT_CODES[];
|
||||
|
||||
static char* PTYPE_STRINGS[] =
|
||||
{
|
||||
"PTYPE_REQUEST",
|
||||
@@ -110,114 +72,15 @@ static char* PTYPE_STRINGS[] =
|
||||
""
|
||||
};
|
||||
|
||||
const RPC_FAULT_CODE RPC_FAULT_CODES[] =
|
||||
const RPC_SECURITY_PROVIDER_INFO RPC_SECURITY_PROVIDER_INFO_TABLE[] =
|
||||
{
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_object_not_found)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_cancel)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_addr_error)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_context_mismatch)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_fp_div_zero)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_fp_error)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_fp_overflow)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_fp_underflow)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_ill_inst)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_int_div_by_zero)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_int_overflow)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_invalid_bound)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_invalid_tag)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_closed)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_comm_error)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_discipline)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_empty)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_memory)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_order)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_remote_no_memory)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_user_defined)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_tx_open_failed)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_codeset_conv_error)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_no_client_stub)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_STRING_BINDING)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_WRONG_KIND_OF_BINDING)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_BINDING)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_PROTSEQ_NOT_SUPPORTED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_RPC_PROTSEQ)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_STRING_UUID)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_ENDPOINT_FORMAT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_NET_ADDR)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_ENDPOINT_FOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_TIMEOUT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_OBJECT_NOT_FOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ALREADY_REGISTERED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_TYPE_ALREADY_REGISTERED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ALREADY_LISTENING)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_PROTSEQS_REGISTERED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NOT_LISTENING)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_MGR_TYPE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_IF)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_BINDINGS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_PROTSEQS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_CANT_CREATE_ENDPOINT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_OUT_OF_RESOURCES)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_SERVER_UNAVAILABLE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_SERVER_TOO_BUSY)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_NETWORK_OPTIONS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_CALL_ACTIVE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_CALL_FAILED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_CALL_FAILED_DNE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_PROTOCOL_ERROR)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_PROXY_ACCESS_DENIED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNSUPPORTED_TRANS_SYN)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNSUPPORTED_TYPE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_TAG)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_BOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_ENTRY_NAME)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_NAME_SYNTAX)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNSUPPORTED_NAME_SYNTAX)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UUID_NO_ADDRESS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_DUPLICATE_ENDPOINT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_AUTHN_TYPE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_MAX_CALLS_TOO_SMALL)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_STRING_TOO_LONG)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_PROTSEQ_NOT_FOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_PROCNUM_OUT_OF_RANGE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_BINDING_HAS_NO_AUTH)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_AUTHN_SERVICE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_AUTHN_LEVEL)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_AUTH_IDENTITY)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_AUTHZ_SERVICE)
|
||||
DEFINE_RPC_FAULT_CODE(EPT_S_INVALID_ENTRY)
|
||||
DEFINE_RPC_FAULT_CODE(EPT_S_CANT_PERFORM_OP)
|
||||
DEFINE_RPC_FAULT_CODE(EPT_S_NOT_REGISTERED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NOTHING_TO_EXPORT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INCOMPLETE_NAME)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_VERS_OPTION)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_MORE_MEMBERS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NOT_ALL_OBJS_UNEXPORTED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INTERFACE_NOT_FOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ENTRY_ALREADY_EXISTS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ENTRY_NOT_FOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NAME_SERVICE_UNAVAILABLE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_NAF_ID)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_CANNOT_SUPPORT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_CONTEXT_AVAILABLE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INTERNAL_ERROR)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ZERO_DIVIDE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ADDRESS_ERROR)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_FP_DIV_ZERO)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_FP_UNDERFLOW)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_FP_OVERFLOW)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_NO_MORE_ENTRIES)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_CHAR_TRANS_OPEN_FAIL)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_CHAR_TRANS_SHORT_FILE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_IN_NULL_CONTEXT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_CONTEXT_DAMAGED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_HANDLES_MISMATCH)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_CANNOT_GET_CALL_HANDLE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_NULL_REF_POINTER)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_ENUM_VALUE_OUT_OF_RANGE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_BYTE_COUNT_TOO_SMALL)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_BAD_STUB_DATA)
|
||||
{ 0, NULL }
|
||||
{ RPC_C_AUTHN_NONE, TRUE, -1 },
|
||||
{ RPC_C_AUTHN_GSS_NEGOTIATE, TRUE, -1 },
|
||||
{ RPC_C_AUTHN_WINNT, FALSE, 3 },
|
||||
{ RPC_C_AUTHN_GSS_SCHANNEL, TRUE, -1 },
|
||||
{ RPC_C_AUTHN_GSS_KERBEROS, TRUE, -1 },
|
||||
{ RPC_C_AUTHN_DEFAULT, -1, -1 },
|
||||
{ 0, -1, -1 }
|
||||
};
|
||||
|
||||
void rpc_pdu_header_print(rpcconn_hdr_t* header)
|
||||
@@ -291,232 +154,6 @@ UINT32 rpc_offset_pad(UINT32* offset, UINT32 pad)
|
||||
return pad;
|
||||
}
|
||||
|
||||
BOOL rpc_send_bind_pdu(rdpRpc* rpc)
|
||||
{
|
||||
BYTE* buffer;
|
||||
UINT32 offset;
|
||||
p_cont_elem_t* p_cont_elem;
|
||||
rpcconn_bind_hdr_t* bind_pdu;
|
||||
rdpSettings* settings = rpc->settings;
|
||||
|
||||
rpc->ntlm = ntlm_new();
|
||||
|
||||
DEBUG_RPC("Sending bind PDU");
|
||||
|
||||
ntlm_client_init(rpc->ntlm, FALSE, settings->Username, settings->Domain, settings->Password);
|
||||
|
||||
ntlm_authenticate(rpc->ntlm);
|
||||
|
||||
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, (rpcconn_hdr_t*) bind_pdu);
|
||||
|
||||
bind_pdu->auth_length = rpc->ntlm->outputBuffer.cbBuffer;
|
||||
bind_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer.pvBuffer;
|
||||
|
||||
bind_pdu->ptype = PTYPE_BIND;
|
||||
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 = 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;
|
||||
bind_pdu->p_context_elem.reserved = 0;
|
||||
bind_pdu->p_context_elem.reserved2 = 0;
|
||||
|
||||
bind_pdu->p_context_elem.p_cont_elem = malloc(sizeof(p_cont_elem_t) * bind_pdu->p_context_elem.n_context_elem);
|
||||
|
||||
p_cont_elem = &bind_pdu->p_context_elem.p_cont_elem[0];
|
||||
|
||||
p_cont_elem->p_cont_id = 0;
|
||||
p_cont_elem->n_transfer_syn = 1;
|
||||
p_cont_elem->reserved = 0;
|
||||
CopyMemory(&(p_cont_elem->abstract_syntax.if_uuid), &TSGU_UUID, sizeof(p_uuid_t));
|
||||
p_cont_elem->abstract_syntax.if_version = TSGU_SYNTAX_IF_VERSION;
|
||||
|
||||
p_cont_elem->transfer_syntaxes = malloc(sizeof(p_syntax_id_t));
|
||||
CopyMemory(&(p_cont_elem->transfer_syntaxes[0].if_uuid), &NDR_UUID, sizeof(p_uuid_t));
|
||||
p_cont_elem->transfer_syntaxes[0].if_version = NDR_SYNTAX_IF_VERSION;
|
||||
|
||||
p_cont_elem = &bind_pdu->p_context_elem.p_cont_elem[1];
|
||||
|
||||
p_cont_elem->p_cont_id = 1;
|
||||
p_cont_elem->n_transfer_syn = 1;
|
||||
p_cont_elem->reserved = 0;
|
||||
CopyMemory(&(p_cont_elem->abstract_syntax.if_uuid), &TSGU_UUID, sizeof(p_uuid_t));
|
||||
p_cont_elem->abstract_syntax.if_version = TSGU_SYNTAX_IF_VERSION;
|
||||
|
||||
p_cont_elem->transfer_syntaxes = malloc(sizeof(p_syntax_id_t));
|
||||
CopyMemory(&(p_cont_elem->transfer_syntaxes[0].if_uuid), &BTFN_UUID, sizeof(p_uuid_t));
|
||||
p_cont_elem->transfer_syntaxes[0].if_version = BTFN_SYNTAX_IF_VERSION;
|
||||
|
||||
offset = 116;
|
||||
bind_pdu->auth_verifier.auth_pad_length = rpc_offset_align(&offset, 4);
|
||||
|
||||
bind_pdu->auth_verifier.auth_type = RPC_C_AUTHN_WINNT;
|
||||
bind_pdu->auth_verifier.auth_level = RPC_C_AUTHN_LEVEL_PKT_INTEGRITY;
|
||||
bind_pdu->auth_verifier.auth_reserved = 0x00;
|
||||
bind_pdu->auth_verifier.auth_context_id = 0x00000000;
|
||||
offset += (8 + bind_pdu->auth_length);
|
||||
|
||||
bind_pdu->frag_length = offset;
|
||||
|
||||
buffer = (BYTE*) malloc(bind_pdu->frag_length);
|
||||
|
||||
CopyMemory(buffer, bind_pdu, 24);
|
||||
CopyMemory(&buffer[24], &bind_pdu->p_context_elem, 4);
|
||||
CopyMemory(&buffer[28], &bind_pdu->p_context_elem.p_cont_elem[0], 24);
|
||||
CopyMemory(&buffer[52], bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes, 20);
|
||||
CopyMemory(&buffer[72], &bind_pdu->p_context_elem.p_cont_elem[1], 24);
|
||||
CopyMemory(&buffer[96], bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes, 20);
|
||||
|
||||
offset = 116;
|
||||
rpc_offset_pad(&offset, bind_pdu->auth_verifier.auth_pad_length);
|
||||
|
||||
CopyMemory(&buffer[offset], &bind_pdu->auth_verifier.auth_type, 8);
|
||||
CopyMemory(&buffer[offset + 8], bind_pdu->auth_verifier.auth_value, bind_pdu->auth_length);
|
||||
offset += (8 + bind_pdu->auth_length);
|
||||
|
||||
rpc_in_write(rpc, buffer, bind_pdu->frag_length);
|
||||
|
||||
free(bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes);
|
||||
free(bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes);
|
||||
free(bind_pdu->p_context_elem.p_cont_elem);
|
||||
free(bind_pdu);
|
||||
free(buffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum Transmit/Receive Fragment Size Negotiation
|
||||
*
|
||||
* The client determines, and then sends in the bind PDU, its desired maximum size for transmitting fragments,
|
||||
* and its desired maximum receive fragment size. Similarly, the server determines its desired maximum sizes
|
||||
* for transmitting and receiving fragments. Transmit and receive sizes may be different to help preserve buffering.
|
||||
* When the server receives the client’s values, it sets its operational transmit size to the minimum of the client’s
|
||||
* receive size (from the bind PDU) and its own desired transmit size. Then it sets its actual receive size to the
|
||||
* minimum of the client’s transmit size (from the bind) and its own desired receive size. The server then returns its
|
||||
* operational values in the bind_ack PDU. The client then sets its operational values from the received bind_ack PDU.
|
||||
* The received transmit size becomes the client’s receive size, and the received receive size becomes the client’s
|
||||
* transmit size. Either party may use receive buffers larger than negotiated — although this will not provide any
|
||||
* advantage — but may not transmit larger fragments than negotiated.
|
||||
*/
|
||||
|
||||
int rpc_recv_bind_ack_pdu(rdpRpc* rpc)
|
||||
{
|
||||
int status;
|
||||
BYTE* auth_data;
|
||||
rpcconn_hdr_t* header;
|
||||
|
||||
status = rpc_recv_pdu_fragment(rpc);
|
||||
|
||||
if (status > 0)
|
||||
{
|
||||
header = (rpcconn_hdr_t*) rpc->buffer;
|
||||
|
||||
rpc->max_recv_frag = header->bind_ack.max_xmit_frag;
|
||||
rpc->max_xmit_frag = header->bind_ack.max_recv_frag;
|
||||
|
||||
rpc->ntlm->inputBuffer.cbBuffer = header->common.auth_length;
|
||||
rpc->ntlm->inputBuffer.pvBuffer = malloc(header->common.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);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
BOOL rpc_send_rpc_auth_3_pdu(rdpRpc* rpc)
|
||||
{
|
||||
BYTE* buffer;
|
||||
UINT32 offset;
|
||||
rpcconn_rpc_auth_3_hdr_t* auth_3_pdu;
|
||||
|
||||
DEBUG_RPC("Sending auth_3 PDU");
|
||||
|
||||
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, (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;
|
||||
|
||||
auth_3_pdu->ptype = PTYPE_RPC_AUTH_3;
|
||||
auth_3_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_CONC_MPX;
|
||||
auth_3_pdu->call_id = 2;
|
||||
|
||||
offset = 20;
|
||||
|
||||
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);
|
||||
|
||||
auth_3_pdu->auth_verifier.auth_type = RPC_C_AUTHN_WINNT;
|
||||
auth_3_pdu->auth_verifier.auth_level = RPC_C_AUTHN_LEVEL_PKT_INTEGRITY;
|
||||
auth_3_pdu->auth_verifier.auth_reserved = 0x00;
|
||||
auth_3_pdu->auth_verifier.auth_context_id = 0x00000000;
|
||||
|
||||
auth_3_pdu->frag_length = 20 + 4 +
|
||||
auth_3_pdu->auth_verifier.auth_pad_length + auth_3_pdu->auth_length + 8;
|
||||
|
||||
buffer = (BYTE*) malloc(auth_3_pdu->frag_length);
|
||||
|
||||
CopyMemory(buffer, auth_3_pdu, 24);
|
||||
|
||||
offset = 24;
|
||||
rpc_offset_pad(&offset, auth_3_pdu->auth_verifier.auth_pad_length);
|
||||
|
||||
CopyMemory(&buffer[offset], &auth_3_pdu->auth_verifier.auth_type, 8);
|
||||
CopyMemory(&buffer[offset + 8], auth_3_pdu->auth_verifier.auth_value, auth_3_pdu->auth_length);
|
||||
offset += (8 + auth_3_pdu->auth_length);
|
||||
|
||||
rpc_in_write(rpc, buffer, auth_3_pdu->frag_length);
|
||||
|
||||
free(auth_3_pdu);
|
||||
free(buffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int rpc_recv_fault_pdu(rpcconn_hdr_t* header)
|
||||
{
|
||||
int index;
|
||||
|
||||
printf("RPC Fault PDU:\n");
|
||||
|
||||
for (index = 0; RPC_FAULT_CODES[index].name != NULL; index++)
|
||||
{
|
||||
if (RPC_FAULT_CODES[index].code == header->fault.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 == header->fault.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", header->fault.status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* PDU Structure with verification trailer
|
||||
*
|
||||
@@ -968,21 +605,11 @@ BOOL rpc_connect(rdpRpc* rpc)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!rpc_send_bind_pdu(rpc))
|
||||
{
|
||||
printf("rpc_send_bind_pdu error!\n");
|
||||
return FALSE;
|
||||
}
|
||||
rpc->State = RPC_CLIENT_STATE_ESTABLISHED;
|
||||
|
||||
if (rpc_recv_bind_ack_pdu(rpc) <= 0)
|
||||
if (rpc_secure_bind(rpc) != 0)
|
||||
{
|
||||
printf("rpc_recv_bind_ack_pdu error!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!rpc_send_rpc_auth_3_pdu(rpc))
|
||||
{
|
||||
printf("rpc_send_rpc_auth_3 error!\n");
|
||||
printf("rpc_secure_bind error!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -1072,6 +699,8 @@ rdpRpc* rpc_new(rdpTransport* transport)
|
||||
{
|
||||
ZeroMemory(rpc, sizeof(rdpRpc));
|
||||
|
||||
rpc->State = RPC_CLIENT_STATE_INITIAL;
|
||||
|
||||
rpc->transport = transport;
|
||||
rpc->settings = transport->settings;
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ typedef struct
|
||||
#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
|
||||
@@ -534,6 +535,39 @@ typedef union
|
||||
rpcconn_rts_hdr_t rts;
|
||||
} rpcconn_hdr_t;
|
||||
|
||||
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;
|
||||
|
||||
enum _TSG_CHANNEL
|
||||
{
|
||||
TSG_CHANNEL_IN,
|
||||
@@ -668,6 +702,8 @@ typedef struct _RPC_PDU_ENTRY
|
||||
|
||||
struct rdp_rpc
|
||||
{
|
||||
RPC_CLIENT_STATE State;
|
||||
|
||||
rdpTls* TlsIn;
|
||||
rdpTls* TlsOut;
|
||||
|
||||
|
||||
359
libfreerdp/core/gateway/rpc_bind.c
Normal file
359
libfreerdp/core/gateway/rpc_bind.c
Normal file
@@ -0,0 +1,359 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* RPC Secure Context Binding
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
|
||||
#include "rpc_bind.h"
|
||||
|
||||
/**
|
||||
* Connection-Oriented RPC Protocol Client Details:
|
||||
* http://msdn.microsoft.com/en-us/library/cc243724/
|
||||
*/
|
||||
|
||||
/* Syntax UUIDs */
|
||||
|
||||
const p_uuid_t TSGU_UUID =
|
||||
{
|
||||
0x44E265DD, /* time_low */
|
||||
0x7DAF, /* time_mid */
|
||||
0x42CD, /* time_hi_and_version */
|
||||
0x85, /* clock_seq_hi_and_reserved */
|
||||
0x60, /* clock_seq_low */
|
||||
{ 0x3C, 0xDB, 0x6E, 0x7A, 0x27, 0x29 } /* node[6] */
|
||||
};
|
||||
|
||||
#define TSGU_SYNTAX_IF_VERSION 0x00030001
|
||||
|
||||
const p_uuid_t NDR_UUID =
|
||||
{
|
||||
0x8A885D04, /* time_low */
|
||||
0x1CEB, /* time_mid */
|
||||
0x11C9, /* time_hi_and_version */
|
||||
0x9F, /* clock_seq_hi_and_reserved */
|
||||
0xE8, /* clock_seq_low */
|
||||
{ 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60 } /* node[6] */
|
||||
};
|
||||
|
||||
#define NDR_SYNTAX_IF_VERSION 0x00000002
|
||||
|
||||
const p_uuid_t BTFN_UUID =
|
||||
{
|
||||
0x6CB71C2C, /* time_low */
|
||||
0x9812, /* time_mid */
|
||||
0x4540, /* time_hi_and_version */
|
||||
0x03, /* clock_seq_hi_and_reserved */
|
||||
0x00, /* clock_seq_low */
|
||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } /* node[6] */
|
||||
};
|
||||
|
||||
#define BTFN_SYNTAX_IF_VERSION 0x00000001
|
||||
|
||||
/**
|
||||
* SECURE_BIND: RPC bind PDU with sec_trailer and auth_token. Auth_token is generated by calling
|
||||
* the implementation equivalent of the abstract GSS_Init_sec_context call. Upon receiving that, the
|
||||
* server calls the implementation equivalent of the abstract GSS_Accept_sec_context call, which
|
||||
* returns an auth_token and continue status in this example. Assume the following:
|
||||
*
|
||||
* 1) The client chooses the auth_context_id field in the sec_trailer sent with this PDU to be 1.
|
||||
*
|
||||
* 2) The client uses the RPC_C_AUTHN_LEVEL_PKT_PRIVACY authentication level and the
|
||||
* Authentication Service (AS) NTLM.
|
||||
*
|
||||
* 3) The client sets the PFC_SUPPORT_HEADER_SIGN flag in the PDU header.
|
||||
*/
|
||||
|
||||
int rpc_send_bind_pdu(rdpRpc* rpc)
|
||||
{
|
||||
BYTE* buffer;
|
||||
UINT32 offset;
|
||||
UINT32 length;
|
||||
p_cont_elem_t* p_cont_elem;
|
||||
rpcconn_bind_hdr_t* bind_pdu;
|
||||
rdpSettings* settings = rpc->settings;
|
||||
|
||||
rpc->ntlm = ntlm_new();
|
||||
|
||||
DEBUG_RPC("Sending bind PDU");
|
||||
|
||||
ntlm_client_init(rpc->ntlm, FALSE, settings->Username, settings->Domain, settings->Password);
|
||||
|
||||
ntlm_authenticate(rpc->ntlm);
|
||||
|
||||
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, (rpcconn_hdr_t*) bind_pdu);
|
||||
|
||||
bind_pdu->auth_length = rpc->ntlm->outputBuffer.cbBuffer;
|
||||
bind_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer.pvBuffer;
|
||||
|
||||
bind_pdu->ptype = PTYPE_BIND;
|
||||
bind_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_SUPPORT_HEADER_SIGN | PFC_CONC_MPX;
|
||||
bind_pdu->call_id = 2;
|
||||
|
||||
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;
|
||||
bind_pdu->p_context_elem.reserved = 0;
|
||||
bind_pdu->p_context_elem.reserved2 = 0;
|
||||
|
||||
bind_pdu->p_context_elem.p_cont_elem = malloc(sizeof(p_cont_elem_t) * bind_pdu->p_context_elem.n_context_elem);
|
||||
|
||||
p_cont_elem = &bind_pdu->p_context_elem.p_cont_elem[0];
|
||||
|
||||
p_cont_elem->p_cont_id = 0;
|
||||
p_cont_elem->n_transfer_syn = 1;
|
||||
p_cont_elem->reserved = 0;
|
||||
CopyMemory(&(p_cont_elem->abstract_syntax.if_uuid), &TSGU_UUID, sizeof(p_uuid_t));
|
||||
p_cont_elem->abstract_syntax.if_version = TSGU_SYNTAX_IF_VERSION;
|
||||
|
||||
p_cont_elem->transfer_syntaxes = malloc(sizeof(p_syntax_id_t));
|
||||
CopyMemory(&(p_cont_elem->transfer_syntaxes[0].if_uuid), &NDR_UUID, sizeof(p_uuid_t));
|
||||
p_cont_elem->transfer_syntaxes[0].if_version = NDR_SYNTAX_IF_VERSION;
|
||||
|
||||
p_cont_elem = &bind_pdu->p_context_elem.p_cont_elem[1];
|
||||
|
||||
p_cont_elem->p_cont_id = 1;
|
||||
p_cont_elem->n_transfer_syn = 1;
|
||||
p_cont_elem->reserved = 0;
|
||||
CopyMemory(&(p_cont_elem->abstract_syntax.if_uuid), &TSGU_UUID, sizeof(p_uuid_t));
|
||||
p_cont_elem->abstract_syntax.if_version = TSGU_SYNTAX_IF_VERSION;
|
||||
|
||||
p_cont_elem->transfer_syntaxes = malloc(sizeof(p_syntax_id_t));
|
||||
CopyMemory(&(p_cont_elem->transfer_syntaxes[0].if_uuid), &BTFN_UUID, sizeof(p_uuid_t));
|
||||
p_cont_elem->transfer_syntaxes[0].if_version = BTFN_SYNTAX_IF_VERSION;
|
||||
|
||||
offset = 116;
|
||||
bind_pdu->auth_verifier.auth_pad_length = rpc_offset_align(&offset, 4);
|
||||
|
||||
bind_pdu->auth_verifier.auth_type = RPC_C_AUTHN_WINNT;
|
||||
bind_pdu->auth_verifier.auth_level = RPC_C_AUTHN_LEVEL_PKT_INTEGRITY;
|
||||
bind_pdu->auth_verifier.auth_reserved = 0x00;
|
||||
bind_pdu->auth_verifier.auth_context_id = 0x00000000;
|
||||
offset += (8 + bind_pdu->auth_length);
|
||||
|
||||
bind_pdu->frag_length = offset;
|
||||
|
||||
buffer = (BYTE*) malloc(bind_pdu->frag_length);
|
||||
|
||||
CopyMemory(buffer, bind_pdu, 24);
|
||||
CopyMemory(&buffer[24], &bind_pdu->p_context_elem, 4);
|
||||
CopyMemory(&buffer[28], &bind_pdu->p_context_elem.p_cont_elem[0], 24);
|
||||
CopyMemory(&buffer[52], bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes, 20);
|
||||
CopyMemory(&buffer[72], &bind_pdu->p_context_elem.p_cont_elem[1], 24);
|
||||
CopyMemory(&buffer[96], bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes, 20);
|
||||
|
||||
offset = 116;
|
||||
rpc_offset_pad(&offset, bind_pdu->auth_verifier.auth_pad_length);
|
||||
|
||||
CopyMemory(&buffer[offset], &bind_pdu->auth_verifier.auth_type, 8);
|
||||
CopyMemory(&buffer[offset + 8], bind_pdu->auth_verifier.auth_value, bind_pdu->auth_length);
|
||||
offset += (8 + bind_pdu->auth_length);
|
||||
|
||||
rpc_in_write(rpc, buffer, bind_pdu->frag_length);
|
||||
length = bind_pdu->frag_length;
|
||||
|
||||
free(bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes);
|
||||
free(bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes);
|
||||
free(bind_pdu->p_context_elem.p_cont_elem);
|
||||
free(bind_pdu);
|
||||
free(buffer);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Maximum Transmit/Receive Fragment Size Negotiation
|
||||
*
|
||||
* The client determines, and then sends in the bind PDU, its desired maximum size for transmitting fragments,
|
||||
* and its desired maximum receive fragment size. Similarly, the server determines its desired maximum sizes
|
||||
* for transmitting and receiving fragments. Transmit and receive sizes may be different to help preserve buffering.
|
||||
* When the server receives the client’s values, it sets its operational transmit size to the minimum of the client’s
|
||||
* receive size (from the bind PDU) and its own desired transmit size. Then it sets its actual receive size to the
|
||||
* minimum of the client’s transmit size (from the bind) and its own desired receive size. The server then returns its
|
||||
* operational values in the bind_ack PDU. The client then sets its operational values from the received bind_ack PDU.
|
||||
* The received transmit size becomes the client’s receive size, and the received receive size becomes the client’s
|
||||
* transmit size. Either party may use receive buffers larger than negotiated — although this will not provide any
|
||||
* advantage — but may not transmit larger fragments than negotiated.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
* SECURE_BIND_ACK: RPC bind_ack PDU with sec_trailer and auth_token. The PFC_SUPPORT_HEADER_SIGN
|
||||
* flag in the PDU header is also set in this example. Auth_token is generated by the server in the
|
||||
* previous step. Upon receiving that PDU, the client calls the implementation equivalent of the
|
||||
* abstract GSS_Init_sec_context call, which returns an auth_token and continue status in this example.
|
||||
*/
|
||||
|
||||
int rpc_recv_bind_ack_pdu(rdpRpc* rpc)
|
||||
{
|
||||
int status;
|
||||
BYTE* auth_data;
|
||||
rpcconn_hdr_t* header;
|
||||
|
||||
status = rpc_recv_pdu_fragment(rpc);
|
||||
|
||||
if (status > 0)
|
||||
{
|
||||
header = (rpcconn_hdr_t*) rpc->buffer;
|
||||
|
||||
rpc->max_recv_frag = header->bind_ack.max_xmit_frag;
|
||||
rpc->max_xmit_frag = header->bind_ack.max_recv_frag;
|
||||
|
||||
rpc->ntlm->inputBuffer.cbBuffer = header->common.auth_length;
|
||||
rpc->ntlm->inputBuffer.pvBuffer = malloc(header->common.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);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* RPC_AUTH_3: The client knows that this is an NTLM that uses three legs. It sends an rpc_auth_3
|
||||
* PDU with the auth_token obtained in the previous step. Upon receiving this PDU, the server calls
|
||||
* the implementation equivalent of the abstract GSS_Accept_sec_context call, which returns success
|
||||
* status in this example.
|
||||
*/
|
||||
|
||||
int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc)
|
||||
{
|
||||
BYTE* buffer;
|
||||
UINT32 offset;
|
||||
UINT32 length;
|
||||
rpcconn_rpc_auth_3_hdr_t* auth_3_pdu;
|
||||
|
||||
DEBUG_RPC("Sending auth_3 PDU");
|
||||
|
||||
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, (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;
|
||||
|
||||
auth_3_pdu->ptype = PTYPE_RPC_AUTH_3;
|
||||
auth_3_pdu->pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG | PFC_CONC_MPX;
|
||||
auth_3_pdu->call_id = 2;
|
||||
|
||||
offset = 20;
|
||||
|
||||
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);
|
||||
|
||||
auth_3_pdu->auth_verifier.auth_type = RPC_C_AUTHN_WINNT;
|
||||
auth_3_pdu->auth_verifier.auth_level = RPC_C_AUTHN_LEVEL_PKT_INTEGRITY;
|
||||
auth_3_pdu->auth_verifier.auth_reserved = 0x00;
|
||||
auth_3_pdu->auth_verifier.auth_context_id = 0x00000000;
|
||||
|
||||
auth_3_pdu->frag_length = 20 + 4 +
|
||||
auth_3_pdu->auth_verifier.auth_pad_length + auth_3_pdu->auth_length + 8;
|
||||
|
||||
buffer = (BYTE*) malloc(auth_3_pdu->frag_length);
|
||||
|
||||
CopyMemory(buffer, auth_3_pdu, 24);
|
||||
|
||||
offset = 24;
|
||||
rpc_offset_pad(&offset, auth_3_pdu->auth_verifier.auth_pad_length);
|
||||
|
||||
CopyMemory(&buffer[offset], &auth_3_pdu->auth_verifier.auth_type, 8);
|
||||
CopyMemory(&buffer[offset + 8], auth_3_pdu->auth_verifier.auth_value, auth_3_pdu->auth_length);
|
||||
offset += (8 + auth_3_pdu->auth_length);
|
||||
|
||||
rpc_in_write(rpc, buffer, auth_3_pdu->frag_length);
|
||||
length = auth_3_pdu->frag_length;
|
||||
|
||||
free(auth_3_pdu);
|
||||
free(buffer);
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure Connection-Oriented RPC Packet Sequence
|
||||
*
|
||||
* Client Server
|
||||
* | |
|
||||
* |-------------------SECURE_BIND-------------------->|
|
||||
* | |
|
||||
* |<----------------SECURE_BIND_ACK-------------------|
|
||||
* | |
|
||||
* |--------------------RPC_AUTH_3-------------------->|
|
||||
* | |
|
||||
* | |
|
||||
* |------------------REQUEST_PDU_#1------------------>|
|
||||
* |------------------REQUEST_PDU_#2------------------>|
|
||||
* | |
|
||||
* | ... |
|
||||
* | |
|
||||
* |<-----------------RESPONSE_PDU_#1------------------|
|
||||
* |<-----------------RESPONSE_PDU_#2------------------|
|
||||
* | |
|
||||
* | ... |
|
||||
*/
|
||||
|
||||
int rpc_secure_bind(rdpRpc* rpc)
|
||||
{
|
||||
if (rpc->State != RPC_CLIENT_STATE_ESTABLISHED)
|
||||
{
|
||||
printf("rpc_secure_bind: invalid state, expected RPC_CLIENT_STATE_ESTABLISHED\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rpc_send_bind_pdu(rpc) <= 0)
|
||||
{
|
||||
printf("rpc_send_bind_pdu error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rpc->State = RPC_CLIENT_STATE_WAIT_SECURE_BIND_ACK;
|
||||
|
||||
if (rpc_recv_bind_ack_pdu(rpc) <= 0)
|
||||
{
|
||||
printf("rpc_recv_bind_ack_pdu error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rpc_send_rpc_auth_3_pdu(rpc) <= 0)
|
||||
{
|
||||
printf("rpc_send_rpc_auth_3 error!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rpc->State = RPC_CLIENT_STATE_CONTEXT_NEGOTIATED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
33
libfreerdp/core/gateway/rpc_bind.h
Normal file
33
libfreerdp/core/gateway/rpc_bind.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* RPC Secure Context Binding
|
||||
*
|
||||
* 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_CORE_RPC_BIND_H
|
||||
#define FREERDP_CORE_RPC_BIND_H
|
||||
|
||||
#include "rpc.h"
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
int rpc_send_bind_pdu(rdpRpc* rpc);
|
||||
int rpc_recv_bind_ack_pdu(rdpRpc* rpc);
|
||||
int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc);
|
||||
|
||||
int rpc_secure_bind(rdpRpc* rpc);
|
||||
|
||||
#endif /* FREERDP_CORE_RPC_BIND_H */
|
||||
200
libfreerdp/core/gateway/rpc_fault.c
Normal file
200
libfreerdp/core/gateway/rpc_fault.c
Normal file
@@ -0,0 +1,200 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* RPC Fault Handling
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "rpc_fault.h"
|
||||
|
||||
extern const RPC_FAULT_CODE RPC_TSG_FAULT_CODES[];
|
||||
|
||||
const RPC_FAULT_CODE RPC_FAULT_CODES[] =
|
||||
{
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_object_not_found)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_cancel)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_addr_error)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_context_mismatch)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_fp_div_zero)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_fp_error)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_fp_overflow)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_fp_underflow)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_ill_inst)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_int_div_by_zero)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_int_overflow)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_invalid_bound)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_invalid_tag)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_closed)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_comm_error)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_discipline)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_empty)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_memory)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_pipe_order)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_remote_no_memory)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_user_defined)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_tx_open_failed)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_codeset_conv_error)
|
||||
DEFINE_RPC_FAULT_CODE(nca_s_fault_no_client_stub)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_STRING_BINDING)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_WRONG_KIND_OF_BINDING)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_BINDING)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_PROTSEQ_NOT_SUPPORTED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_RPC_PROTSEQ)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_STRING_UUID)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_ENDPOINT_FORMAT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_NET_ADDR)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_ENDPOINT_FOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_TIMEOUT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_OBJECT_NOT_FOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ALREADY_REGISTERED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_TYPE_ALREADY_REGISTERED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ALREADY_LISTENING)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_PROTSEQS_REGISTERED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NOT_LISTENING)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_MGR_TYPE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_IF)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_BINDINGS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_PROTSEQS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_CANT_CREATE_ENDPOINT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_OUT_OF_RESOURCES)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_SERVER_UNAVAILABLE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_SERVER_TOO_BUSY)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_NETWORK_OPTIONS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_CALL_ACTIVE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_CALL_FAILED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_CALL_FAILED_DNE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_PROTOCOL_ERROR)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_PROXY_ACCESS_DENIED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNSUPPORTED_TRANS_SYN)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNSUPPORTED_TYPE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_TAG)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_BOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_ENTRY_NAME)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_NAME_SYNTAX)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNSUPPORTED_NAME_SYNTAX)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UUID_NO_ADDRESS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_DUPLICATE_ENDPOINT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_AUTHN_TYPE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_MAX_CALLS_TOO_SMALL)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_STRING_TOO_LONG)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_PROTSEQ_NOT_FOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_PROCNUM_OUT_OF_RANGE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_BINDING_HAS_NO_AUTH)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_AUTHN_SERVICE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_AUTHN_LEVEL)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_AUTH_IDENTITY)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_UNKNOWN_AUTHZ_SERVICE)
|
||||
DEFINE_RPC_FAULT_CODE(EPT_S_INVALID_ENTRY)
|
||||
DEFINE_RPC_FAULT_CODE(EPT_S_CANT_PERFORM_OP)
|
||||
DEFINE_RPC_FAULT_CODE(EPT_S_NOT_REGISTERED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NOTHING_TO_EXPORT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INCOMPLETE_NAME)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_VERS_OPTION)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_MORE_MEMBERS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NOT_ALL_OBJS_UNEXPORTED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INTERFACE_NOT_FOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ENTRY_ALREADY_EXISTS)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ENTRY_NOT_FOUND)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NAME_SERVICE_UNAVAILABLE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INVALID_NAF_ID)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_CANNOT_SUPPORT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_NO_CONTEXT_AVAILABLE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_INTERNAL_ERROR)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ZERO_DIVIDE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_ADDRESS_ERROR)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_FP_DIV_ZERO)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_FP_UNDERFLOW)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_S_FP_OVERFLOW)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_NO_MORE_ENTRIES)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_CHAR_TRANS_OPEN_FAIL)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_CHAR_TRANS_SHORT_FILE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_IN_NULL_CONTEXT)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_CONTEXT_DAMAGED)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_HANDLES_MISMATCH)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_SS_CANNOT_GET_CALL_HANDLE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_NULL_REF_POINTER)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_ENUM_VALUE_OUT_OF_RANGE)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_BYTE_COUNT_TOO_SMALL)
|
||||
DEFINE_RPC_FAULT_CODE(RPC_X_BAD_STUB_DATA)
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
const RPC_FAULT_CODE RPC_TSG_FAULT_CODES[] =
|
||||
{
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_SUCCESS)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_ACCESS_DENIED)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_ONLY_IF_CONNECTED)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_INVALID_PARAMETER)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_GRACEFUL_DISCONNECT)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_OPERATION_ABORTED)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_BAD_ARGUMENTS)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_INTERNALERROR)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_RAP_ACCESSDENIED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_NAP_ACCESSDENIED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_TS_CONNECTFAILED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_ALREADYDISCONNECTED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_QUARANTINE_ACCESSDENIED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_NOCERTAVAILABLE)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_COOKIE_BADPACKET)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_COOKIE_AUTHENTICATION_ACCESS_DENIED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_UNSUPPORTED_AUTHENTICATION_METHOD)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_CAPABILITYMISMATCH)
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_NOTSUPPORTED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_TS_CONNECTFAILED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_MAXCONNECTIONSREACHED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_INTERNALERROR))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_SESSIONTIMEOUT))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_REAUTH_AUTHN_FAILED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_REAUTH_CAP_FAILED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_REAUTH_RAP_FAILED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_SDR_NOT_SUPPORTED_BY_TS))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_REAUTH_NAP_FAILED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_CONNECTIONABORTED))
|
||||
DEFINE_RPC_FAULT_CODE(__HRESULT_FROM_WIN32(RPC_S_CALL_CANCELLED))
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
int rpc_recv_fault_pdu(rpcconn_hdr_t* header)
|
||||
{
|
||||
int index;
|
||||
|
||||
printf("RPC Fault PDU:\n");
|
||||
|
||||
for (index = 0; RPC_FAULT_CODES[index].name != NULL; index++)
|
||||
{
|
||||
if (RPC_FAULT_CODES[index].code == header->fault.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 == header->fault.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", header->fault.status);
|
||||
|
||||
return 0;
|
||||
}
|
||||
29
libfreerdp/core/gateway/rpc_fault.h
Normal file
29
libfreerdp/core/gateway/rpc_fault.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* FreeRDP: A Remote Desktop Protocol Implementation
|
||||
* RPC Fault Handling
|
||||
*
|
||||
* 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_CORE_RPC_FAULT_H
|
||||
#define FREERDP_CORE_RPC_FAULT_H
|
||||
|
||||
#include "rpc.h"
|
||||
|
||||
#include <winpr/wtypes.h>
|
||||
|
||||
int rpc_recv_fault_pdu(rpcconn_hdr_t* header);
|
||||
|
||||
#endif /* FREERDP_CORE_RPC_FAULT_H */
|
||||
@@ -43,41 +43,6 @@
|
||||
* RPC NDR Interface Reference: http://msdn.microsoft.com/en-us/library/windows/desktop/hh802752/
|
||||
*/
|
||||
|
||||
const RPC_FAULT_CODE RPC_TSG_FAULT_CODES[] =
|
||||
{
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_SUCCESS)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_ACCESS_DENIED)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_ONLY_IF_CONNECTED)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_INVALID_PARAMETER)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_GRACEFUL_DISCONNECT)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_OPERATION_ABORTED)
|
||||
DEFINE_RPC_FAULT_CODE(ERROR_BAD_ARGUMENTS)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_INTERNALERROR)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_RAP_ACCESSDENIED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_NAP_ACCESSDENIED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_TS_CONNECTFAILED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_ALREADYDISCONNECTED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_QUARANTINE_ACCESSDENIED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_NOCERTAVAILABLE)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_COOKIE_BADPACKET)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_COOKIE_AUTHENTICATION_ACCESS_DENIED)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_UNSUPPORTED_AUTHENTICATION_METHOD)
|
||||
DEFINE_RPC_FAULT_CODE(E_PROXY_CAPABILITYMISMATCH)
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_NOTSUPPORTED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_TS_CONNECTFAILED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_MAXCONNECTIONSREACHED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_INTERNALERROR))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_SESSIONTIMEOUT))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_REAUTH_AUTHN_FAILED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_REAUTH_CAP_FAILED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_REAUTH_RAP_FAILED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_SDR_NOT_SUPPORTED_BY_TS))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_REAUTH_NAP_FAILED))
|
||||
DEFINE_RPC_FAULT_CODE(HRESULT_CODE(E_PROXY_CONNECTIONABORTED))
|
||||
DEFINE_RPC_FAULT_CODE(__HRESULT_FROM_WIN32(RPC_S_CALL_CANCELLED))
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
/* this might be a verification trailer */
|
||||
|
||||
BYTE TsProxyCreateTunnelUnknownTrailerBytes[60] =
|
||||
|
||||
@@ -641,13 +641,14 @@ BOOL rdp_recv_out_of_sequence_pdu(rdpRdp* rdp, STREAM* s)
|
||||
|
||||
BOOL rdp_decrypt(rdpRdp* rdp, STREAM* s, int length, UINT16 securityFlags)
|
||||
{
|
||||
BYTE cmac[8], wmac[8];
|
||||
BYTE cmac[8];
|
||||
BYTE wmac[8];
|
||||
|
||||
if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
|
||||
{
|
||||
UINT16 len;
|
||||
BYTE version, pad;
|
||||
BYTE *sig;
|
||||
BYTE* sig;
|
||||
|
||||
stream_read_UINT16(s, len); /* 0x10 */
|
||||
stream_read_BYTE(s, version); /* 0x1 */
|
||||
@@ -725,7 +726,8 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
if (rdp->settings->DisableEncryption)
|
||||
{
|
||||
rdp_read_security_header(s, &securityFlags);
|
||||
if (securityFlags & (SEC_ENCRYPT|SEC_REDIRECTION_PKT))
|
||||
|
||||
if (securityFlags & (SEC_ENCRYPT | SEC_REDIRECTION_PKT))
|
||||
{
|
||||
if (!rdp_decrypt(rdp, s, length - 4, securityFlags))
|
||||
{
|
||||
@@ -733,6 +735,7 @@ static BOOL rdp_recv_tpkt_pdu(rdpRdp* rdp, STREAM* s)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (securityFlags & SEC_REDIRECTION_PKT)
|
||||
{
|
||||
/*
|
||||
@@ -797,7 +800,7 @@ static BOOL rdp_recv_fastpath_pdu(rdpRdp* rdp, STREAM* s)
|
||||
fastpath = rdp->fastpath;
|
||||
length = fastpath_read_header_rdp(fastpath, s);
|
||||
|
||||
if (length == 0 || length > stream_get_left(s))
|
||||
if ((length == 0) || (length > stream_get_left(s)))
|
||||
{
|
||||
printf("incorrect FastPath PDU header length %d\n", length);
|
||||
return FALSE;
|
||||
|
||||
@@ -265,6 +265,7 @@ void security_salted_mac_signature(rdpRdp *rdp, BYTE* data, UINT32 length, BOOL
|
||||
BYTE sha1_digest[CRYPTO_SHA1_DIGEST_LENGTH];
|
||||
|
||||
security_UINT32_le(length_le, length); /* length must be little-endian */
|
||||
|
||||
if (encryption)
|
||||
{
|
||||
security_UINT32_le(use_count_le, rdp->encrypt_checksum_use_count);
|
||||
@@ -273,8 +274,7 @@ void security_salted_mac_signature(rdpRdp *rdp, BYTE* data, UINT32 length, BOOL
|
||||
{
|
||||
/*
|
||||
* We calculate checksum on plain text, so we must have already
|
||||
* decrypt it, which means decrypt_checksum_use_count is
|
||||
* off by one.
|
||||
* decrypt it, which means decrypt_checksum_use_count is off by one.
|
||||
*/
|
||||
security_UINT32_le(use_count_le, rdp->decrypt_checksum_use_count - 1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user