Fixed /pth: Consistently treat the hash offset to password length.
This commit is contained in:
parent
1a27f28ba9
commit
5b961e9c75
@ -225,6 +225,8 @@
|
||||
#define LB_CLIENT_TSV_URL 0x00001000
|
||||
#define LB_SERVER_TSV_CAPABLE 0x00002000
|
||||
|
||||
#define LB_PASSWORD_MAX_LENGTH 512
|
||||
|
||||
/* Keyboard Hook */
|
||||
#define KEYBOARD_HOOK_LOCAL 0
|
||||
#define KEYBOARD_HOOK_REMOTE 1
|
||||
|
@ -517,7 +517,7 @@ static BOOL rdp_read_info_packet(rdpRdp* rdp, wStream* s)
|
||||
* This size excludes (!) the length of the mandatory null terminator.
|
||||
* Maximum value including the mandatory null terminator: 512
|
||||
*/
|
||||
if ((cbPassword % 2) || cbPassword > 512)
|
||||
if ((cbPassword % 2) || cbPassword > LB_PASSWORD_MAX_LENGTH)
|
||||
{
|
||||
WLog_ERR(TAG, "protocol error: invalid cbPassword value: %"PRIu16"", cbPassword);
|
||||
return FALSE;
|
||||
@ -639,11 +639,11 @@ static void rdp_write_info_packet(rdpRdp* rdp, wStream* s)
|
||||
BOOL usedPasswordCookie = FALSE;
|
||||
rdpSettings* settings = rdp->settings;
|
||||
flags = INFO_MOUSE |
|
||||
INFO_UNICODE |
|
||||
INFO_LOGONERRORS |
|
||||
INFO_MAXIMIZESHELL |
|
||||
INFO_ENABLEWINDOWSKEY |
|
||||
INFO_DISABLECTRLALTDEL;
|
||||
INFO_UNICODE |
|
||||
INFO_LOGONERRORS |
|
||||
INFO_MAXIMIZESHELL |
|
||||
INFO_ENABLEWINDOWSKEY |
|
||||
INFO_DISABLECTRLALTDEL;
|
||||
|
||||
if (settings->AudioCapture)
|
||||
flags |= INFO_AUDIOCAPTURE;
|
||||
|
@ -150,7 +150,12 @@ void nla_identity_free(SEC_WINNT_AUTH_IDENTITY* identity)
|
||||
|
||||
if (identity->Password)
|
||||
{
|
||||
memset(identity->Password, 0, identity->PasswordLength * 2);
|
||||
size_t len = identity->PasswordLength;
|
||||
|
||||
if (len > LB_PASSWORD_MAX_LENGTH) /* [pth] Password hash */
|
||||
len -= LB_PASSWORD_MAX_LENGTH;
|
||||
|
||||
memset(identity->Password, 0, len * 2);
|
||||
free(identity->Password);
|
||||
}
|
||||
|
||||
@ -286,7 +291,7 @@ static int nla_client_init(rdpNla* nla)
|
||||
* Multiply password hash length by 64 to obtain a length exceeding
|
||||
* the maximum (256) and use it this for hash identification in WinPR.
|
||||
*/
|
||||
identity->PasswordLength = 32 * 64; /* 2048 */
|
||||
identity->PasswordLength += LB_PASSWORD_MAX_LENGTH;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1941,7 +1946,7 @@ static int nla_decode_ts_request(rdpNla* nla, wStream* s)
|
||||
if (nla->peerVersion == 0)
|
||||
{
|
||||
WLog_DBG(TAG, "CredSSP protocol support %"PRIu32", peer supports %"PRIu32,
|
||||
nla->version, version);
|
||||
nla->version, version);
|
||||
nla->peerVersion = version;
|
||||
}
|
||||
|
||||
@ -1949,7 +1954,7 @@ static int nla_decode_ts_request(rdpNla* nla, wStream* s)
|
||||
if (nla->peerVersion != version)
|
||||
{
|
||||
WLog_ERR(TAG, "CredSSP peer changed protocol version from %"PRIu32" to %"PRIu32,
|
||||
nla->peerVersion, version);
|
||||
nla->peerVersion, version);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -2247,7 +2252,6 @@ rdpNla* nla_new(freerdp* instance, rdpTransport* transport, rdpSettings* setting
|
||||
nla->sendSeqNum = 0;
|
||||
nla->recvSeqNum = 0;
|
||||
nla->version = 6;
|
||||
|
||||
ZeroMemory(&nla->ClientNonce, sizeof(SecBuffer));
|
||||
ZeroMemory(&nla->negoToken, sizeof(SecBuffer));
|
||||
ZeroMemory(&nla->pubKeyAuth, sizeof(SecBuffer));
|
||||
@ -2308,7 +2312,6 @@ rdpNla* nla_new(freerdp* instance, rdpTransport* transport, rdpSettings* setting
|
||||
}
|
||||
|
||||
return nla;
|
||||
|
||||
cleanup:
|
||||
nla_free(nla);
|
||||
return NULL;
|
||||
|
@ -357,7 +357,7 @@ static BOOL rdp_recv_server_redirection_pdu(rdpRdp* rdp, wStream* s)
|
||||
if (Stream_GetRemainingLength(s) < redirection->PasswordLength)
|
||||
return -1;
|
||||
|
||||
if (redirection->PasswordLength > 512)
|
||||
if (redirection->PasswordLength > LB_PASSWORD_MAX_LENGTH)
|
||||
return -1;
|
||||
|
||||
redirection->Password = (BYTE*) calloc(1, redirection->PasswordLength + sizeof(WCHAR));
|
||||
|
@ -259,8 +259,8 @@ int ntlm_convert_password_hash(NTLM_CONTEXT* context, BYTE* hash)
|
||||
char* PasswordHash = NULL;
|
||||
UINT32 PasswordHashLength = 0;
|
||||
SSPI_CREDENTIALS* credentials = context->credentials;
|
||||
/* Password contains a password hash of length (PasswordLength / SSPI_CREDENTIALS_HASH_LENGTH_FACTOR) */
|
||||
PasswordHashLength = credentials->identity.PasswordLength / SSPI_CREDENTIALS_HASH_LENGTH_FACTOR;
|
||||
/* Password contains a password hash of length (PasswordLength - SSPI_CREDENTIALS_HASH_LENGTH_OFFSET) */
|
||||
PasswordHashLength = credentials->identity.PasswordLength - SSPI_CREDENTIALS_HASH_LENGTH_OFFSET;
|
||||
status = ConvertFromUnicode(CP_UTF8, 0, (LPCWSTR) credentials->identity.Password,
|
||||
PasswordHashLength, &PasswordHash, 0, NULL, NULL);
|
||||
|
||||
@ -280,7 +280,7 @@ int ntlm_convert_password_hash(NTLM_CONTEXT* context, BYTE* hash)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ntlm_compute_ntlm_v2_hash(NTLM_CONTEXT* context, BYTE* hash)
|
||||
static int ntlm_compute_ntlm_v2_hash(NTLM_CONTEXT* context, BYTE* hash)
|
||||
{
|
||||
SSPI_CREDENTIALS* credentials = context->credentials;
|
||||
#ifdef WITH_DEBUG_NTLM
|
||||
@ -316,7 +316,7 @@ int ntlm_compute_ntlm_v2_hash(NTLM_CONTEXT* context, BYTE* hash)
|
||||
(LPWSTR) credentials->identity.Domain, credentials->identity.DomainLength * 2,
|
||||
(BYTE*) hash);
|
||||
}
|
||||
else if (credentials->identity.PasswordLength > 256)
|
||||
else if (credentials->identity.PasswordLength > SSPI_CREDENTIALS_HASH_LENGTH_OFFSET)
|
||||
{
|
||||
/* Special case for WinPR: password hash */
|
||||
if (ntlm_convert_password_hash(context, context->NtlmHash) < 0)
|
||||
@ -349,8 +349,8 @@ int ntlm_compute_ntlm_v2_hash(NTLM_CONTEXT* context, BYTE* hash)
|
||||
|
||||
ret = context->HashCallback(context->HashCallbackArg, &credentials->identity, &proofValue,
|
||||
context->EncryptedRandomSessionKey,
|
||||
(&context->AUTHENTICATE_MESSAGE)->MessageIntegrityCheck,
|
||||
&micValue, hash);
|
||||
(&context->AUTHENTICATE_MESSAGE)->MessageIntegrityCheck,
|
||||
&micValue, hash);
|
||||
sspi_SecBufferFree(&proofValue);
|
||||
sspi_SecBufferFree(&micValue);
|
||||
return ret ? 1 : -1;
|
||||
@ -723,14 +723,13 @@ void ntlm_init_rc4_seal_states(NTLM_CONTEXT* context)
|
||||
}
|
||||
}
|
||||
|
||||
void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context, BYTE *mic, UINT32 size)
|
||||
void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context, BYTE* mic, UINT32 size)
|
||||
{
|
||||
/*
|
||||
* Compute the HMAC-MD5 hash of ConcatenationOf(NEGOTIATE_MESSAGE,
|
||||
* CHALLENGE_MESSAGE, AUTHENTICATE_MESSAGE) using the ExportedSessionKey
|
||||
*/
|
||||
WINPR_HMAC_CTX* hmac = winpr_HMAC_New();
|
||||
|
||||
assert(size >= WINPR_MD5_DIGEST_LENGTH);
|
||||
|
||||
if (!hmac)
|
||||
|
@ -38,7 +38,6 @@ void ntlm_output_channel_bindings(NTLM_CONTEXT* context);
|
||||
void ntlm_current_time(BYTE* timestamp);
|
||||
void ntlm_generate_timestamp(NTLM_CONTEXT* context);
|
||||
|
||||
int ntlm_compute_ntlm_v2_hash(NTLM_CONTEXT* context, BYTE* hash);
|
||||
int ntlm_compute_lm_v2_response(NTLM_CONTEXT* context);
|
||||
int ntlm_compute_ntlm_v2_response(NTLM_CONTEXT* context);
|
||||
|
||||
@ -57,6 +56,6 @@ void ntlm_generate_client_sealing_key(NTLM_CONTEXT* context);
|
||||
void ntlm_generate_server_sealing_key(NTLM_CONTEXT* context);
|
||||
void ntlm_init_rc4_seal_states(NTLM_CONTEXT* context);
|
||||
|
||||
void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context, BYTE *mic, UINT32 size);
|
||||
void ntlm_compute_message_integrity_check(NTLM_CONTEXT* context, BYTE* mic, UINT32 size);
|
||||
|
||||
#endif /* WINPR_AUTH_NTLM_COMPUTE_H */
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#define SSPI_CREDENTIALS_PASSWORD_HASH 0x00000001
|
||||
|
||||
#define SSPI_CREDENTIALS_HASH_LENGTH_FACTOR 64
|
||||
#define SSPI_CREDENTIALS_HASH_LENGTH_OFFSET 512
|
||||
|
||||
struct _SSPI_CREDENTIALS
|
||||
{
|
||||
|
@ -242,6 +242,9 @@ void sspi_CredentialsFree(SSPI_CREDENTIALS* credentials)
|
||||
domainLength = credentials->identity.DomainLength;
|
||||
passwordLength = credentials->identity.PasswordLength;
|
||||
|
||||
if (passwordLength > SSPI_CREDENTIALS_HASH_LENGTH_OFFSET) /* [pth] */
|
||||
passwordLength -= SSPI_CREDENTIALS_HASH_LENGTH_OFFSET;
|
||||
|
||||
if (credentials->identity.Flags & SEC_WINNT_AUTH_IDENTITY_UNICODE)
|
||||
{
|
||||
userLength *= 2;
|
||||
@ -413,7 +416,7 @@ int sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDEN
|
||||
{
|
||||
int status;
|
||||
|
||||
if (srcIdentity->Flags == SEC_WINNT_AUTH_IDENTITY_ANSI)
|
||||
if (srcIdentity->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI)
|
||||
{
|
||||
status = sspi_SetAuthIdentity(identity, (char*) srcIdentity->User,
|
||||
(char*) srcIdentity->Domain, (char*) srcIdentity->Password);
|
||||
@ -421,11 +424,12 @@ int sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDEN
|
||||
if (status <= 0)
|
||||
return -1;
|
||||
|
||||
identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
identity->Flags &= ~SEC_WINNT_AUTH_IDENTITY_ANSI;
|
||||
identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
return 1;
|
||||
}
|
||||
|
||||
identity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
identity->Flags |= SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
||||
/* login/password authentication */
|
||||
identity->User = identity->Domain = identity->Password = NULL;
|
||||
identity->UserLength = srcIdentity->UserLength;
|
||||
@ -456,8 +460,8 @@ int sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDEN
|
||||
|
||||
identity->PasswordLength = srcIdentity->PasswordLength;
|
||||
|
||||
if (identity->PasswordLength > 256)
|
||||
identity->PasswordLength /= SSPI_CREDENTIALS_HASH_LENGTH_FACTOR;
|
||||
if (identity->PasswordLength > SSPI_CREDENTIALS_HASH_LENGTH_OFFSET)
|
||||
identity->PasswordLength -= SSPI_CREDENTIALS_HASH_LENGTH_OFFSET;
|
||||
|
||||
if (srcIdentity->Password)
|
||||
{
|
||||
@ -470,6 +474,7 @@ int sspi_CopyAuthIdentity(SEC_WINNT_AUTH_IDENTITY* identity, SEC_WINNT_AUTH_IDEN
|
||||
identity->Password[identity->PasswordLength] = 0;
|
||||
}
|
||||
|
||||
identity->PasswordLength = srcIdentity->PasswordLength;
|
||||
/* End of login/password authentication */
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user