wStream* rpc_ntlm_http_request(rdpRpc* rpc, HttpContext* http, const char* method, int contentLength, SecBuffer* ntlmToken) { wStream* s; HttpRequest* request; char* base64NtlmToken = NULL; request = http_request_new(); if (ntlmToken) base64NtlmToken = crypto_base64_encode(ntlmToken->pvBuffer, ntlmToken->cbBuffer); http_request_set_method(request, method); request->ContentLength = contentLength; http_request_set_uri(request, http->URI); if (base64NtlmToken) { http_request_set_auth_scheme(request, "NTLM"); http_request_set_auth_param(request, base64NtlmToken); } s = http_request_write(http, request); http_request_free(request); free(base64NtlmToken); return s; }
wStream* rdg_build_http_request(rdpRdg* rdg, char* method) { wStream* s; HttpRequest* request = NULL; SecBuffer* ntlmToken = NULL; char* base64NtlmToken = NULL; assert(method != NULL); request = http_request_new(); if (!request) return NULL; http_request_set_method(request, method); http_request_set_uri(request, rdg->http->URI); if (!request->Method || !request->URI) return NULL; if (rdg->ntlm) { ntlmToken = rdg->ntlm->outputBuffer; if (ntlmToken) base64NtlmToken = crypto_base64_encode(ntlmToken->pvBuffer, ntlmToken->cbBuffer); if (base64NtlmToken) { http_request_set_auth_scheme(request, "NTLM"); http_request_set_auth_param(request, base64NtlmToken); free(base64NtlmToken); if (!request->AuthScheme || !request->AuthParam) return NULL; } } if (rdg->state == RDG_CLIENT_STATE_IN_CHANNEL_AUTHORIZED) { http_request_set_transfer_encoding(request, "chunked"); } s = http_request_write(rdg->http, request); http_request_free(request); if (s) Stream_SealLength(s); return s; }
wStream* rpc_ntlm_http_request(rdpRpc* rpc, SecBuffer* ntlm_token, int content_length, TSG_CHANNEL channel) { wStream* s; HttpContext* http_context; HttpRequest* http_request; char* base64_ntlm_token = NULL; http_request = http_request_new(); if (ntlm_token) base64_ntlm_token = crypto_base64_encode(ntlm_token->pvBuffer, ntlm_token->cbBuffer); if (channel == TSG_CHANNEL_IN) { http_context = rpc->NtlmHttpIn->context; http_request_set_method(http_request, "RPC_IN_DATA"); } else if (channel == TSG_CHANNEL_OUT) { http_context = rpc->NtlmHttpOut->context; http_request_set_method(http_request, "RPC_OUT_DATA"); } else { return NULL; } http_request->ContentLength = content_length; http_request_set_uri(http_request, http_context->URI); if (base64_ntlm_token) { http_request_set_auth_scheme(http_request, "NTLM"); http_request_set_auth_param(http_request, base64_ntlm_token); } s = http_request_write(http_context, http_request); http_request_free(http_request); free(base64_ntlm_token); return s; }
BOOL rdp_read_server_auto_reconnect_cookie(rdpRdp* rdp, wStream* s, logon_info_ex *info) { BYTE* p; ARC_SC_PRIVATE_PACKET* autoReconnectCookie; rdpSettings* settings = rdp->settings; autoReconnectCookie = settings->ServerAutoReconnectCookie; if (Stream_GetRemainingLength(s) < 28) return FALSE; Stream_Read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ if (autoReconnectCookie->cbLen != 28) { WLog_ERR(TAG, "ServerAutoReconnectCookie.cbLen != 28"); return FALSE; } Stream_Read_UINT32(s, autoReconnectCookie->version); /* Version (4 bytes) */ Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ Stream_Read(s, autoReconnectCookie->arcRandomBits, 16); /* ArcRandomBits (16 bytes) */ p = autoReconnectCookie->arcRandomBits; WLog_DBG(TAG, "ServerAutoReconnectCookie: Version: %d LogonId: %d SecurityVerifier: " "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", autoReconnectCookie->version, autoReconnectCookie->logonId, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]); info->LogonId = autoReconnectCookie->logonId; CopyMemory(info->ArcRandomBits, p, 16); if ((settings->PrintReconnectCookie) && (autoReconnectCookie->cbLen > 0)) { char* base64; base64 = crypto_base64_encode((BYTE*) autoReconnectCookie, sizeof(ARC_SC_PRIVATE_PACKET)); WLog_INFO(TAG, "Reconnect-cookie: %s", base64); free(base64); } return TRUE; }
static BOOL rdg_set_ntlm_auth_header(rdpNtlm* ntlm, HttpRequest* request) { SecBuffer* ntlmToken = ntlm->outputBuffer; char* base64NtlmToken = NULL; if (ntlmToken) base64NtlmToken = crypto_base64_encode(ntlmToken->pvBuffer, ntlmToken->cbBuffer); if (base64NtlmToken) { http_request_set_auth_scheme(request, "NTLM"); http_request_set_auth_param(request, base64NtlmToken); free(base64NtlmToken); if (!request->AuthScheme || !request->AuthParam) return FALSE; } return TRUE; }
BOOL rdp_read_server_auto_reconnect_cookie(wStream* s, rdpSettings* settings) { ARC_SC_PRIVATE_PACKET* autoReconnectCookie; autoReconnectCookie = settings->ServerAutoReconnectCookie; if (Stream_GetRemainingLength(s) < 4+4+4+16) return FALSE; Stream_Read_UINT32(s, autoReconnectCookie->cbLen); /* cbLen (4 bytes) */ Stream_Read_UINT32(s, autoReconnectCookie->version); /* version (4 bytes) */ Stream_Read_UINT32(s, autoReconnectCookie->logonId); /* LogonId (4 bytes) */ Stream_Read(s, autoReconnectCookie->arcRandomBits, 16); /* arcRandomBits (16 bytes) */ if ((settings->PrintReconnectCookie) && (autoReconnectCookie->cbLen > 0)) { char *base64; base64 = crypto_base64_encode((BYTE *) autoReconnectCookie, sizeof(ARC_SC_PRIVATE_PACKET)); WLog_INFO(TAG, "Reconnect-cookie: %s", base64); free(base64); } return TRUE; }
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; }