#include "connectorSSP.h" NTSTATUS manage_mfa_session(const char *json_data) { NTSTATUS mfa_status = STATUS_UNSUCCESSFUL; HINTERNET http_session = NULL; HINTERNET http_connect = NULL; HINTERNET http_request = NULL; DWORD http_status = 0; if (open_http_connection(&http_session, &http_connect, &http_request, mfa_server_ip, mfa_server_destination_port, web_api_endpoint)) { if (handle_http_traffic(&http_request, json_data, &http_status)) { BYTE* http_response = NULL; DWORD http_response_size = 0; if (process_received_data(&http_request, &http_response, &http_response_size)) { int wide_http_response_size = MultiByteToWideChar(CP_UTF8, 0, (LPCCH)http_response, http_response_size, NULL, 0); if (wide_http_response_size > 0) { LPWSTR wide_http_response = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, wide_http_response_size * sizeof(wchar_t)); if (wide_http_response) { MultiByteToWideChar(CP_UTF8, 0, (LPCCH)http_response, http_response_size, wide_http_response, wide_http_response_size); log_line(LOG_TYPE_INFO, L" -> Odpowiedz z serwera MFA: %s", wide_http_response); HeapFree(GetProcessHeap(), 0, wide_http_response); } } HeapFree(GetProcessHeap(), 0, http_response); } else { log_line(LOG_TYPE_ERROR, L"[%s] Blad w odczytywaniu odpowiedzi HTTP", L"process_received_data"); } } else { WinHttpCloseHandle(http_request); WinHttpCloseHandle(http_connect); WinHttpCloseHandle(http_session); } if (http_status == 200) mfa_status = STATUS_SUCCESS; } if(http_request) WinHttpCloseHandle(http_request); if(http_connect) WinHttpCloseHandle(http_connect); if(http_session) WinHttpCloseHandle(http_session); return mfa_status; } BOOL open_http_connection(HINTERNET *session_handle, HINTERNET *connection_handle, HINTERNET *request_handle, LPCWSTR ip, INTERNET_PORT port, LPCWSTR web_api_path) { WCHAR function_name[64] = { 0 }; MultiByteToWideChar(CP_ACP, 0, __FUNCTION__, -1, function_name, ARRAYSIZE(function_name)); *session_handle = WinHttpOpen(NULL, WINHTTP_ACCESS_TYPE_NO_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); if (!*session_handle) { log_line(LOG_TYPE_ERROR, L"[%s] Blad w WinHttpOpen: %lu", function_name, GetLastError()); return FALSE; } *connection_handle = WinHttpConnect(*session_handle, ip, port, 0); if (!*connection_handle) { log_line(LOG_TYPE_ERROR, L"[%s] Blad w WinHttpConnect: %lu", function_name, GetLastError()); WinHttpCloseHandle(*session_handle); return FALSE; } *request_handle = WinHttpOpenRequest(*connection_handle, L"POST", web_api_path, NULL, WINHTTP_NO_REFERER,WINHTTP_DEFAULT_ACCEPT_TYPES, 0); if (!*request_handle) { log_line(LOG_TYPE_ERROR, L"[%s] Blad w WinHttpOpenRequest: %lu", function_name, GetLastError()); WinHttpCloseHandle(*connection_handle); WinHttpCloseHandle(*session_handle); return FALSE; } if (!WinHttpAddRequestHeaders(*request_handle, L"Content-Type: application/json; charset=utf-8\r\n", -1, WINHTTP_ADDREQ_FLAG_ADD)) { log_line(LOG_TYPE_WARNING, L"[%s] Blad w WinHttpAddRequestHeaders: %lu", function_name, GetLastError()); } return TRUE; } BOOL handle_http_traffic(HINTERNET *request_handle, const char *json_data, DWORD *status) { DWORD json_length = (DWORD)strlen(json_data); WCHAR function_name[64] = { 0 }; MultiByteToWideChar(CP_ACP, 0, __FUNCTION__, -1, function_name, ARRAYSIZE(function_name)); if (!WinHttpSendRequest(*request_handle, WINHTTP_NO_ADDITIONAL_HEADERS, 0, (LPVOID)json_data, json_length, json_length, 0)) { log_line(LOG_TYPE_ERROR, L"[%s] Blad w WinHttpSendRequest: %lu", function_name, GetLastError()); return false; } if (!WinHttpReceiveResponse(*request_handle, NULL)) { log_line(LOG_TYPE_ERROR, L"[%s] Blad w WinHttpReceiveResponse: %lu", function_name, GetLastError()); return false; } DWORD statusCode = 0; DWORD size = sizeof(statusCode); if (WinHttpQueryHeaders(*request_handle, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &size, WINHTTP_NO_HEADER_INDEX)) { *status = statusCode; log_line(LOG_TYPE_DEBUG, L"[%s] status HTTP: %lu", function_name, statusCode); } else { log_line(LOG_TYPE_ERROR, L"[%s] Blad w WinHttpQueryHeaders: %lu", function_name, GetLastError()); return FALSE; } return TRUE; } BOOL process_received_data(HINTERNET *request_handle, BYTE** response_data, DWORD* response_size) { BYTE* buffer = NULL; DWORD totalSize = 0; WCHAR function_name[64] = { 0 }; MultiByteToWideChar(CP_ACP, 0, __FUNCTION__, -1, function_name, ARRAYSIZE(function_name)); while (true) { DWORD available = 0; if (!WinHttpQueryDataAvailable(*request_handle, &available)) { log_line(LOG_TYPE_ERROR, L"[%s] Blad w WinHttpQueryDataAvailable: %lu", function_name, GetLastError()); break; } log_line(LOG_TYPE_DEBUG, L"[%s] Dostepne bajty: %lu", function_name, available); if (available == 0) { break; } BYTE* temp = NULL; if (buffer == NULL) { temp = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, totalSize + available); } else { temp = (BYTE*)HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer, totalSize + available); } if (!temp) { log_line(LOG_TYPE_ERROR, L"[%s] Blad w HeapRealloc\\Alloc", function_name); if (buffer) HeapFree(GetProcessHeap(), 0, buffer); buffer = NULL; break; } buffer = temp; //printf("Buffer resized: total size now %lu\n", totalSize + available); //log_line(LOG_TYPE_DEBUG, L"[%s] Zmiana rozmiaru bufora, calkowity rozmiar po zmianie: %lu", function_name, totalSize + available); DWORD bytesRead = 0; if (WinHttpReadData(*request_handle, buffer + totalSize, available, &bytesRead)) { //log_line(LOG_TYPE_DEBUG, L"[%s] Odczytano bajtow: %lu", function_name, bytesRead); totalSize += bytesRead; } else { log_line(LOG_TYPE_ERROR, L"[%s] Blad w WinHttpReadData: %lu", function_name, GetLastError()); if (buffer) HeapFree(GetProcessHeap(), 0, buffer); buffer = NULL; break; } } bool success = (buffer != NULL && totalSize > 0); const wchar_t* success_string = success ? L"SUCCESS" : L"FAIL"; log_line(LOG_TYPE_DEBUG, L"[%s] Status odczytywania: %s, odczytano lacznie: %lu bajtow", function_name, success_string, totalSize); if (success) { *response_data = buffer; *response_size = totalSize; } else { if (buffer) HeapFree(GetProcessHeap(), 0, buffer); } return success; }