static BOOL rdg_handle_ntlm_challenge(rdpNtlm* ntlm, HttpResponse* response) { char* token64 = NULL; int ntlmTokenLength = 0; BYTE* ntlmTokenData = NULL; if (response->StatusCode != HTTP_STATUS_DENIED) { WLog_DBG(TAG, "Unexpected NTLM challenge HTTP status: %d", response->StatusCode); return FALSE; } token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM"); if (!token64) return FALSE; crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength); if (ntlmTokenData && ntlmTokenLength) { ntlm->inputBuffer[0].pvBuffer = ntlmTokenData; ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength; } ntlm_authenticate(ntlm); return TRUE; }
int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc) { char* token64; int ntlm_token_length = 0; BYTE* ntlm_token_data = NULL; HttpResponse* http_response; rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm; http_response = http_response_recv(rpc->TlsIn); if (!http_response) return -1; if (ListDictionary_Contains(http_response->Authenticates, "NTLM")) { token64 = ListDictionary_GetItemValue(http_response->Authenticates, "NTLM"); if (!token64) goto out; crypto_base64_decode(token64, strlen(token64), &ntlm_token_data, &ntlm_token_length); } out: ntlm->inputBuffer[0].pvBuffer = ntlm_token_data; ntlm->inputBuffer[0].cbBuffer = ntlm_token_length; http_response_free(http_response); return 0; }
int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc, HttpResponse* response) { char* token64 = NULL; int ntlmTokenLength = 0; BYTE* ntlmTokenData = NULL; rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm; if (ListDictionary_Contains(response->Authenticates, "NTLM")) { token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM"); if (!token64) return -1; crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength); } if (ntlmTokenData && ntlmTokenLength) { ntlm->inputBuffer[0].pvBuffer = ntlmTokenData; ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength; } return 1; }
BOOL rdg_process_out_channel_response(rdpRdg* rdg, HttpResponse* response) { int status; wStream* s; char* token64 = NULL; int ntlmTokenLength = 0; BYTE* ntlmTokenData = NULL; rdpNtlm* ntlm = rdg->ntlm; if (response->StatusCode != HTTP_STATUS_DENIED) { WLog_DBG(TAG, "RDG not supported"); rdg->state = RDG_CLIENT_STATE_NOT_FOUND; return FALSE; } WLog_DBG(TAG, "Out Channel authorization required"); if (ListDictionary_Contains(response->Authenticates, "NTLM")) { token64 = ListDictionary_GetItemValue(response->Authenticates, "NTLM"); if (!token64) { return FALSE; } crypto_base64_decode(token64, strlen(token64), &ntlmTokenData, &ntlmTokenLength); } if (ntlmTokenData && ntlmTokenLength) { ntlm->inputBuffer[0].pvBuffer = ntlmTokenData; ntlm->inputBuffer[0].cbBuffer = ntlmTokenLength; } ntlm_authenticate(ntlm); s = rdg_build_http_request(rdg, "RDG_OUT_DATA"); if (!s) return FALSE; status = tls_write_all(rdg->tlsOut, Stream_Buffer(s), Stream_Length(s)); Stream_Free(s, TRUE); ntlm_free(rdg->ntlm); rdg->ntlm = NULL; if (status < 0) { return FALSE; } rdg->state = RDG_CLIENT_STATE_OUT_CHANNEL_AUTHORIZE; return TRUE; }
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; }
int rpc_ncacn_http_recv_in_channel_response(rdpRpc* rpc) { int ntlm_token_length; BYTE* ntlm_token_data; HttpResponse* http_response; rdpNtlm* ntlm = rpc->NtlmHttpIn->ntlm; http_response = http_response_recv(rpc->TlsIn); 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; http_response_free(http_response); return 0; }
int rpc_ncacn_http_recv_out_channel_response(rdpRpc* rpc) { int ntlm_token_length = 0; BYTE* ntlm_token_data; HttpResponse* http_response; rdpNtlm* ntlm = rpc->NtlmHttpOut->ntlm; http_response = http_response_recv(rpc->TlsOut); ntlm_token_data = NULL; if (http_response && http_response->AuthParam) { crypto_base64_decode((BYTE*) http_response->AuthParam, strlen(http_response->AuthParam), &ntlm_token_data, &ntlm_token_length); } ntlm->inputBuffer[0].pvBuffer = ntlm_token_data; ntlm->inputBuffer[0].cbBuffer = ntlm_token_length; http_response_free(http_response); return 0; }
tbool rpch_in_connect_http(rdpRpch* rpch) { rdpTls* tls_in = rpch->tls_in; rdpSettings* settings = rpch->settings; rdpRpchHTTP* http_in = rpch->http_in; NTLMSSP* http_in_ntlmssp = http_in->ntht; STREAM* ntlmssp_stream; STREAM* http_stream; int decoded_ntht_length; int encoded_ntht_length = 0; int bytes; uint8* decoded_ntht_data; uint8* encoded_ntht_data = NULL; char* ntlm_text; LLOGLN(10, ("rpch_in_connect_http:")); ntlmssp_stream = stream_new(0xFFFF); http_stream = stream_new(0xFFFF); ntlmssp_set_username(http_in_ntlmssp, settings->tsg_username); ntlmssp_set_password(http_in_ntlmssp, settings->tsg_password); ntlmssp_set_domain(http_in_ntlmssp, settings->tsg_domain); ntlmssp_set_workstation(http_in_ntlmssp, "WORKSTATION"); /* TODO insert proper w.name */ LLOGLN(10, ("rpch_in_connect_http: tsg_username %s tsg_password %s tsg_domain %s", settings->tsg_username, settings->tsg_password, settings->tsg_domain)); ntlmssp_send(http_in_ntlmssp, ntlmssp_stream); decoded_ntht_length = (int) (ntlmssp_stream->p - ntlmssp_stream->data); decoded_ntht_data = (uint8*) xmalloc(decoded_ntht_length); ntlmssp_stream->p = ntlmssp_stream->data; stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); stream_clear(ntlmssp_stream); ntlmssp_stream->p = ntlmssp_stream->data; crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); stream_write(http_stream, "RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 54); stream_write(http_stream, "Accept: application/rpc\n", 24); stream_write(http_stream, "Cache-Control: no-cache\n", 24); stream_write(http_stream, "Connection: Keep-Alive\n", 23); stream_write(http_stream, "Content-Length: 0\n", 18); stream_write(http_stream, "User-Agent: MSRPC\n", 18); stream_write(http_stream, "Host: ", 6); stream_write(http_stream, settings->tsg_server, strlen(settings->tsg_server)); stream_write(http_stream, "\n", 1); stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); stream_write(http_stream, "Authorization: NTLM ", 20); stream_write(http_stream, encoded_ntht_data, encoded_ntht_length); stream_write(http_stream, "\n\n", 2); LLOGLN(10, ("rpch_in_connect_http: sending\n%s", http_stream->data)); DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); bytes = (int) (http_stream->p - http_stream->data); tls_write(tls_in, http_stream->data, bytes); stream_clear(http_stream); http_stream->p = http_stream->data; xfree(decoded_ntht_data); encoded_ntht_length = -1; xfree(encoded_ntht_data); encoded_ntht_data = NULL; http_in->contentLength = 0; LLOGLN(10, ("rpch_in_connect_http: 1")); stream_free(http_stream); http_stream = read_http(tls_in, NULL, true); if (http_stream == NULL) { LLOGLN(0, ("rpch_in_connect_http: error http_stream is nil")); return false; } ntlm_text = strstr((char*)(http_stream->data), "NTLM "); if (ntlm_text != NULL) { encoded_ntht_data = (uint8*)(ntlm_text + 5); encoded_ntht_length = 0; while (encoded_ntht_data[encoded_ntht_length] != '\r' && encoded_ntht_data[encoded_ntht_length] != '\n') { encoded_ntht_length++; } } LLOGLN(0, ("rpch_in_connect_http: encoded_ntht_length %d encoded_ntht_data %s", encoded_ntht_length, encoded_ntht_data)); if (encoded_ntht_length < 1) /* No NTLM data was found */ { LLOGLN(0, ("rpch_in_connect_http: error encoded_ntht_length < 1")); return false; } http_stream->p = http_stream->data; crypto_base64_decode(encoded_ntht_data, encoded_ntht_length, &decoded_ntht_data, &decoded_ntht_length); stream_write(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); ntlmssp_stream->p = ntlmssp_stream->data; xfree(decoded_ntht_data); ntlmssp_recv(http_in_ntlmssp, ntlmssp_stream); stream_clear(ntlmssp_stream); ntlmssp_stream->p = ntlmssp_stream->data; ntlmssp_send(http_in_ntlmssp, ntlmssp_stream); decoded_ntht_length = (int) (ntlmssp_stream->p - ntlmssp_stream->data); decoded_ntht_data = (uint8*) xmalloc(decoded_ntht_length); ntlmssp_stream->p = ntlmssp_stream->data; stream_read(ntlmssp_stream, decoded_ntht_data, decoded_ntht_length); stream_clear(ntlmssp_stream); ntlmssp_stream->p = ntlmssp_stream->data; crypto_base64_encode(decoded_ntht_data, decoded_ntht_length, &encoded_ntht_data, &encoded_ntht_length); stream_write(http_stream, "RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1\n", 54); stream_write(http_stream, "Accept: application/rpc\n", 24); stream_write(http_stream, "Cache-Control: no-cache\n", 24); stream_write(http_stream, "Connection: Keep-Alive\n", 23); stream_write(http_stream, "Content-Length: 1073741824\n", 27); stream_write(http_stream, "User-Agent: MSRPC\n", 18); stream_write(http_stream, "Host: ", 6); stream_write(http_stream, settings->tsg_server, strlen(settings->tsg_server)); stream_write(http_stream, "\n", 1); stream_write(http_stream, "Pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=33ad20ac-7469-4f63-946d-113eac21a23c\n", 110); stream_write(http_stream, "Authorization: NTLM ", 20); stream_write(http_stream, encoded_ntht_data, encoded_ntht_length); stream_write(http_stream, "\n\n", 2); http_in->contentLength = 1073741824; http_in->remContentLength = 1073741824; DEBUG_RPCH("\nSend:\n%s\n", http_stream->data); tls_write(tls_in, http_stream->data, http_stream->p - http_stream->data); stream_clear(http_stream); http_stream->p = http_stream->data; xfree(decoded_ntht_data); xfree(encoded_ntht_data); /* At this point IN connection is ready to send CONN/B1 and start with sending data */ http_in->state = RPCH_HTTP_SENDING; LLOGLN(10, ("rpch_in_connect_http: out")); return true; }
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; }