wfreerdp-client: Handle credman domain qualified username correctly

If credentials are read from the Windows credential manager, and the **username** contains the **domain** portion (`domain\username`), a connection couldn't be establish.
This PR parses the username and domain, sets the correct properties in the settings structure pretty much the same way the CLI args handling is doing.
This commit is contained in:
Stefan Koell 2023-09-12 15:56:14 +02:00 committed by akallabeth
parent 88f79c5748
commit c81e045cee
1 changed files with 52 additions and 16 deletions

View File

@ -30,22 +30,21 @@ static PCWSTR ValidateString(const BYTE* pb, ULONG cb)
if (cb % sizeof(WCHAR) != 0)
return 0;
if (*(WCHAR*)(pb + cb - sizeof(WCHAR)))
return 0;
return (PCWSTR)pb;
}
static void AddDefaultSettings_I(rdpSettings* settings, size_t idHostname, size_t idUsername,
size_t idPassword)
size_t idDomain, size_t idPassword)
{
static const PSTR TERMSRV = "TERMSRV/%s";
PSTR TargetName = NULL;
PSTR UserName = NULL;
PSTR Password = NULL;
PWSTR TargetNameW = NULL;
PWSTR ServerHostnameW = NULL;
PWSTR ServerHostNameW = NULL;
PWSTR ParsedUserNameW = NULL;
PWSTR ParsedDomainW = NULL;
PWSTR PasswordNullTerminatedW = NULL;
PCREDENTIALW Credential = { 0 };
PCSTR ServerHostname = freerdp_settings_get_string(settings, idHostname);
@ -82,9 +81,16 @@ static void AddDefaultSettings_I(rdpSettings* settings, size_t idHostname, size_
const WCHAR* PasswordW =
ValidateString(Credential->CredentialBlob, Credential->CredentialBlobSize);
if (PasswordW)
PasswordNullTerminatedW = (PWSTR)calloc(Credential->CredentialBlobSize + 1, sizeof(WCHAR));
if (!PasswordNullTerminatedW)
goto fail;
memcpy(PasswordNullTerminatedW, PasswordW, Credential->CredentialBlobSize * sizeof(WCHAR));
if (PasswordNullTerminatedW)
{
if (!freerdp_settings_set_string_from_utf16(settings, idPassword, PasswordW))
if (!freerdp_settings_set_string_from_utf16(settings, idPassword, PasswordNullTerminatedW))
goto fail;
}
}
@ -95,24 +101,54 @@ static void AddDefaultSettings_I(rdpSettings* settings, size_t idHostname, size_
if (UserNameW)
{
if (!freerdp_settings_set_string_from_utf16(settings, idUsername, UserNameW))
ParsedUserNameW = calloc(CREDUI_MAX_USERNAME_LENGTH + 1, sizeof(WCHAR));
if (!ParsedUserNameW)
goto fail;
ParsedDomainW = calloc(CREDUI_MAX_DOMAIN_TARGET_LENGTH + 1, sizeof(WCHAR));
if (!ParsedDomainW)
goto fail;
DWORD ParseResult =
CredUIParseUserNameW(UserNameW, ParsedUserNameW, CREDUI_MAX_USERNAME_LENGTH + 1,
ParsedDomainW, CREDUI_MAX_DOMAIN_TARGET_LENGTH + 1);
if (ParseResult == NO_ERROR)
{
if (!freerdp_settings_set_string_from_utf16(settings, idUsername, ParsedUserNameW))
goto fail;
if (*ParsedDomainW != 0)
{
if (!freerdp_settings_set_string_from_utf16(settings, idDomain, ParsedDomainW))
goto fail;
}
}
else if (ParseResult == ERROR_INVALID_ACCOUNT_NAME)
{
if (!freerdp_settings_set_string_from_utf16(settings, idUsername, UserNameW))
goto fail;
}
}
}
fail:
CredFree(Credential);
if (Credential)
{
CredFree(Credential);
}
free(TargetName);
free(TargetNameW);
free(ServerHostnameW);
free(UserName);
free(Password);
free(TargetNameW);
free(ServerHostNameW);
free(ParsedUserNameW);
free(ParsedDomainW);
free(PasswordNullTerminatedW);
return;
}
void WINAPI AddDefaultSettings(rdpSettings* settings)
{
AddDefaultSettings_I(settings, FreeRDP_ServerHostname, FreeRDP_Username, FreeRDP_Password);
AddDefaultSettings_I(settings, FreeRDP_GatewayHostname, FreeRDP_GatewayUsername,
FreeRDP_GatewayPassword);
AddDefaultSettings_I(settings, FreeRDP_ServerHostname, FreeRDP_Username, FreeRDP_Domain, FreeRDP_Password);
AddDefaultSettings_I(settings, FreeRDP_GatewayHostname, FreeRDP_GatewayUsername, FreeRDP_GatewayDomain, FreeRDP_GatewayPassword);
}