boolean rpc_ntlm_http_in_connect(rdpRpc* rpc) { STREAM* s; int ntlm_token_length; uint8* ntlm_token_data; HttpResponse* http_response; rdpNtlm* ntlm = rpc->ntlm_http_in->ntlm; ntlm_client_init(ntlm, true, rpc->settings->username, rpc->settings->domain, rpc->settings->password); ntlm_authenticate(ntlm); s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 0, TSG_CHANNEL_IN); /* Send IN Channel Request */ DEBUG_RPC("\n%s", s->data); tls_write_all(rpc->tls_in, s->data, s->size); stream_free(s); /* Receive IN Channel Response */ http_response = http_response_recv(rpc->tls_in); ntlm_token_data = NULL; crypto_base64_decode((uint8*) http_response->AuthParam, strlen(http_response->AuthParam), &ntlm_token_data, &ntlm_token_length); ntlm->inputBuffer.pvBuffer = ntlm_token_data; ntlm->inputBuffer.cbBuffer = ntlm_token_length; ntlm_authenticate(ntlm); http_response_free(http_response); s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 0x40000000, TSG_CHANNEL_IN); /* Send IN Channel Request */ DEBUG_RPC("\n%s", s->data); tls_write_all(rpc->tls_in, s->data, s->size); stream_free(s); ntlm_client_uninit(ntlm); ntlm_free(ntlm); return true; }
BOOL rts_send_ping_pdu(rdpRpc* rpc) { STREAM* s; RTS_PDU_HEADER header; header.rpc_vers = 5; header.rpc_vers_minor = 0; header.ptype = PTYPE_RTS; header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG; header.packed_drep[0] = 0x10; header.packed_drep[1] = 0x00; header.packed_drep[2] = 0x00; header.packed_drep[3] = 0x00; header.frag_length = 20; header.auth_length = 0; header.call_id = 0; header.flags = 1; header.numberOfCommands = 0; DEBUG_RPC("Sending Ping RTS PDU"); s = stream_new(header.frag_length); rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ stream_seal(s); rpc_in_write(rpc, s->data, s->size); stream_free(s); return TRUE; }
boolean rts_send_keep_alive_pdu(rdpRpc* rpc) { STREAM* s; RTS_PDU_HEADER header; header.rpc_vers = 5; header.rpc_vers_minor = 0; header.ptype = PTYPE_RTS; header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG; header.packed_drep[0] = 0x10; header.packed_drep[1] = 0x00; header.packed_drep[2] = 0x00; header.packed_drep[3] = 0x00; header.frag_length = 28; header.auth_length = 0; header.call_id = 0; header.flags = 2; header.numberOfCommands = 1; DEBUG_RPC("Sending Keep-Alive RTS PDU"); s = stream_new(header.frag_length); rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ rts_client_keepalive_command_write(s, 0x00007530); /* ClientKeepalive (8 bytes) */ stream_seal(s); rpc_in_write(rpc, s->data, s->size); stream_free(s); return true; }
int rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) { BYTE* buffer; UINT32 offset; UINT32 length; RpcClientCall* clientCall; rpcconn_rpc_auth_3_hdr_t* auth_3_pdu; DEBUG_RPC("Sending rpc_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 = (UINT16) rpc->ntlm->outputBuffer[0].cbBuffer; auth_3_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer[0].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; auth_3_pdu->max_xmit_frag = rpc->max_xmit_frag; auth_3_pdu->max_recv_frag = rpc->max_recv_frag; offset = 20; 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; offset += (8 + auth_3_pdu->auth_length); auth_3_pdu->frag_length = offset; buffer = (BYTE*) malloc(auth_3_pdu->frag_length); CopyMemory(buffer, auth_3_pdu, 20); offset = 20; 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); length = auth_3_pdu->frag_length; clientCall = rpc_client_call_new(auth_3_pdu->call_id, 0); ArrayList_Add(rpc->client->ClientCallList, clientCall); if (rpc_send_enqueue_pdu(rpc, buffer, length) != 0) length = -1; free(auth_3_pdu); return length; }
boolean rpc_send_rpc_auth_3_pdu(rdpRpc* rpc) { STREAM* pdu; STREAM* s = stream_new(0); rpcconn_rpc_auth_3_hdr_t* rpc_auth_3_pdu; DEBUG_RPC("Sending auth_3 PDU"); s->size = rpc->ntlm->outputBuffer.cbBuffer; 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->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; rpc_auth_3_pdu->packed_drep[2] = 0x00; rpc_auth_3_pdu->packed_drep[3] = 0x00; rpc_auth_3_pdu->frag_length = 28 + s->size; rpc_auth_3_pdu->auth_length = s->size; rpc_auth_3_pdu->call_id = 2; 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 = xmalloc(rpc_auth_3_pdu->auth_length); /* credentials; size_is(auth_length) p */ memcpy(rpc_auth_3_pdu->auth_verifier.auth_value, s->data, rpc_auth_3_pdu->auth_length); stream_free(s); pdu = stream_new(rpc_auth_3_pdu->frag_length); stream_write(pdu, rpc_auth_3_pdu, 20); if (rpc_auth_3_pdu->auth_verifier.auth_pad_length > 0) stream_write(pdu, rpc_auth_3_pdu->auth_verifier.auth_pad, rpc_auth_3_pdu->auth_verifier.auth_pad_length); stream_write(pdu, &rpc_auth_3_pdu->auth_verifier.auth_type, 8); stream_write(pdu, rpc_auth_3_pdu->auth_verifier.auth_value, rpc_auth_3_pdu->auth_length); rpc_in_write(rpc, pdu->data, stream_get_length(pdu)); stream_free(pdu) ; xfree(rpc_auth_3_pdu); return true; }
BOOL rts_send_CONN_B1_pdu(rdpRpc* rpc) { STREAM* s; RTS_PDU_HEADER header; BYTE* INChannelCookie; BYTE* AssociationGroupId; BYTE* VirtualConnectionCookie; header.rpc_vers = 5; header.rpc_vers_minor = 0; header.ptype = PTYPE_RTS; header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG; header.packed_drep[0] = 0x10; header.packed_drep[1] = 0x00; header.packed_drep[2] = 0x00; header.packed_drep[3] = 0x00; header.frag_length = 104; header.auth_length = 0; header.call_id = 0; header.flags = 0; header.numberOfCommands = 6; DEBUG_RPC("Sending CONN_B1 RTS PDU"); s = stream_new(header.frag_length); rpc_generate_cookie((BYTE*) &(rpc->VirtualConnection->DefaultInChannelCookie)); rpc_generate_cookie((BYTE*) &(rpc->VirtualConnection->AssociationGroupId)); VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie); INChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultInChannelCookie); AssociationGroupId = (BYTE*) &(rpc->VirtualConnection->AssociationGroupId); rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ rts_version_command_write(s); /* Version (8 bytes) */ rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ rts_cookie_command_write(s, INChannelCookie); /* INChannelCookie (20 bytes) */ rts_channel_lifetime_command_write(s, 0x40000000); /* ChannelLifetime (8 bytes) */ rts_client_keepalive_command_write(s, 0x000493E0); /* ClientKeepalive (8 bytes) */ rts_association_group_id_command_write(s, AssociationGroupId); /* AssociationGroupId (20 bytes) */ stream_seal(s); rpc_in_write(rpc, s->data, s->size); stream_free(s); return TRUE; }
BOOL rts_send_CONN_A1_pdu(rdpRpc* rpc) { STREAM* s; RTS_PDU_HEADER header; UINT32 ReceiveWindowSize; BYTE* OUTChannelCookie; BYTE* VirtualConnectionCookie; header.rpc_vers = 5; header.rpc_vers_minor = 0; header.ptype = PTYPE_RTS; header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG; header.packed_drep[0] = 0x10; header.packed_drep[1] = 0x00; header.packed_drep[2] = 0x00; header.packed_drep[3] = 0x00; header.frag_length = 76; header.auth_length = 0; header.call_id = 0; header.flags = 0; header.numberOfCommands = 4; DEBUG_RPC("Sending CONN_A1 RTS PDU"); s = stream_new(header.frag_length); rpc_generate_cookie((BYTE*) &(rpc->VirtualConnection->Cookie)); rpc_generate_cookie((BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie)); VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie); OUTChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie); ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow; rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ rts_version_command_write(s); /* Version (8 bytes) */ rts_cookie_command_write(s, VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ rts_cookie_command_write(s, OUTChannelCookie); /* OUTChannelCookie (20 bytes) */ rts_receive_window_size_command_write(s, ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */ stream_seal(s); rpc_out_write(rpc, s->data, s->size); stream_free(s); return TRUE; }
int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc) { wStream* s; int content_length; BOOL continue_needed; rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm; continue_needed = ntlm_authenticate(ntlm); content_length = (continue_needed) ? 0 : 0x40000000; s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, content_length, TSG_CHANNEL_IN); DEBUG_RPC("\n%s", Stream_Buffer(s)); rpc_in_write(rpc, Stream_Buffer(s), Stream_Length(s)); Stream_Free(s, TRUE); return 0; }
BOOL rts_send_flow_control_ack_pdu(rdpRpc* rpc) { STREAM* s; RTS_PDU_HEADER header; UINT32 BytesReceived; UINT32 AvailableWindow; BYTE* ChannelCookie; header.rpc_vers = 5; header.rpc_vers_minor = 0; header.ptype = PTYPE_RTS; header.pfc_flags = PFC_FIRST_FRAG | PFC_LAST_FRAG; header.packed_drep[0] = 0x10; header.packed_drep[1] = 0x00; header.packed_drep[2] = 0x00; header.packed_drep[3] = 0x00; header.frag_length = 56; header.auth_length = 0; header.call_id = 0; header.flags = 2; header.numberOfCommands = 2; DEBUG_RPC("Sending FlowControlAck RTS PDU"); BytesReceived = rpc->VirtualConnection->DefaultOutChannel->BytesReceived; AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow; ChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie); s = stream_new(header.frag_length); rts_pdu_header_write(s, &header); /* RTS Header (20 bytes) */ rts_destination_command_write(s, FDOutProxy); /* Destination Command (8 bytes) */ /* FlowControlAck Command (28 bytes) */ rts_flow_control_ack_command_write(s, BytesReceived, AvailableWindow, ChannelCookie); stream_seal(s); rpc_in_write(rpc, s->data, s->size); stream_free(s); return TRUE; }
int rpc_ncacn_http_send_in_channel_request(rdpRpc* rpc) { STREAM* s; int content_length; BOOL continue_needed; rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm; continue_needed = ntlm_authenticate(ntlm); content_length = (continue_needed) ? 0 : 0x40000000; s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, content_length, TSG_CHANNEL_IN); DEBUG_RPC("\n%s", s->data); rpc_in_write(rpc, s->data, s->size); stream_free(s); return 0; }
int rts_send_CONN_B1_pdu(rdpRpc* rpc) { BYTE* buffer; UINT32 length; rpcconn_rts_hdr_t header; BYTE* INChannelCookie; BYTE* AssociationGroupId; BYTE* VirtualConnectionCookie; rts_pdu_header_init(&header); header.frag_length = 104; header.Flags = RTS_FLAG_NONE; header.NumberOfCommands = 6; DEBUG_RPC("Sending CONN_B1 RTS PDU"); rts_generate_cookie((BYTE*) &(rpc->VirtualConnection->DefaultInChannelCookie)); rts_generate_cookie((BYTE*) &(rpc->VirtualConnection->AssociationGroupId)); VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie); INChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultInChannelCookie); AssociationGroupId = (BYTE*) &(rpc->VirtualConnection->AssociationGroupId); buffer = (BYTE*) malloc(header.frag_length); CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */ rts_version_command_write(&buffer[20]); /* Version (8 bytes) */ rts_cookie_command_write(&buffer[28], VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ rts_cookie_command_write(&buffer[48], INChannelCookie); /* INChannelCookie (20 bytes) */ rts_channel_lifetime_command_write(&buffer[68], rpc->ChannelLifetime); /* ChannelLifetime (8 bytes) */ rts_client_keepalive_command_write(&buffer[76], rpc->KeepAliveInterval); /* ClientKeepalive (8 bytes) */ rts_association_group_id_command_write(&buffer[84], AssociationGroupId); /* AssociationGroupId (20 bytes) */ length = header.frag_length; rpc_in_write(rpc, buffer, length); free(buffer); return 0; }
int rts_send_flow_control_ack_pdu(rdpRpc* rpc) { BYTE* buffer; UINT32 length; rpcconn_rts_hdr_t header; UINT32 BytesReceived; UINT32 AvailableWindow; BYTE* ChannelCookie; rts_pdu_header_init(&header); header.frag_length = 56; header.Flags = RTS_FLAG_OTHER_CMD; header.NumberOfCommands = 2; DEBUG_RPC("Sending FlowControlAck RTS PDU"); BytesReceived = rpc->VirtualConnection->DefaultOutChannel->BytesReceived; AvailableWindow = rpc->VirtualConnection->DefaultOutChannel->AvailableWindowAdvertised; ChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie); rpc->VirtualConnection->DefaultOutChannel->ReceiverAvailableWindow = rpc->VirtualConnection->DefaultOutChannel->AvailableWindowAdvertised; buffer = (BYTE*) malloc(header.frag_length); CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */ rts_destination_command_write(&buffer[20], FDOutProxy); /* Destination Command (8 bytes) */ /* FlowControlAck Command (28 bytes) */ rts_flow_control_ack_command_write(&buffer[28], BytesReceived, AvailableWindow, ChannelCookie); length = header.frag_length; rpc_in_write(rpc, buffer, length); free(buffer); return 0; }
int rts_send_ping_pdu(rdpRpc* rpc) { BYTE* buffer; UINT32 length; rpcconn_rts_hdr_t header; rts_pdu_header_init(&header); header.frag_length = 20; header.Flags = RTS_FLAG_PING; header.NumberOfCommands = 0; DEBUG_RPC("Sending Ping RTS PDU"); buffer = (BYTE*) malloc(header.frag_length); CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */ length = header.frag_length; rpc_in_write(rpc, buffer, length); free(buffer); return length; }
int rts_send_keep_alive_pdu(rdpRpc* rpc) { BYTE* buffer; UINT32 length; rpcconn_rts_hdr_t header; rts_pdu_header_init(&header); header.frag_length = 28; header.Flags = RTS_FLAG_OTHER_CMD; header.NumberOfCommands = 1; DEBUG_RPC("Sending Keep-Alive RTS PDU"); buffer = (BYTE*) malloc(header.frag_length); CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */ rts_client_keepalive_command_write(&buffer[20], rpc->CurrentKeepAliveInterval); /* ClientKeepAlive (8 bytes) */ length = header.frag_length; rpc_in_write(rpc, buffer, length); free(buffer); return length; }
int rts_send_CONN_A1_pdu(rdpRpc* rpc) { BYTE* buffer; rpcconn_rts_hdr_t header; UINT32 ReceiveWindowSize; BYTE* OUTChannelCookie; BYTE* VirtualConnectionCookie; rts_pdu_header_init(&header); header.frag_length = 76; header.Flags = RTS_FLAG_NONE; header.NumberOfCommands = 4; DEBUG_RPC("Sending CONN_A1 RTS PDU"); rts_generate_cookie((BYTE*) &(rpc->VirtualConnection->Cookie)); rts_generate_cookie((BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie)); VirtualConnectionCookie = (BYTE*) &(rpc->VirtualConnection->Cookie); OUTChannelCookie = (BYTE*) &(rpc->VirtualConnection->DefaultOutChannelCookie); ReceiveWindowSize = rpc->VirtualConnection->DefaultOutChannel->ReceiveWindow; buffer = (BYTE*) malloc(header.frag_length); CopyMemory(buffer, ((BYTE*) &header), 20); /* RTS Header (20 bytes) */ rts_version_command_write(&buffer[20]); /* Version (8 bytes) */ rts_cookie_command_write(&buffer[28], VirtualConnectionCookie); /* VirtualConnectionCookie (20 bytes) */ rts_cookie_command_write(&buffer[48], OUTChannelCookie); /* OUTChannelCookie (20 bytes) */ rts_receive_window_size_command_write(&buffer[68], ReceiveWindowSize); /* ReceiveWindowSize (8 bytes) */ rpc_out_write(rpc, buffer, header.frag_length); free(buffer); return 0; }
boolean rpc_send_bind_pdu(rdpRpc* rpc) { STREAM* pdu; rpcconn_bind_hdr_t* bind_pdu; rdpSettings* settings = rpc->settings; STREAM* ntlm_stream = stream_new(0xFFFF); 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); ntlm_stream->size = rpc->ntlm->outputBuffer.cbBuffer; 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->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; bind_pdu->packed_drep[2] = 0x00; bind_pdu->packed_drep[3] = 0x00; 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; bind_pdu->p_context_elem.p_cont_elem = xmalloc(sizeof(p_cont_elem_t) * bind_pdu->p_context_elem.n_context_elem); 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.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[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 = xmalloc(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.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[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; bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes[0].if_version = 0x00000002; 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.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[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 = xmalloc(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_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; bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.clock_seq_low = 0x00; bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[0] = 0x00; bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[1] = 0x00; bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[2] = 0x00; bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes[0].if_uuid.node[3] = 0x00; 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 = xmalloc(bind_pdu->auth_length); /* credentials; size_is(auth_length) p*/; memcpy(bind_pdu->auth_verifier.auth_value, ntlm_stream->data, bind_pdu->auth_length); stream_free(ntlm_stream); pdu = stream_new(bind_pdu->frag_length); stream_write(pdu, bind_pdu, 24); stream_write(pdu, &bind_pdu->p_context_elem, 4); stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem, 24); stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem[0].transfer_syntaxes, 20); stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem + 1, 24); stream_write(pdu, bind_pdu->p_context_elem.p_cont_elem[1].transfer_syntaxes, 20); if (bind_pdu->auth_verifier.auth_pad_length > 0) stream_write(pdu, bind_pdu->auth_verifier.auth_pad, bind_pdu->auth_verifier.auth_pad_length); stream_write(pdu, &bind_pdu->auth_verifier.auth_type, 8); /* assumed that uint8 pointer is 32bit long (4 bytes) */ stream_write(pdu, bind_pdu->auth_verifier.auth_value, bind_pdu->auth_length); stream_seal(pdu); rpc_in_write(rpc, pdu->data, pdu->size); stream_free(pdu) ; xfree(bind_pdu); return true; }
int rpc_send_bind_pdu(rdpRpc* rpc) { BYTE* buffer; UINT32 offset; UINT32 length; RpcClientCall* clientCall; p_cont_elem_t* p_cont_elem; rpcconn_bind_hdr_t* bind_pdu; rdpSettings* settings = rpc->settings; BOOL promptPassword = FALSE; freerdp* instance = (freerdp*) settings->instance; DEBUG_RPC("Sending bind PDU"); rpc->ntlm = ntlm_new(); if (!rpc->ntlm) return -1; if ((!settings->GatewayPassword) || (!settings->GatewayUsername) || (!strlen(settings->GatewayPassword)) || (!strlen(settings->GatewayUsername))) { promptPassword = TRUE; } if (promptPassword) { if (instance->GatewayAuthenticate) { BOOL proceed = instance->GatewayAuthenticate(instance, &settings->GatewayUsername, &settings->GatewayPassword, &settings->GatewayDomain); if (!proceed) { connectErrorCode = CANCELEDBYUSER; freerdp_set_last_error(instance->context, FREERDP_ERROR_CONNECT_CANCELLED); return 0; } if (settings->GatewayUseSameCredentials) { settings->Username = _strdup(settings->GatewayUsername); settings->Domain = _strdup(settings->GatewayDomain); settings->Password = _strdup(settings->GatewayPassword); if (!settings->Username || !settings->Domain || settings->Password) return -1; } } } if (!ntlm_client_init(rpc->ntlm, FALSE, settings->GatewayUsername, settings->GatewayDomain, settings->GatewayPassword, NULL) || !ntlm_client_make_spn(rpc->ntlm, NULL, settings->GatewayHostname) || !ntlm_authenticate(rpc->ntlm) ) return -1; bind_pdu = (rpcconn_bind_hdr_t*) calloc(1, sizeof(rpcconn_bind_hdr_t)); if (!bind_pdu) return -1; rpc_pdu_header_init(rpc, (rpcconn_hdr_t*) bind_pdu); bind_pdu->auth_length = (UINT16) rpc->ntlm->outputBuffer[0].cbBuffer; bind_pdu->auth_verifier.auth_value = rpc->ntlm->outputBuffer[0].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); if (!bind_pdu->p_context_elem.p_cont_elem) return -1; 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); if (!buffer) return -1; 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); length = bind_pdu->frag_length; clientCall = rpc_client_call_new(bind_pdu->call_id, 0); if (!clientCall) return -1; if (ArrayList_Add(rpc->client->ClientCallList, clientCall) < 0) return -1; if (rpc_send_enqueue_pdu(rpc, buffer, length) != 0) length = -1; 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); return length; }
BOOL rpc_ntlm_http_in_connect(rdpRpc* rpc) { STREAM* s; rdpSettings* settings; int ntlm_token_length; BYTE* ntlm_token_data; HttpResponse* http_response; rdpNtlm* ntlm = rpc->ntlm_http_in->ntlm; settings = rpc->settings; if (settings->tsg_same_credentials) { ntlm_client_init(ntlm, TRUE, settings->username, settings->domain, settings->password); ntlm_client_make_spn(ntlm, _T("HTTP"), settings->tsg_hostname); } else { ntlm_client_init(ntlm, TRUE, settings->tsg_username, settings->tsg_domain, settings->tsg_password); ntlm_client_make_spn(ntlm, _T("HTTP"), settings->tsg_hostname); } ntlm_authenticate(ntlm); s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 0, TSG_CHANNEL_IN); /* Send IN Channel Request */ DEBUG_RPC("\n%s", s->data); tls_write_all(rpc->tls_in, s->data, s->size); stream_free(s); /* Receive IN Channel Response */ http_response = http_response_recv(rpc->tls_in); ntlm_token_data = NULL; crypto_base64_decode((BYTE*) http_response->AuthParam, strlen(http_response->AuthParam), &ntlm_token_data, &ntlm_token_length); ntlm->inputBuffer.pvBuffer = ntlm_token_data; ntlm->inputBuffer.cbBuffer = ntlm_token_length; ntlm_authenticate(ntlm); http_response_free(http_response); s = rpc_ntlm_http_request(rpc, &ntlm->outputBuffer, 0x40000000, TSG_CHANNEL_IN); /* Send IN Channel Request */ DEBUG_RPC("\n%s", s->data); tls_write_all(rpc->tls_in, s->data, s->size); stream_free(s); ntlm_client_uninit(ntlm); ntlm_free(ntlm); return TRUE; }