diff --git a/CMakeLists.txt b/CMakeLists.txt index 4994d474b..fe9716389 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,7 +98,7 @@ endif() # This forces the MSVC runtime to be statically linked -if(MSVC) +if(WITH_MSVC_STATIC) foreach(flag_var CMAKE_C_FLAGS_DEBUG CMAKE_CXX_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO CMAKE_CXX_FLAGS_RELWITHDEBINFO) string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") string(REGEX REPLACE "/MDd" "/MTd" ${flag_var} "${${flag_var}}") diff --git a/client/Windows/wf_graphics.c b/client/Windows/wf_graphics.c index 17d0b85c5..2d1d98d9a 100644 --- a/client/Windows/wf_graphics.c +++ b/client/Windows/wf_graphics.c @@ -85,21 +85,6 @@ wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, uint8* data) return image; } -wfBitmap* wf_bitmap_new(wfInfo* wfi, int width, int height, int bpp, uint8* data) -{ - HDC hdc; - wfBitmap* bitmap; - - hdc = GetDC(NULL); - bitmap = (wfBitmap*) xmalloc(sizeof(wfBitmap)); - bitmap->hdc = CreateCompatibleDC(hdc); - bitmap->bitmap = wf_create_dib(wfi, width, height, bpp, data, &(bitmap->pdata)); - bitmap->org_bitmap = (HBITMAP) SelectObject(bitmap->hdc, bitmap->bitmap); - ReleaseDC(NULL, hdc); - - return bitmap; -} - void wf_image_free(wfBitmap* image) { if (image != 0) diff --git a/client/Windows/wf_graphics.h b/client/Windows/wf_graphics.h index 024d3f77b..96dfd3513 100644 --- a/client/Windows/wf_graphics.h +++ b/client/Windows/wf_graphics.h @@ -24,7 +24,6 @@ HBITMAP wf_create_dib(wfInfo* wfi, int width, int height, int bpp, uint8* data, uint8** pdata); wfBitmap* wf_image_new(wfInfo* wfi, int width, int height, int bpp, uint8* data); -wfBitmap* wf_bitmap_new(wfInfo* wfi, int width, int height, int bpp, uint8* data); void wf_image_free(wfBitmap* image); void wf_register_graphics(rdpGraphics* graphics); diff --git a/client/Windows/wfreerdp.c b/client/Windows/wfreerdp.c index 2fe643dca..6bc8a59ea 100644 --- a/client/Windows/wfreerdp.c +++ b/client/Windows/wfreerdp.c @@ -153,30 +153,30 @@ boolean wf_pre_connect(freerdp* instance) settings->os_major_type = OSMAJORTYPE_WINDOWS; settings->os_minor_type = OSMINORTYPE_WINDOWS_NT; - settings->order_support[NEG_DSTBLT_INDEX] = true; - settings->order_support[NEG_PATBLT_INDEX] = true; - settings->order_support[NEG_SCRBLT_INDEX] = true; - settings->order_support[NEG_OPAQUE_RECT_INDEX] = true; - settings->order_support[NEG_DRAWNINEGRID_INDEX] = false; - settings->order_support[NEG_MULTIDSTBLT_INDEX] = false; - settings->order_support[NEG_MULTIPATBLT_INDEX] = false; - settings->order_support[NEG_MULTISCRBLT_INDEX] = false; - settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = true; - settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = false; - settings->order_support[NEG_LINETO_INDEX] = true; - settings->order_support[NEG_POLYLINE_INDEX] = true; - settings->order_support[NEG_MEMBLT_INDEX] = true; - settings->order_support[NEG_MEM3BLT_INDEX] = false; - settings->order_support[NEG_SAVEBITMAP_INDEX] = false; - settings->order_support[NEG_GLYPH_INDEX_INDEX] = false; - settings->order_support[NEG_FAST_INDEX_INDEX] = false; - settings->order_support[NEG_FAST_GLYPH_INDEX] = false; - settings->order_support[NEG_POLYGON_SC_INDEX] = false; - settings->order_support[NEG_POLYGON_CB_INDEX] = false; - settings->order_support[NEG_ELLIPSE_SC_INDEX] = false; - settings->order_support[NEG_ELLIPSE_CB_INDEX] = false; + settings->order_support[NEG_DSTBLT_INDEX] = TRUE; + settings->order_support[NEG_PATBLT_INDEX] = TRUE; + settings->order_support[NEG_SCRBLT_INDEX] = TRUE; + settings->order_support[NEG_OPAQUE_RECT_INDEX] = TRUE; + settings->order_support[NEG_DRAWNINEGRID_INDEX] = FALSE; + settings->order_support[NEG_MULTIDSTBLT_INDEX] = FALSE; + settings->order_support[NEG_MULTIPATBLT_INDEX] = FALSE; + settings->order_support[NEG_MULTISCRBLT_INDEX] = FALSE; + settings->order_support[NEG_MULTIOPAQUERECT_INDEX] = TRUE; + settings->order_support[NEG_MULTI_DRAWNINEGRID_INDEX] = FALSE; + settings->order_support[NEG_LINETO_INDEX] = TRUE; + settings->order_support[NEG_POLYLINE_INDEX] = TRUE; + settings->order_support[NEG_MEMBLT_INDEX] = TRUE; + settings->order_support[NEG_MEM3BLT_INDEX] = FALSE; + settings->order_support[NEG_SAVEBITMAP_INDEX] = FALSE; + settings->order_support[NEG_GLYPH_INDEX_INDEX] = FALSE; + settings->order_support[NEG_FAST_INDEX_INDEX] = FALSE; + settings->order_support[NEG_FAST_GLYPH_INDEX] = FALSE; + settings->order_support[NEG_POLYGON_SC_INDEX] = FALSE; + settings->order_support[NEG_POLYGON_CB_INDEX] = FALSE; + settings->order_support[NEG_ELLIPSE_SC_INDEX] = FALSE; + settings->order_support[NEG_ELLIPSE_CB_INDEX] = FALSE; - settings->glyph_cache = false; + settings->glyph_cache = FALSE; wfi->cursor = g_default_cursor; @@ -186,7 +186,7 @@ boolean wf_pre_connect(freerdp* instance) wfi->clrconv = (HCLRCONV) xzalloc(sizeof(CLRCONV)); wfi->clrconv->palette = NULL; - wfi->clrconv->alpha = false; + wfi->clrconv->alpha = FALSE; instance->context->cache = cache_new(settings); @@ -219,7 +219,7 @@ boolean wf_pre_connect(freerdp* instance) settings->kbd_layout = (int) GetKeyboardLayout(0) & 0x0000FFFF; freerdp_channels_pre_connect(instance->context->channels, instance); - return true; + return TRUE; } void cpuid(unsigned info, unsigned *eax, unsigned *ebx, unsigned *ecx, unsigned *edx) @@ -309,12 +309,12 @@ boolean wf_post_connect(freerdp* instance) wfi->hdc->hwnd->cinvalid = (HGDI_RGN) xmalloc(sizeof(GDI_RGN) * wfi->hdc->hwnd->count); wfi->hdc->hwnd->ninvalid = 0; - wfi->image = wf_bitmap_new(wfi, 64, 64, 32, NULL); + wfi->image = wf_image_new(wfi, 64, 64, 32, NULL); wfi->image->_bitmap.data = NULL; if (settings->rfx_codec) { - wfi->tile = wf_bitmap_new(wfi, 64, 64, 32, NULL); + wfi->tile = wf_image_new(wfi, 64, 64, 32, NULL); wfi->rfx_context = rfx_context_new(); rfx_context_set_cpu_opt(wfi->rfx_context, wfi_detect_cpu()); } @@ -324,7 +324,7 @@ boolean wf_post_connect(freerdp* instance) } if (settings->window_title != NULL) - _snwprintf(win_title, sizeof(win_title), L"%S", settings->window_title); + _snwprintf(win_title, ARRAY_SIZE(win_title), L"%S", settings->window_title); else if (settings->port == 3389) _snwprintf(win_title, ARRAY_SIZE(win_title), L"FreeRDP: %S", settings->hostname); else @@ -377,7 +377,7 @@ boolean wf_post_connect(freerdp* instance) pointer_cache_register_callbacks(instance->update); - if (wfi->sw_gdi != true) + if (wfi->sw_gdi != TRUE) { brush_cache_register_callbacks(instance->update); bitmap_cache_register_callbacks(instance->update); @@ -390,7 +390,7 @@ boolean wf_post_connect(freerdp* instance) wf_cliprdr_init(wfi, instance->context->channels); - return true; + return TRUE; } boolean wf_verify_certificate(freerdp* instance, char* subject, char* issuer, char* fingerprint) @@ -421,7 +421,7 @@ boolean wf_verify_certificate(freerdp* instance, char* subject, char* issuer, ch SetConsoleMode(input_handle, mode); #endif - return true; + return TRUE; } int wf_receive_channel_data(freerdp* instance, int channelId, uint8* data, int size, int flags, int total_size) @@ -441,12 +441,12 @@ void wf_process_channel_event(rdpChannels* channels, freerdp* instance) boolean wf_get_fds(freerdp* instance, void** rfds, int* rcount, void** wfds, int* wcount) { - return true; + return TRUE; } boolean wf_check_fds(freerdp* instance) { - return true; + return TRUE; } int wf_process_plugin_args(rdpSettings* settings, const char* name, RDP_PLUGIN_DATA* plugin_data, void* user_data) @@ -481,7 +481,7 @@ int wfreerdp_run(freerdp* instance) memset(rfds, 0, sizeof(rfds)); memset(wfds, 0, sizeof(wfds)); - if (freerdp_connect(instance) != true) + if (freerdp_connect(instance) != TRUE) return 0; channels = instance->context->channels; @@ -491,17 +491,17 @@ int wfreerdp_run(freerdp* instance) rcount = 0; wcount = 0; - if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != true) + if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { printf("Failed to get FreeRDP file descriptor\n"); break; } - if (wf_get_fds(instance, rfds, &rcount, wfds, &wcount) != true) + if (wf_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) { printf("Failed to get wfreerdp file descriptor\n"); break; } - if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != true) + if (freerdp_channels_get_fds(channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) { printf("Failed to get channel manager file descriptor\n"); break; @@ -532,17 +532,17 @@ int wfreerdp_run(freerdp* instance) break; } - if (freerdp_check_fds(instance) != true) + if (freerdp_check_fds(instance) != TRUE) { printf("Failed to check FreeRDP file descriptor\n"); break; } - if (wf_check_fds(instance) != true) + if (wf_check_fds(instance) != TRUE) { printf("Failed to check wfreerdp file descriptor\n"); break; } - if (freerdp_channels_check_fds(channels, instance) != true) + if (freerdp_channels_check_fds(channels, instance) != TRUE) { printf("Failed to check channel manager file descriptor\n"); break; @@ -569,8 +569,10 @@ int wfreerdp_run(freerdp* instance) } /* cleanup */ + + freerdp_channels_close(channels, instance); freerdp_channels_free(channels); - freerdp_free(instance); + freerdp_disconnect(instance); return 0; } @@ -721,6 +723,9 @@ INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine L"Failed to start wfreerdp.\n\nPlease check the debug output.", L"FreeRDP Error", MB_ICONSTOP); + freerdp_context_free(instance); + freerdp_free(instance); + WSACleanup(); #ifdef _DEBUG diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake index cc2afd95d..a0c8ad15e 100644 --- a/cmake/ConfigOptions.cmake +++ b/cmake/ConfigOptions.cmake @@ -12,6 +12,7 @@ endif() if(MSVC) option(WITH_NATIVE_SSPI "Use native SSPI modules" ON) + option(WITH_MSVC_STATIC "Use static MSVC runtime" OFF) endif() if(${CMAKE_VERSION} VERSION_GREATER 2.8.8) diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index 4f38d5973..9935f4f29 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -50,30 +50,39 @@ void settings_client_load_hkey_local_machine(rdpSettings* settings) if (status != ERROR_SUCCESS) return; + dwSize = sizeof(DWORD); if (RegQueryValueEx(hKey, _T("DesktopWidth"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) settings->width = dwValue; + dwSize = sizeof(DWORD); if (RegQueryValueEx(hKey, _T("DesktopHeight"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) settings->height = dwValue; + dwSize = sizeof(DWORD); if (RegQueryValueEx(hKey, _T("KeyboardType"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) settings->kbd_type = dwValue; + dwSize = sizeof(DWORD); if (RegQueryValueEx(hKey, _T("KeyboardSubType"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) settings->kbd_subtype = dwValue; + dwSize = sizeof(DWORD); if (RegQueryValueEx(hKey, _T("KeyboardFunctionKeys"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) settings->kbd_fn_keys = dwValue; + dwSize = sizeof(DWORD); if (RegQueryValueEx(hKey, _T("KeyboardLayout"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) settings->kbd_layout = dwValue; + dwSize = sizeof(DWORD); if (RegQueryValueEx(hKey, _T("NlaSecurity"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) settings->nla_security = dwValue ? 1 : 0; + dwSize = sizeof(DWORD); if (RegQueryValueEx(hKey, _T("TlsSecurity"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) settings->tls_security = dwValue ? 1 : 0; + dwSize = sizeof(DWORD); if (RegQueryValueEx(hKey, _T("RdpSecurity"), NULL, &dwType, (BYTE*) &dwValue, &dwSize) == ERROR_SUCCESS) settings->rdp_security = dwValue ? 1 : 0; diff --git a/libfreerdp/crypto/nla.c b/libfreerdp/crypto/nla.c index e98663b37..e81e030f2 100644 --- a/libfreerdp/crypto/nla.c +++ b/libfreerdp/crypto/nla.c @@ -128,6 +128,11 @@ int credssp_ntlm_client_init(rdpCredssp* credssp) sspi_SetAuthIdentity(&(credssp->identity), settings->username, settings->domain, settings->password); +#ifdef WITH_DEBUG_NLA + _tprintf(_T("User: %s Domain: %s Password: %s\n"), + credssp->identity.User, credssp->identity.Domain, credssp->identity.Password); +#endif + sspi_SecBufferAlloc(&credssp->PublicKey, credssp->tls->public_key.length); CopyMemory(credssp->PublicKey.pvBuffer, credssp->tls->public_key.data, credssp->tls->public_key.length); @@ -174,7 +179,6 @@ int credssp_client_authenticate(rdpCredssp* credssp) CredHandle credentials; TimeStamp expiration; PSecPkgInfo pPackageInfo; - PSecBuffer p_buffer; SecBuffer input_buffer; SecBuffer output_buffer; SecBufferDesc input_buffer_desc; @@ -245,9 +249,6 @@ int credssp_client_authenticate(rdpCredssp* credssp) while (true) { -#ifdef WITH_DEBUG_CREDSSP - printf("credssp_client_authenticate loop"); -#endif output_buffer_desc.ulVersion = SECBUFFER_VERSION; output_buffer_desc.cBuffers = 1; output_buffer_desc.pBuffers = &output_buffer; @@ -292,10 +293,8 @@ int credssp_client_authenticate(rdpCredssp* credssp) if (output_buffer.cbBuffer > 0) { - p_buffer = &output_buffer_desc.pBuffers[0]; - - credssp->negoToken.pvBuffer = p_buffer->pvBuffer; - credssp->negoToken.cbBuffer = p_buffer->cbBuffer; + credssp->negoToken.pvBuffer = output_buffer.pvBuffer; + credssp->negoToken.cbBuffer = output_buffer.cbBuffer; #ifdef WITH_DEBUG_CREDSSP printf("Sending Authentication Token\n"); @@ -324,9 +323,8 @@ int credssp_client_authenticate(rdpCredssp* credssp) winpr_HexDump(credssp->negoToken.pvBuffer, credssp->negoToken.cbBuffer); #endif - p_buffer = &input_buffer_desc.pBuffers[0]; - p_buffer->pvBuffer = credssp->negoToken.pvBuffer; - p_buffer->cbBuffer = credssp->negoToken.cbBuffer; + input_buffer.pvBuffer = credssp->negoToken.pvBuffer; + input_buffer.cbBuffer = credssp->negoToken.cbBuffer; have_input_buffer = true; have_context = true; diff --git a/winpr/include/winpr/sspi.h b/winpr/include/winpr/sspi.h index 0c4bd9fb2..80f9611cb 100644 --- a/winpr/include/winpr/sspi.h +++ b/winpr/include/winpr/sspi.h @@ -28,6 +28,8 @@ #include #include +#define _NO_KSECDD_IMPORT_ 1 + #ifdef _WIN32 #include @@ -669,8 +671,8 @@ typedef SecBufferDesc* PSecBufferDesc; typedef void (SEC_ENTRY * SEC_GET_KEY_FN)(void* Arg, void* Principal, UINT32 KeyVer, void** Key, SECURITY_STATUS* Status); -typedef SECURITY_STATUS (SEC_ENTRY * ENUMERATE_SECURITY_PACKAGES_FN_A)(UINT32* pcPackages, PSecPkgInfoA* ppPackageInfo); -typedef SECURITY_STATUS (SEC_ENTRY * ENUMERATE_SECURITY_PACKAGES_FN_W)(UINT32* pcPackages, PSecPkgInfoW* ppPackageInfo); +typedef SECURITY_STATUS (SEC_ENTRY * ENUMERATE_SECURITY_PACKAGES_FN_A)(ULONG* pcPackages, PSecPkgInfoA* ppPackageInfo); +typedef SECURITY_STATUS (SEC_ENTRY * ENUMERATE_SECURITY_PACKAGES_FN_W)(ULONG* pcPackages, PSecPkgInfoW* ppPackageInfo); #ifdef UNICODE #define EnumerateSecurityPackages EnumerateSecurityPackagesW @@ -692,10 +694,10 @@ typedef SECURITY_STATUS (SEC_ENTRY * QUERY_CREDENTIALS_ATTRIBUTES_FN_W)(PCredHan #endif typedef SECURITY_STATUS (SEC_ENTRY * ACQUIRE_CREDENTIALS_HANDLE_FN_A)(LPSTR pszPrincipal, LPSTR pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry); typedef SECURITY_STATUS (SEC_ENTRY * ACQUIRE_CREDENTIALS_HANDLE_FN_W)(LPWSTR pszPrincipal, LPWSTR pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry); #ifdef UNICODE @@ -767,10 +769,10 @@ typedef SECURITY_STATUS (SEC_ENTRY * QUERY_SECURITY_PACKAGE_INFO_FN_W)(SEC_WCHAR #define QUERY_SECURITY_PACKAGE_INFO_FN QUERY_SECURITY_PACKAGE_INFO_FN_A #endif -typedef SECURITY_STATUS (SEC_ENTRY * EXPORT_SECURITY_CONTEXT_FN)(PCtxtHandle phContext, UINT32 fFlags, PSecBuffer pPackedContext, void* pToken); +typedef SECURITY_STATUS (SEC_ENTRY * EXPORT_SECURITY_CONTEXT_FN)(PCtxtHandle phContext, ULONG fFlags, PSecBuffer pPackedContext, HANDLE* pToken); -typedef SECURITY_STATUS (SEC_ENTRY * IMPORT_SECURITY_CONTEXT_FN_A)(SEC_CHAR* pszPackage, PSecBuffer pPackedContext, void* pToken, PCtxtHandle phContext); -typedef SECURITY_STATUS (SEC_ENTRY * IMPORT_SECURITY_CONTEXT_FN_W)(SEC_WCHAR* pszPackage, PSecBuffer pPackedContext, void* pToken, PCtxtHandle phContext); +typedef SECURITY_STATUS (SEC_ENTRY * IMPORT_SECURITY_CONTEXT_FN_A)(SEC_CHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext); +typedef SECURITY_STATUS (SEC_ENTRY * IMPORT_SECURITY_CONTEXT_FN_W)(SEC_WCHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext); #ifdef UNICODE #define ImportSecurityContext ImportSecurityContextW @@ -793,7 +795,7 @@ typedef SECURITY_STATUS (SEC_ENTRY * ADD_CREDENTIALS_FN_W)(PCredHandle hCredenti #define ADD_CREDENTIALS_FN ADD_CREDENTIALS_FN_A #endif -typedef SECURITY_STATUS (SEC_ENTRY * QUERY_SECURITY_CONTEXT_TOKEN_FN)(PCtxtHandle phContext, void* phToken); +typedef SECURITY_STATUS (SEC_ENTRY * QUERY_SECURITY_CONTEXT_TOKEN_FN)(PCtxtHandle phContext, HANDLE* phToken); typedef SECURITY_STATUS (SEC_ENTRY * ENCRYPT_MESSAGE_FN)(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo); @@ -900,27 +902,29 @@ typedef PSecurityFunctionTableW (SEC_ENTRY * INIT_SECURITY_INTERFACE_W)(void); /* Package Management */ -WINPR_API SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesA(UINT32* pcPackages, PSecPkgInfoA* ppPackageInfo); -WINPR_API SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesW(UINT32* pcPackages, PSecPkgInfoW* ppPackageInfo); -WINPR_API SecurityFunctionTableA* SEC_ENTRY InitSecurityInterfaceA(void); -WINPR_API SecurityFunctionTableW* SEC_ENTRY InitSecurityInterfaceW(void); +WINPR_API SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesA(ULONG* pcPackages, PSecPkgInfoA* ppPackageInfo); +WINPR_API SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesW(ULONG* pcPackages, PSecPkgInfoW* ppPackageInfo); + +PSecurityFunctionTableA SEC_ENTRY InitSecurityInterfaceA(void); +PSecurityFunctionTableW SEC_ENTRY InitSecurityInterfaceW(void); + WINPR_API SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoA(SEC_CHAR* pszPackageName, PSecPkgInfoA* ppPackageInfo); WINPR_API SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoW(SEC_WCHAR* pszPackageName, PSecPkgInfoW* ppPackageInfo); /* Credential Management */ WINPR_API SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry); WINPR_API SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry); -WINPR_API SECURITY_STATUS SEC_ENTRY ExportSecurityContext(PCtxtHandle phContext, UINT32 fFlags, PSecBuffer pPackedContext, void* pToken); +WINPR_API SECURITY_STATUS SEC_ENTRY ExportSecurityContext(PCtxtHandle phContext, ULONG fFlags, PSecBuffer pPackedContext, HANDLE* pToken); WINPR_API SECURITY_STATUS SEC_ENTRY FreeCredentialsHandle(PCredHandle phCredential); -WINPR_API SECURITY_STATUS SEC_ENTRY ImportSecurityContextA(SEC_CHAR* pszPackage, PSecBuffer pPackedContext, void* pToken, PCtxtHandle phContext); -WINPR_API SECURITY_STATUS SEC_ENTRY ImportSecurityContextW(SEC_WCHAR* pszPackage, PSecBuffer pPackedContext, void* pToken, PCtxtHandle phContext); +WINPR_API SECURITY_STATUS SEC_ENTRY ImportSecurityContextA(SEC_CHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext); +WINPR_API SECURITY_STATUS SEC_ENTRY ImportSecurityContextW(SEC_WCHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext); WINPR_API SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer); WINPR_API SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesW(PCredHandle phCredential, ULONG ulAttribute, void* pBuffer); @@ -947,7 +951,7 @@ WINPR_API SECURITY_STATUS SEC_ENTRY InitializeSecurityContextW(PCredHandle phCre PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry); WINPR_API SECURITY_STATUS SEC_ENTRY QueryContextAttributes(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer); -WINPR_API SECURITY_STATUS SEC_ENTRY QuerySecurityContextToken(PCtxtHandle phContext, void* phToken); +WINPR_API SECURITY_STATUS SEC_ENTRY QuerySecurityContextToken(PCtxtHandle phContext, HANDLE* phToken); WINPR_API SECURITY_STATUS SEC_ENTRY SetContextAttributes(PCtxtHandle phContext, ULONG ulAttribute, void* pBuffer, ULONG cbBuffer); WINPR_API SECURITY_STATUS SEC_ENTRY RevertSecurityContext(PCtxtHandle phContext); diff --git a/winpr/include/winpr/tchar.h b/winpr/include/winpr/tchar.h index e63633b63..0078cc93b 100644 --- a/winpr/include/winpr/tchar.h +++ b/winpr/include/winpr/tchar.h @@ -20,6 +20,7 @@ #ifndef WINPR_TCHAR_H #define WINPR_TCHAR_H +#include #include #ifdef _WIN32 @@ -31,9 +32,13 @@ #ifdef UNICODE typedef WCHAR TCHAR; #define _tprintf wprintf +#define _tcsdup _wcsdup +#define _tcscmp wcscmp #else typedef CHAR TCHAR; #define _tprintf printf +#define _tcsdup _strdup +#define _tcscmp strcmp #endif #endif diff --git a/winpr/libwinpr/sspi/CredSSP/credssp.c b/winpr/libwinpr/sspi/CredSSP/credssp.c index 3da23e942..c0cceea9d 100644 --- a/winpr/libwinpr/sspi/CredSSP/credssp.c +++ b/winpr/libwinpr/sspi/CredSSP/credssp.c @@ -96,14 +96,14 @@ SECURITY_STATUS SEC_ENTRY credssp_QueryContextAttributes(PCtxtHandle phContext, } SECURITY_STATUS SEC_ENTRY credssp_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { return SEC_E_OK; } SECURITY_STATUS SEC_ENTRY credssp_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { CREDENTIALS* credentials; diff --git a/winpr/libwinpr/sspi/NTLM/ntlm.c b/winpr/libwinpr/sspi/NTLM/ntlm.c index 9c5bf4b0c..058595ee9 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm.c @@ -177,7 +177,7 @@ void ntlm_ContextFree(NTLM_CONTEXT* context) } SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { CREDENTIALS* credentials; @@ -218,7 +218,7 @@ SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal } SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { CREDENTIALS* credentials; diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c index 26967621f..9e75b71a3 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_av_pairs.c @@ -195,6 +195,22 @@ void ntlm_get_target_computer_name(PUNICODE_STRING pName, COMPUTER_NAME_FORMAT t free(name); } +void ntlm_free_unicode_string(PUNICODE_STRING string) +{ + if (string != NULL) + { + if (string->Length > 0) + { + if (string->Buffer != NULL) + free(string->Buffer); + + string->Buffer = NULL; + string->Length = 0; + string->MaximumLength = 0; + } + } +} + void ntlm_construct_challenge_target_info(NTLM_CONTEXT* context) { int length; @@ -228,6 +244,11 @@ void ntlm_construct_challenge_target_info(NTLM_CONTEXT* context) ntlm_av_pair_add(pAvPairList, MsvAvDnsDomainName, (PBYTE) DnsDomainName.Buffer, DnsDomainName.Length); ntlm_av_pair_add(pAvPairList, MsvAvDnsComputerName, (PBYTE) DnsComputerName.Buffer, DnsComputerName.Length); ntlm_av_pair_add(pAvPairList, MsvAvTimestamp, context->Timestamp, sizeof(context->Timestamp)); + + ntlm_free_unicode_string(&NbDomainName); + ntlm_free_unicode_string(&NbComputerName); + ntlm_free_unicode_string(&DnsDomainName); + ntlm_free_unicode_string(&DnsComputerName); } void ntlm_construct_authenticate_target_info(NTLM_CONTEXT* context) diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c index 3fe05ee58..93d32069d 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_compute.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_compute.c @@ -656,5 +656,6 @@ void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context) HMAC_Update(&hmac_ctx, context->ChallengeMessage.pvBuffer, context->ChallengeMessage.cbBuffer); HMAC_Update(&hmac_ctx, context->AuthenticateMessage.pvBuffer, context->AuthenticateMessage.cbBuffer); HMAC_Final(&hmac_ctx, context->MessageIntegrityCheck, NULL); + HMAC_CTX_cleanup(&hmac_ctx); } diff --git a/winpr/libwinpr/sspi/NTLM/ntlm_message.c b/winpr/libwinpr/sspi/NTLM/ntlm_message.c index 28d17f02c..4eff96641 100644 --- a/winpr/libwinpr/sspi/NTLM/ntlm_message.c +++ b/winpr/libwinpr/sspi/NTLM/ntlm_message.c @@ -161,6 +161,22 @@ void ntlm_write_message_fields_buffer(PStream s, NTLM_MESSAGE_FIELDS* fields) } } +void ntlm_free_message_fields_buffer(NTLM_MESSAGE_FIELDS* fields) +{ + if (fields != NULL) + { + if (fields->Buffer != NULL) + { + free(fields->Buffer); + + fields->Len = 0; + fields->MaxLen = 0; + fields->Buffer = NULL; + fields->BufferOffset = 0; + } + } +} + void ntlm_print_message_fields(NTLM_MESSAGE_FIELDS* fields, const char* name) { printf("%s (Len: %d MaxLen: %d BufferOffset: %d)\n", @@ -847,6 +863,13 @@ SECURITY_STATUS ntlm_read_AuthenticateMessage(NTLM_CONTEXT* context, PSecBuffer PStreamFreeDetach(s); + ntlm_free_message_fields_buffer(&(message.DomainName)); + ntlm_free_message_fields_buffer(&(message.UserName)); + ntlm_free_message_fields_buffer(&(message.Workstation)); + ntlm_free_message_fields_buffer(&(message.LmChallengeResponse)); + ntlm_free_message_fields_buffer(&(message.NtChallengeResponse)); + ntlm_free_message_fields_buffer(&(message.EncryptedRandomSessionKey)); + return SEC_I_COMPLETE_NEEDED; } diff --git a/winpr/libwinpr/sspi/Negotiate/negotiate.c b/winpr/libwinpr/sspi/Negotiate/negotiate.c index 616c647a7..dab859917 100644 --- a/winpr/libwinpr/sspi/Negotiate/negotiate.c +++ b/winpr/libwinpr/sspi/Negotiate/negotiate.c @@ -113,14 +113,14 @@ SECURITY_STATUS SEC_ENTRY negotiate_QueryContextAttributes(PCtxtHandle phContext } SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { return SEC_E_OK; } SECURITY_STATUS SEC_ENTRY negotiate_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { CREDENTIALS* credentials; diff --git a/winpr/libwinpr/sspi/Schannel/schannel.c b/winpr/libwinpr/sspi/Schannel/schannel.c index b6d755379..4010bf2dd 100644 --- a/winpr/libwinpr/sspi/Schannel/schannel.c +++ b/winpr/libwinpr/sspi/Schannel/schannel.c @@ -96,14 +96,14 @@ SECURITY_STATUS SEC_ENTRY schannel_QueryContextAttributes(PCtxtHandle phContext, } SECURITY_STATUS SEC_ENTRY schannel_AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { return SEC_E_OK; } SECURITY_STATUS SEC_ENTRY schannel_AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { CREDENTIALS* credentials; diff --git a/winpr/libwinpr/sspi/sspi.c b/winpr/libwinpr/sspi/sspi.c index 87697460c..3322c8f7b 100644 --- a/winpr/libwinpr/sspi/sspi.c +++ b/winpr/libwinpr/sspi/sspi.c @@ -23,10 +23,15 @@ #include +#include + #include #include #include +#include +#include + #include "sspi.h" /* Authentication Functions: http://msdn.microsoft.com/en-us/library/windows/desktop/aa374731/ */ @@ -284,8 +289,9 @@ void sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, char* user, char* d if (user) { identity->UserLength = MultiByteToWideChar(CP_UTF8, 0, user, strlen(user), NULL, 0); - identity->User = (UINT16*) malloc(identity->UserLength * sizeof(WCHAR)); + identity->User = (UINT16*) malloc((identity->UserLength + 1) * sizeof(WCHAR)); MultiByteToWideChar(CP_UTF8, 0, user, identity->UserLength, (LPWSTR) identity->User, identity->UserLength * sizeof(WCHAR)); + identity->User[identity->UserLength] = 0; } else { @@ -296,8 +302,9 @@ void sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, char* user, char* d if (domain) { identity->DomainLength = MultiByteToWideChar(CP_UTF8, 0, domain, strlen(domain), NULL, 0); - identity->Domain = (UINT16*) malloc(identity->DomainLength * sizeof(WCHAR)); + identity->Domain = (UINT16*) malloc((identity->DomainLength + 1) * sizeof(WCHAR)); MultiByteToWideChar(CP_UTF8, 0, domain, identity->DomainLength, (LPWSTR) identity->Domain, identity->DomainLength * sizeof(WCHAR)); + identity->Domain[identity->DomainLength] = 0; } else { @@ -308,8 +315,9 @@ void sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, char* user, char* d if (password != NULL) { identity->PasswordLength = MultiByteToWideChar(CP_UTF8, 0, password, strlen(password), NULL, 0); - identity->Password = (UINT16*) malloc(identity->PasswordLength * sizeof(WCHAR)); + identity->Password = (UINT16*) malloc((identity->PasswordLength + 1) * sizeof(WCHAR)); MultiByteToWideChar(CP_UTF8, 0, password, identity->PasswordLength, (LPWSTR) identity->Password, identity->PasswordLength * sizeof(WCHAR)); + identity->Password[identity->PasswordLength] = 0; } else { @@ -332,21 +340,38 @@ void sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDE identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; + identity->User = identity->Domain = identity->Password = NULL; + identity->UserLength = srcIdentity->UserLength; - identity->User = (UINT16*) malloc(identity->UserLength * sizeof(WCHAR)); - CopyMemory(identity->User, srcIdentity->User, identity->UserLength * sizeof(WCHAR)); + + if (identity->UserLength > 0) + { + identity->User = (UINT16*) malloc((identity->UserLength + 1) * sizeof(WCHAR)); + CopyMemory(identity->User, srcIdentity->User, identity->UserLength * sizeof(WCHAR)); + } identity->DomainLength = srcIdentity->DomainLength; - identity->Domain = (UINT16*) malloc(identity->DomainLength * sizeof(WCHAR)); - CopyMemory(identity->Domain, srcIdentity->Domain, identity->DomainLength * sizeof(WCHAR)); + + if (identity->DomainLength > 0) + { + identity->Domain = (UINT16*) malloc((identity->DomainLength + 1) * sizeof(WCHAR)); + CopyMemory(identity->Domain, srcIdentity->Domain, identity->DomainLength * sizeof(WCHAR)); + } identity->PasswordLength = srcIdentity->PasswordLength; - identity->Password = (UINT16*) malloc(identity->PasswordLength * sizeof(WCHAR)); - CopyMemory(identity->Password, srcIdentity->Password, identity->PasswordLength * sizeof(WCHAR)); + + if (identity->PasswordLength > 0) + { + identity->Password = (UINT16*) malloc((identity->PasswordLength + 1) * sizeof(WCHAR)); + CopyMemory(identity->Password, srcIdentity->Password, identity->PasswordLength * sizeof(WCHAR)); + } } void sspi_GlobalInit() { + SSL_load_error_strings(); + SSL_library_init(); + sspi_ContextBufferAllocTableNew(); } @@ -451,7 +476,7 @@ void sspi_ContextBufferFree(void* contextBuffer) /* Package Management */ -SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesW(UINT32* pcPackages, PSecPkgInfoW* ppPackageInfo) +SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesW(ULONG* pcPackages, PSecPkgInfoW* ppPackageInfo) { int index; size_t size; @@ -479,7 +504,7 @@ SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesW(UINT32* pcPackages, PSecPkg return SEC_E_OK; } -SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesA(UINT32* pcPackages, PSecPkgInfoA* ppPackageInfo) +SECURITY_STATUS SEC_ENTRY EnumerateSecurityPackagesA(ULONG* pcPackages, PSecPkgInfoA* ppPackageInfo) { int index; size_t size; @@ -621,7 +646,7 @@ void FreeContextBuffer_QuerySecurityPackageInfo(void* contextBuffer) /* Credential Management */ SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { SECURITY_STATUS status; @@ -640,7 +665,7 @@ SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC } SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage, - ULONG fCredentialUse, PLUID pvLogonID, void* pAuthData, void* pGetKeyFn, + ULONG fCredentialUse, void* pvLogonID, void* pAuthData, SEC_GET_KEY_FN pGetKeyFn, void* pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry) { SECURITY_STATUS status; @@ -658,7 +683,7 @@ SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_ return status; } -SECURITY_STATUS SEC_ENTRY ExportSecurityContext(PCtxtHandle phContext, UINT32 fFlags, PSecBuffer pPackedContext, void* pToken) +SECURITY_STATUS SEC_ENTRY ExportSecurityContext(PCtxtHandle phContext, ULONG fFlags, PSecBuffer pPackedContext, HANDLE* pToken) { return SEC_E_OK; } @@ -687,12 +712,12 @@ SECURITY_STATUS SEC_ENTRY FreeCredentialsHandle(PCredHandle phCredential) return status; } -SECURITY_STATUS SEC_ENTRY ImportSecurityContextW(SEC_WCHAR* pszPackage, PSecBuffer pPackedContext, void* pToken, PCtxtHandle phContext) +SECURITY_STATUS SEC_ENTRY ImportSecurityContextW(SEC_WCHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext) { return SEC_E_OK; } -SECURITY_STATUS SEC_ENTRY ImportSecurityContextA(SEC_CHAR* pszPackage, PSecBuffer pPackedContext, void* pToken, PCtxtHandle phContext) +SECURITY_STATUS SEC_ENTRY ImportSecurityContextA(SEC_CHAR* pszPackage, PSecBuffer pPackedContext, HANDLE pToken, PCtxtHandle phContext) { return SEC_E_OK; } @@ -929,7 +954,7 @@ SECURITY_STATUS SEC_ENTRY QueryContextAttributesA(PCtxtHandle phContext, ULONG u return status; } -SECURITY_STATUS SEC_ENTRY QuerySecurityContextToken(PCtxtHandle phContext, void* phToken) +SECURITY_STATUS SEC_ENTRY QuerySecurityContextToken(PCtxtHandle phContext, HANDLE* phToken) { return SEC_E_OK; } diff --git a/winpr/libwinpr/utils/ntlm.c b/winpr/libwinpr/utils/ntlm.c index 200583ac6..9b99de5ec 100644 --- a/winpr/libwinpr/utils/ntlm.c +++ b/winpr/libwinpr/utils/ntlm.c @@ -27,6 +27,8 @@ #include #include + +#include #include #include #include @@ -149,7 +151,11 @@ BYTE* NTOWFv2FromHashW(BYTE* NtHashV1, LPWSTR User, UINT32 UserLength, LPWSTR Do CopyMemory(buffer, User, UserLength); CharUpperBuffW((LPWSTR) buffer, UserLength / 2); - CopyMemory(&buffer[UserLength], Domain, DomainLength); + + if (DomainLength > 0) + { + CopyMemory(&buffer[UserLength], Domain, DomainLength); + } /* Compute the HMAC-MD5 hash of the above value using the NTLMv1 hash as the key, the result is the NTLMv2 hash */ HMAC(EVP_md5(), (void*) NtHashV1, 16, buffer, UserLength + DomainLength, (void*) NtHash, NULL); diff --git a/winpr/libwinpr/utils/sam.c b/winpr/libwinpr/utils/sam.c index b4cebc685..dfc48f459 100644 --- a/winpr/libwinpr/utils/sam.c +++ b/winpr/libwinpr/utils/sam.c @@ -308,6 +308,8 @@ WINPR_SAM_ENTRY* SamLookupUserW(WINPR_SAM* sam, LPWSTR User, UINT32 UserLength, } } + free(EntryUser); + if (UserMatch && DomainMatch) { Found = 1;