diff --git a/libfreerdp/core/gateway/ntlm.c b/libfreerdp/core/gateway/ntlm.c index df22e4fe1..01a2ce545 100644 --- a/libfreerdp/core/gateway/ntlm.c +++ b/libfreerdp/core/gateway/ntlm.c @@ -84,7 +84,7 @@ BOOL ntlm_client_init(rdpNtlm* ntlm, BOOL http, LPCSTR user, LPCSTR domain, LPCS if (!ntlm->table) return FALSE; - sspi_SetAuthIdentity(&(ntlm->identity), user, domain, password); + sspi_SetAuthIdentityA(&(ntlm->identity), user, domain, password); status = ntlm->table->QuerySecurityPackageInfo(NTLM_SSP_NAME, &ntlm->pPackageInfo); if (status != SEC_E_OK) diff --git a/libfreerdp/core/nla.c b/libfreerdp/core/nla.c index f0de17c7a..260454b01 100644 --- a/libfreerdp/core/nla.c +++ b/libfreerdp/core/nla.c @@ -783,8 +783,8 @@ static BOOL nla_client_setup_identity(rdpNla* nla) { if (settings->PasswordHash && strlen(settings->PasswordHash) == 32) { - if (sspi_SetAuthIdentity(nla->identity, settings->Username, settings->Domain, - settings->PasswordHash) < 0) + if (sspi_SetAuthIdentityA(nla->identity, settings->Username, settings->Domain, + settings->PasswordHash) < 0) return -1; /** @@ -799,8 +799,8 @@ static BOOL nla_client_setup_identity(rdpNla* nla) if (usePassword) { - if (sspi_SetAuthIdentity(nla->identity, settings->Username, settings->Domain, - settings->Password) < 0) + if (sspi_SetAuthIdentityA(nla->identity, settings->Username, settings->Domain, + settings->Password) < 0) return -1; } } @@ -2006,6 +2006,12 @@ fail: BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s) { size_t length; + size_t userLen = 0; + size_t domainLen = 0; + size_t passwordLen = 0; + WCHAR* user = NULL; + WCHAR* domain = NULL; + WCHAR* password = NULL; WINPR_ASSERT(nla); WINPR_ASSERT(s); @@ -2036,61 +2042,37 @@ BOOL nla_read_ts_password_creds(rdpNla* nla, wStream* s) return FALSE; } - nla->identity->DomainLength = (UINT32)length; + domainLen = length / sizeof(WCHAR); + if (length > 0) + domain = Stream_Pointer(s); - if (nla->identity->DomainLength > 0) - { - nla->identity->Domain = (UINT16*)malloc(length); - - if (!nla->identity->Domain) - return FALSE; - - CopyMemory(nla->identity->Domain, Stream_Pointer(s), nla->identity->DomainLength); - Stream_Seek(s, nla->identity->DomainLength); - nla->identity->DomainLength /= 2; - } + if (!Stream_SafeSeek(s, length)) + return FALSE; /* [1] userName (OCTET STRING) */ if (!ber_read_contextual_tag(s, 1, &length, TRUE) || !ber_read_octet_string_tag(s, &length)) - { return FALSE; - } - nla->identity->UserLength = (UINT32)length; + userLen = length / sizeof(WCHAR); + if (length > 0) + user = Stream_Pointer(s); - if (nla->identity->UserLength > 0) - { - nla->identity->User = (UINT16*)malloc(length); - - if (!nla->identity->User) - return FALSE; - - CopyMemory(nla->identity->User, Stream_Pointer(s), nla->identity->UserLength); - Stream_Seek(s, nla->identity->UserLength); - nla->identity->UserLength /= 2; - } + if (!Stream_SafeSeek(s, length)) + return FALSE; /* [2] password (OCTET STRING) */ if (!ber_read_contextual_tag(s, 2, &length, TRUE) || !ber_read_octet_string_tag(s, &length)) - { return FALSE; - } - nla->identity->PasswordLength = (UINT32)length; + passwordLen = length / sizeof(WCHAR); + if (length > 0) + password = Stream_Pointer(s); - if (nla->identity->PasswordLength > 0) - { - nla->identity->Password = (UINT16*)malloc(length); + if (!Stream_SafeSeek(s, length)) + return FALSE; - if (!nla->identity->Password) - return FALSE; - - CopyMemory(nla->identity->Password, Stream_Pointer(s), nla->identity->PasswordLength); - Stream_Seek(s, nla->identity->PasswordLength); - nla->identity->PasswordLength /= 2; - } - - return TRUE; + return sspi_SetAuthIdentityWithLengthW(nla->identity, user, userLen, domain, domainLen, + password, passwordLen) > 0; } static BOOL nla_read_ts_credentials(rdpNla* nla, SecBuffer* data, size_t offset) diff --git a/winpr/include/winpr/sspi.h b/winpr/include/winpr/sspi.h index 0387df5b5..8c4a1c3c8 100644 --- a/winpr/include/winpr/sspi.h +++ b/winpr/include/winpr/sspi.h @@ -1228,8 +1228,15 @@ extern "C" WINPR_API void* sspi_SecBufferAlloc(PSecBuffer SecBuffer, ULONG size); WINPR_API void sspi_SecBufferFree(PSecBuffer SecBuffer); - WINPR_API int sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, const char* user, - const char* domain, const char* password); +#define sspi_SetAuthIdentity sspi_SetAuthIdentityA + WINPR_API int sspi_SetAuthIdentityA(SEC_WINNT_AUTH_IDENTITY* identity, const char* user, + const char* domain, const char* password); + WINPR_API int sspi_SetAuthIdentityW(SEC_WINNT_AUTH_IDENTITY* identity, const WCHAR* user, + const WCHAR* domain, const WCHAR* password); + WINPR_API int sspi_SetAuthIdentityWithLengthW(SEC_WINNT_AUTH_IDENTITY* identity, + const WCHAR* user, size_t userLen, + const WCHAR* domain, size_t domainLen, + const WCHAR* password, size_t passwordLen); WINPR_API int sspi_SetAuthIdentityWithUnicodePassword(SEC_WINNT_AUTH_IDENTITY* identity, const char* user, const char* domain, LPWSTR password, ULONG passwordLength); diff --git a/winpr/libwinpr/sspi/sspi_winpr.c b/winpr/libwinpr/sspi/sspi_winpr.c index df7504bd7..a6b564641 100644 --- a/winpr/libwinpr/sspi/sspi_winpr.c +++ b/winpr/libwinpr/sspi/sspi_winpr.c @@ -19,7 +19,7 @@ */ #include - +#include #include #include @@ -318,8 +318,58 @@ void sspi_SecureHandleFree(SecHandle* handle) free(handle); } -int sspi_SetAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, const char* user, const char* domain, - const char* password) +int sspi_SetAuthIdentityW(SEC_WINNT_AUTH_IDENTITY* identity, const WCHAR* user, const WCHAR* domain, + const WCHAR* password) +{ + return sspi_SetAuthIdentityWithLengthW(identity, user, user ? _wcslen(user) : 0, domain, + domain ? _wcslen(domain) : 0, password, + password ? _wcslen(password) : 0); +} + +static BOOL copy(WCHAR** dst, UINT32* dstLen, const WCHAR* what, size_t len) +{ + WINPR_ASSERT(dst); + WINPR_ASSERT(dstLen); + WINPR_ASSERT(what); + WINPR_ASSERT(len > 0); + WINPR_ASSERT(_wcsnlen(what, len) == len); + + *dst = calloc(sizeof(WCHAR), len + 1); + if (!*dst) + return FALSE; + memcpy(*dst, what, len * sizeof(WCHAR)); + *dstLen = len; + return TRUE; +} + +int sspi_SetAuthIdentityWithLengthW(SEC_WINNT_AUTH_IDENTITY* identity, const WCHAR* user, + size_t userLen, const WCHAR* domain, size_t domainLen, + const WCHAR* password, size_t passwordLen) +{ + WINPR_ASSERT(identity); + sspi_FreeAuthIdentity(identity); + identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; + if (user) + { + if (!copy(&identity->User, &identity->UserLength, user, userLen)) + return -1; + } + if (domain) + { + if (!copy(&identity->Domain, &identity->DomainLength, domain, domainLen)) + return -1; + } + if (password) + { + if (!copy(&identity->Password, &identity->PasswordLength, password, passwordLen)) + return -1; + } + + return 1; +} + +int sspi_SetAuthIdentityA(SEC_WINNT_AUTH_IDENTITY* identity, const char* user, const char* domain, + const char* password) { int rc; int unicodePasswordLenW;