mirror of
https://github.com/reactos/reactos.git
synced 2024-09-09 20:30:04 +00:00
[ADVAPI32]
- Fix buffer handling in CredMarshalCredential/CredUnmarshalCredential. Fixes stack corruption during advapi32:cred CORE-7242 #resolve svn path=/trunk/; revision=62593
This commit is contained in:
parent
e2359b3724
commit
059daa9d85
|
@ -2008,18 +2008,13 @@ BOOL WINAPI CredMarshalCredentialW( CRED_MARSHAL_TYPE type, PVOID cred, LPWSTR *
|
||||||
{
|
{
|
||||||
case CertCredential:
|
case CertCredential:
|
||||||
{
|
{
|
||||||
char hash[CERT_HASH_LENGTH + 2];
|
size = (sizeof(cert->rgbHashOfCert) + 2) * 4 / 3;
|
||||||
|
|
||||||
memcpy( hash, cert->rgbHashOfCert, sizeof(cert->rgbHashOfCert) );
|
|
||||||
memset( hash + sizeof(cert->rgbHashOfCert), 0, sizeof(hash) - sizeof(cert->rgbHashOfCert) );
|
|
||||||
|
|
||||||
size = sizeof(hash) * 4 / 3;
|
|
||||||
if (!(p = HeapAlloc( GetProcessHeap(), 0, (size + 4) * sizeof(WCHAR) ))) return FALSE;
|
if (!(p = HeapAlloc( GetProcessHeap(), 0, (size + 4) * sizeof(WCHAR) ))) return FALSE;
|
||||||
p[0] = '@';
|
p[0] = '@';
|
||||||
p[1] = '@';
|
p[1] = '@';
|
||||||
p[2] = 'A' + type;
|
p[2] = 'A' + type;
|
||||||
len = cred_encode( (const char *)hash, sizeof(hash), p + 3 );
|
len = cred_encode( (const char *)cert->rgbHashOfCert, sizeof(cert->rgbHashOfCert), p + 3 );
|
||||||
p[len] = 0;
|
p[len + 3] = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UsernameTargetCredential:
|
case UsernameTargetCredential:
|
||||||
|
@ -2105,7 +2100,6 @@ static BOOL cred_decode( const WCHAR *cred, unsigned int len, char *buf )
|
||||||
|
|
||||||
buf[i + 0] = (c1 << 6) | c0;
|
buf[i + 0] = (c1 << 6) | c0;
|
||||||
buf[i + 1] = (c2 << 4) | (c1 >> 2);
|
buf[i + 1] = (c2 << 4) | (c1 >> 2);
|
||||||
buf[i + 2] = c2 >> 4;
|
|
||||||
}
|
}
|
||||||
else if (len == 2)
|
else if (len == 2)
|
||||||
{
|
{
|
||||||
|
@ -2113,16 +2107,10 @@ static BOOL cred_decode( const WCHAR *cred, unsigned int len, char *buf )
|
||||||
if ((c1 = char_decode( p[1] )) > 63) return FALSE;
|
if ((c1 = char_decode( p[1] )) > 63) return FALSE;
|
||||||
|
|
||||||
buf[i + 0] = (c1 << 6) | c0;
|
buf[i + 0] = (c1 << 6) | c0;
|
||||||
buf[i + 1] = c1 >> 2;
|
|
||||||
buf[i + 2] = 0;
|
|
||||||
}
|
}
|
||||||
else if (len == 1)
|
else if (len == 1)
|
||||||
{
|
{
|
||||||
if ((c0 = char_decode( p[0] )) > 63) return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
buf[i + 0] = c0;
|
|
||||||
buf[i + 1] = 0;
|
|
||||||
buf[i + 2] = 0;
|
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -2136,17 +2124,19 @@ BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVO
|
||||||
|
|
||||||
TRACE("%s, %p, %p\n", debugstr_w(cred), type, out);
|
TRACE("%s, %p, %p\n", debugstr_w(cred), type, out);
|
||||||
|
|
||||||
if (!cred || cred[0] != '@' || cred[1] != '@' || !cred[2] || !cred[3])
|
if (!cred || cred[0] != '@' || cred[1] != '@' ||
|
||||||
|
char_decode( cred[2] ) > 63)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_INVALID_PARAMETER );
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
len = strlenW( cred + 3 );
|
len = strlenW( cred + 3 );
|
||||||
switch (cred[2] - 'A')
|
*type = char_decode( cred[2] );
|
||||||
|
switch (*type)
|
||||||
{
|
{
|
||||||
case CertCredential:
|
case CertCredential:
|
||||||
{
|
{
|
||||||
char hash[CERT_HASH_LENGTH + 2];
|
char hash[CERT_HASH_LENGTH];
|
||||||
CERT_CREDENTIAL_INFO *cert;
|
CERT_CREDENTIAL_INFO *cert;
|
||||||
|
|
||||||
if (len != 27 || !cred_decode( cred + 3, len, hash ))
|
if (len != 27 || !cred_decode( cred + 3, len, hash ))
|
||||||
|
@ -2157,17 +2147,16 @@ BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVO
|
||||||
if (!(cert = HeapAlloc( GetProcessHeap(), 0, sizeof(*cert) ))) return FALSE;
|
if (!(cert = HeapAlloc( GetProcessHeap(), 0, sizeof(*cert) ))) return FALSE;
|
||||||
memcpy( cert->rgbHashOfCert, hash, sizeof(cert->rgbHashOfCert) );
|
memcpy( cert->rgbHashOfCert, hash, sizeof(cert->rgbHashOfCert) );
|
||||||
cert->cbSize = sizeof(*cert);
|
cert->cbSize = sizeof(*cert);
|
||||||
*type = CertCredential;
|
|
||||||
*out = cert;
|
*out = cert;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UsernameTargetCredential:
|
case UsernameTargetCredential:
|
||||||
{
|
{
|
||||||
USERNAME_TARGET_CREDENTIAL_INFO *target;
|
USERNAME_TARGET_CREDENTIAL_INFO *target;
|
||||||
ULONGLONG size = 0;
|
DWORD size;
|
||||||
|
|
||||||
if (len < 9 || !cred_decode( cred + 3, 6, (char *)&size ) ||
|
if (len < 9 || !cred_decode( cred + 3, 6, (char *)&size ) ||
|
||||||
!size || size % sizeof(WCHAR) || size > INT_MAX)
|
size % sizeof(WCHAR) || len - 6 != (size * 4 + 2) / 3)
|
||||||
{
|
{
|
||||||
SetLastError( ERROR_INVALID_PARAMETER );
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -2181,7 +2170,6 @@ BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVO
|
||||||
}
|
}
|
||||||
target->UserName = (WCHAR *)(target + 1);
|
target->UserName = (WCHAR *)(target + 1);
|
||||||
target->UserName[size / sizeof(WCHAR)] = 0;
|
target->UserName[size / sizeof(WCHAR)] = 0;
|
||||||
*type = UsernameTargetCredential;
|
|
||||||
*out = target;
|
*out = target;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2189,7 +2177,8 @@ BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVO
|
||||||
FIXME("BinaryBlobCredential not implemented\n");
|
FIXME("BinaryBlobCredential not implemented\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
default:
|
default:
|
||||||
WARN("unhandled type %u\n", cred[2] - 'A');
|
WARN("unhandled type %u\n", *type);
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -2213,7 +2202,7 @@ BOOL WINAPI CredIsMarshaledCredentialW(LPCWSTR name)
|
||||||
|
|
||||||
if (name && name[0] == '@' && name[1] == '@' && name[2] > 'A' && name[3])
|
if (name && name[0] == '@' && name[1] == '@' && name[2] > 'A' && name[3])
|
||||||
{
|
{
|
||||||
char hash[CERT_HASH_LENGTH + 2];
|
char hash[CERT_HASH_LENGTH];
|
||||||
int len = strlenW(name + 3 );
|
int len = strlenW(name + 3 );
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue