void rpc_free(rdpRpc* rpc) { if (rpc != NULL) { rpc_client_stop(rpc); if (rpc->State >= RPC_CLIENT_STATE_CONTEXT_NEGOTIATED) { ntlm_client_uninit(rpc->ntlm); ntlm_free(rpc->ntlm); } rpc_client_virtual_connection_free(rpc->VirtualConnection); ArrayList_Clear(rpc->VirtualConnectionCookieTable); ArrayList_Free(rpc->VirtualConnectionCookieTable); free(rpc); } }
void rdg_free(rdpRdg* rdg) { if (!rdg) return; if (rdg->tlsOut) { tls_free(rdg->tlsOut); rdg->tlsOut = NULL; } if (rdg->tlsIn) { tls_free(rdg->tlsIn); rdg->tlsIn = NULL; } if (rdg->http) { http_context_free(rdg->http); rdg->http = NULL; } if (rdg->ntlm) { ntlm_free(rdg->ntlm); rdg->ntlm = NULL; } if (rdg->readEvent) { CloseHandle(rdg->readEvent); rdg->readEvent = NULL; } DeleteCriticalSection(&rdg->writeSection); free(rdg); }
void rpc_free(rdpRpc* rpc) { if (rpc) { rpc_client_free(rpc); if (rpc->ntlm) { ntlm_client_uninit(rpc->ntlm); ntlm_free(rpc->ntlm); rpc->ntlm = NULL; } if (rpc->VirtualConnection) { rpc_virtual_connection_free(rpc->VirtualConnection); rpc->VirtualConnection = NULL; } free(rpc); } }
BOOL rpc_ntlm_http_out_connect(rdpRpc* rpc) { rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm; rpc_ncacn_http_ntlm_init(rpc, TSG_CHANNEL_OUT); /* Send OUT Channel Request */ rpc_ncacn_http_send_out_channel_request(rpc); /* Receive OUT Channel Response */ rpc_ncacn_http_recv_out_channel_response(rpc); /* Send OUT Channel Request */ rpc_ncacn_http_send_out_channel_request(rpc); ntlm_client_uninit(ntlm); ntlm_free(ntlm); return TRUE; }
void rdg_free(rdpRdg* rdg) { if (!rdg) return; if (rdg->tlsOut) { tls_free(rdg->tlsOut); rdg->tlsOut = NULL; } if (rdg->tlsIn) { tls_free(rdg->tlsIn); rdg->tlsIn = NULL; } if (rdg->http) { http_context_free(rdg->http); rdg->http = NULL; } if (rdg->ntlm) { ntlm_free(rdg->ntlm); rdg->ntlm = NULL; } if (rdg->readEvent) { CloseHandle(rdg->readEvent); rdg->readEvent = NULL; } free(rdg); }
static BOOL rdg_establish_data_connection(rdpRdg* rdg, rdpTls* tls, const char* method, const char* peerAddress, int timeout, BOOL* rpcFallback) { HttpResponse* response = NULL; int statusCode; int bodyLength; if (!rdg_tls_connect(rdg, tls, peerAddress, timeout)) return FALSE; if (rdg->extAuth == HTTP_EXTENDED_AUTH_NONE) { if (!rdg_ntlm_init(rdg, tls)) return FALSE; if (!rdg_send_http_request(rdg, tls, method, NULL)) return FALSE; response = http_response_recv(tls); if (!response) return FALSE; if (response->StatusCode == HTTP_STATUS_NOT_FOUND) { WLog_INFO(TAG, "RD Gateway does not support HTTP transport."); if (rpcFallback) *rpcFallback = TRUE; http_response_free(response); return FALSE; } if (!rdg_handle_ntlm_challenge(rdg->ntlm, response)) { http_response_free(response); return FALSE; } http_response_free(response); } if (!rdg_send_http_request(rdg, tls, method, NULL)) return FALSE; ntlm_free(rdg->ntlm); rdg->ntlm = NULL; response = http_response_recv(tls); if (!response) return FALSE; statusCode = response->StatusCode; bodyLength = response->BodyLength; http_response_free(response); WLog_DBG(TAG, "%s authorization result: %d", method, statusCode); if (statusCode != HTTP_STATUS_OK) return FALSE; if (strcmp(method, "RDG_OUT_DATA") == 0) { if (!rdg_skip_seed_payload(tls, bodyLength)) return FALSE; } else { if (!rdg_send_http_request(rdg, tls, method, "chunked")) return FALSE; } return TRUE; }
int rpc_send_bind_pdu(rdpRpc* rpc) { int status; BYTE* buffer; UINT32 offset; UINT32 length; RpcClientCall* clientCall; p_cont_elem_t* p_cont_elem; rpcconn_bind_hdr_t* bind_pdu; BOOL promptPassword = FALSE; rdpSettings* settings = rpc->settings; freerdp* instance = (freerdp*) settings->instance; RpcVirtualConnection* connection = rpc->VirtualConnection; RpcInChannel* inChannel = connection->DefaultInChannel; WLog_DBG(TAG, "Sending Bind PDU"); ntlm_free(rpc->ntlm); 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) { 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)) return -1; if (!ntlm_client_make_spn(rpc->ntlm, NULL, settings->GatewayHostname)) return -1; if (!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 = calloc(bind_pdu->p_context_elem.n_context_elem, sizeof(p_cont_elem_t)); 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)); if (!p_cont_elem->transfer_syntaxes) return -1; 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)); if (!p_cont_elem->transfer_syntaxes) return -1; 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) { free(buffer); return -1; } if (ArrayList_Add(rpc->client->ClientCallList, clientCall) < 0) { free(buffer); return -1; } status = rpc_in_channel_send_pdu(inChannel, buffer, 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 (status > 0) ? 1 : -1; }
void rpc_ncacn_http_ntlm_uninit(rdpRpc* rpc, RpcChannel* channel) { ntlm_client_uninit(channel->ntlm); ntlm_free(channel->ntlm); channel->ntlm = NULL; }
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; }