advapi32: Implement CredMarshalCredential and CredUnmarshalCredential.
This commit is contained in:
parent
1cee1891fd
commit
d5d2f01d3e
|
@ -148,8 +148,8 @@
|
||||||
# @ stub CredIsMarshaledCredentialW
|
# @ stub CredIsMarshaledCredentialW
|
||||||
# @ stub CredIsProtectedA
|
# @ stub CredIsProtectedA
|
||||||
# @ stub CredIsProtectedW
|
# @ stub CredIsProtectedW
|
||||||
# @ stub CredMarshalCredentialA
|
@ stdcall CredMarshalCredentialA(long ptr ptr)
|
||||||
# @ stub CredMarshalCredentialW
|
@ stdcall CredMarshalCredentialW(long ptr ptr)
|
||||||
# @ stub CredpConvertOneCredentialSize
|
# @ stub CredpConvertOneCredentialSize
|
||||||
# @ stub CredpEncodeSecret
|
# @ stub CredpEncodeSecret
|
||||||
@ stub CredProfileLoaded
|
@ stub CredProfileLoaded
|
||||||
|
@ -164,8 +164,8 @@
|
||||||
# @ stub CredRenameA
|
# @ stub CredRenameA
|
||||||
# @ stub CredRenameW
|
# @ stub CredRenameW
|
||||||
# @ stub CredRestoreCredentials
|
# @ stub CredRestoreCredentials
|
||||||
# @ stub CredUnmarshalCredentialA
|
@ stdcall CredUnmarshalCredentialA(str ptr ptr)
|
||||||
# @ stub CredUnmarshalCredentialW
|
@ stdcall CredUnmarshalCredentialW(wstr ptr ptr)
|
||||||
# @ stub CredUnprotectA
|
# @ stub CredUnprotectA
|
||||||
# @ stub CredUnprotectW
|
# @ stub CredUnprotectW
|
||||||
@ stdcall CredWriteA(ptr long)
|
@ stdcall CredWriteA(ptr long)
|
||||||
|
|
|
@ -1900,3 +1900,264 @@ WINADVAPI BOOL WINAPI CredGetSessionTypes(DWORD persistCount, LPDWORD persists)
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* CredMarshalCredentialA [ADVAPI32.@]
|
||||||
|
*/
|
||||||
|
BOOL WINAPI CredMarshalCredentialA( CRED_MARSHAL_TYPE type, PVOID cred, LPSTR *out )
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
WCHAR *outW;
|
||||||
|
|
||||||
|
TRACE("%u, %p, %p\n", type, cred, out);
|
||||||
|
|
||||||
|
if ((ret = CredMarshalCredentialW( type, cred, &outW )))
|
||||||
|
{
|
||||||
|
int len = WideCharToMultiByte( CP_ACP, 0, outW, -1, NULL, 0, NULL, NULL );
|
||||||
|
if (!(*out = HeapAlloc( GetProcessHeap(), 0, len )))
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, outW );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
WideCharToMultiByte( CP_ACP, 0, outW, -1, *out, len, NULL, NULL );
|
||||||
|
HeapFree( GetProcessHeap(), 0, outW );
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static UINT cred_encode( const char *bin, unsigned int len, WCHAR *cred )
|
||||||
|
{
|
||||||
|
static char enc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#-";
|
||||||
|
UINT n = 0, x;
|
||||||
|
|
||||||
|
while (len > 0)
|
||||||
|
{
|
||||||
|
cred[n++] = enc[bin[0] & 0x3f];
|
||||||
|
x = (bin[0] & 0xc0) >> 6;
|
||||||
|
if (len == 1)
|
||||||
|
{
|
||||||
|
cred[n++] = enc[x];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cred[n++] = enc[((bin[1] & 0xf) << 2) | x];
|
||||||
|
x = (bin[1] & 0xf0) >> 4;
|
||||||
|
if (len == 2)
|
||||||
|
{
|
||||||
|
cred[n++] = enc[x];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cred[n++] = enc[((bin[2] & 0x3) << 4) | x];
|
||||||
|
cred[n++] = enc[(bin[2] & 0xfc) >> 2];
|
||||||
|
bin += 3;
|
||||||
|
len -= 3;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* CredMarshalCredentialW [ADVAPI32.@]
|
||||||
|
*/
|
||||||
|
BOOL WINAPI CredMarshalCredentialW( CRED_MARSHAL_TYPE type, PVOID cred, LPWSTR *out )
|
||||||
|
{
|
||||||
|
CERT_CREDENTIAL_INFO *cert = cred;
|
||||||
|
USERNAME_TARGET_CREDENTIAL_INFO *target = cred;
|
||||||
|
DWORD len, size;
|
||||||
|
WCHAR *p;
|
||||||
|
|
||||||
|
TRACE("%u, %p, %p\n", type, cred, out);
|
||||||
|
|
||||||
|
if (!cred || (type == CertCredential && cert->cbSize < sizeof(*cert)) ||
|
||||||
|
(type != CertCredential && type != UsernameTargetCredential && type != BinaryBlobCredential) ||
|
||||||
|
(type == UsernameTargetCredential && (!target->UserName || !target->UserName[0])))
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case CertCredential:
|
||||||
|
{
|
||||||
|
char hash[CERT_HASH_LENGTH + 2];
|
||||||
|
|
||||||
|
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;
|
||||||
|
p[0] = '@';
|
||||||
|
p[1] = '@';
|
||||||
|
p[2] = 'A' + type;
|
||||||
|
len = cred_encode( (const char *)hash, sizeof(hash), p + 3 );
|
||||||
|
p[len] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case UsernameTargetCredential:
|
||||||
|
{
|
||||||
|
len = strlenW( target->UserName );
|
||||||
|
size = (sizeof(DWORD) + len * sizeof(WCHAR) + 2) * 4 / 3;
|
||||||
|
if (!(p = HeapAlloc( GetProcessHeap(), 0, (size + 4) * sizeof(WCHAR) ))) return FALSE;
|
||||||
|
p[0] = '@';
|
||||||
|
p[1] = '@';
|
||||||
|
p[2] = 'A' + type;
|
||||||
|
size = len * sizeof(WCHAR);
|
||||||
|
len = cred_encode( (const char *)&size, sizeof(DWORD), p + 3 );
|
||||||
|
len += cred_encode( (const char *)target->UserName, size, p + 3 + len );
|
||||||
|
p[len + 3] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinaryBlobCredential:
|
||||||
|
FIXME("BinaryBlobCredential not implemented\n");
|
||||||
|
return FALSE;
|
||||||
|
default:
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*out = p;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* CredUnmarshalCredentialA [ADVAPI32.@]
|
||||||
|
*/
|
||||||
|
BOOL WINAPI CredUnmarshalCredentialA( LPCSTR cred, PCRED_MARSHAL_TYPE type, PVOID *out )
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
WCHAR *credW = NULL;
|
||||||
|
|
||||||
|
TRACE("%s, %p, %p\n", debugstr_a(cred), type, out);
|
||||||
|
|
||||||
|
if (cred)
|
||||||
|
{
|
||||||
|
int len = MultiByteToWideChar( CP_ACP, 0, cred, -1, NULL, 0 );
|
||||||
|
if (!(credW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
|
||||||
|
MultiByteToWideChar( CP_ACP, 0, cred, -1, credW, len );
|
||||||
|
}
|
||||||
|
ret = CredUnmarshalCredentialW( credW, type, out );
|
||||||
|
HeapFree( GetProcessHeap(), 0, credW );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char char_decode( WCHAR c )
|
||||||
|
{
|
||||||
|
if (c >= 'A' && c <= 'Z') return c - 'A';
|
||||||
|
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
|
||||||
|
if (c >= '0' && c <= '9') return c - '0' + 52;
|
||||||
|
if (c == '#') return 62;
|
||||||
|
if (c == '-') return 63;
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL cred_decode( const WCHAR *cred, unsigned int len, char *buf )
|
||||||
|
{
|
||||||
|
unsigned int i = 0;
|
||||||
|
char c0, c1, c2, c3;
|
||||||
|
const WCHAR *p = cred;
|
||||||
|
|
||||||
|
while (len >= 4)
|
||||||
|
{
|
||||||
|
if ((c0 = char_decode( p[0] )) > 63) return FALSE;
|
||||||
|
if ((c1 = char_decode( p[1] )) > 63) return FALSE;
|
||||||
|
if ((c2 = char_decode( p[2] )) > 63) return FALSE;
|
||||||
|
if ((c3 = char_decode( p[3] )) > 63) return FALSE;
|
||||||
|
|
||||||
|
buf[i + 0] = (c1 << 6) | c0;
|
||||||
|
buf[i + 1] = (c2 << 4) | (c1 >> 2);
|
||||||
|
buf[i + 2] = (c3 << 2) | (c2 >> 4);
|
||||||
|
len -= 4;
|
||||||
|
i += 3;
|
||||||
|
p += 4;
|
||||||
|
}
|
||||||
|
if (len == 3)
|
||||||
|
{
|
||||||
|
if ((c0 = char_decode( p[0] )) > 63) return FALSE;
|
||||||
|
if ((c1 = char_decode( p[1] )) > 63) return FALSE;
|
||||||
|
if ((c2 = char_decode( p[2] )) > 63) return FALSE;
|
||||||
|
|
||||||
|
buf[i + 0] = (c1 << 6) | c0;
|
||||||
|
buf[i + 1] = (c2 << 4) | (c1 >> 2);
|
||||||
|
buf[i + 2] = c2 >> 4;
|
||||||
|
}
|
||||||
|
else if (len == 2)
|
||||||
|
{
|
||||||
|
if ((c0 = char_decode( p[0] )) > 63) return FALSE;
|
||||||
|
if ((c1 = char_decode( p[1] )) > 63) return FALSE;
|
||||||
|
|
||||||
|
buf[i + 0] = (c1 << 6) | c0;
|
||||||
|
buf[i + 1] = c1 >> 2;
|
||||||
|
buf[i + 2] = 0;
|
||||||
|
}
|
||||||
|
else if (len == 1)
|
||||||
|
{
|
||||||
|
if ((c0 = char_decode( p[0] )) > 63) return FALSE;
|
||||||
|
|
||||||
|
buf[i + 0] = c0;
|
||||||
|
buf[i + 1] = 0;
|
||||||
|
buf[i + 2] = 0;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/******************************************************************************
|
||||||
|
* CredUnmarshalCredentialW [ADVAPI32.@]
|
||||||
|
*/
|
||||||
|
BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVOID *out )
|
||||||
|
{
|
||||||
|
unsigned int len, buflen, size;
|
||||||
|
|
||||||
|
TRACE("%s, %p, %p\n", debugstr_w(cred), type, out);
|
||||||
|
|
||||||
|
if (!cred || cred[0] != '@' || cred[1] != '@' || !cred[2] || !cred[3])
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
len = strlenW( cred + 3 );
|
||||||
|
switch (cred[2] - 'A')
|
||||||
|
{
|
||||||
|
case CertCredential:
|
||||||
|
{
|
||||||
|
char hash[CERT_HASH_LENGTH + 2];
|
||||||
|
CERT_CREDENTIAL_INFO *cert;
|
||||||
|
|
||||||
|
if (len != 27 || !cred_decode( cred + 3, len, hash ))
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!(cert = HeapAlloc( GetProcessHeap(), 0, sizeof(*cert) ))) return FALSE;
|
||||||
|
memcpy( cert->rgbHashOfCert, hash, sizeof(cert->rgbHashOfCert) );
|
||||||
|
cert->cbSize = sizeof(*cert);
|
||||||
|
*type = CertCredential;
|
||||||
|
*out = cert;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case UsernameTargetCredential:
|
||||||
|
{
|
||||||
|
USERNAME_TARGET_CREDENTIAL_INFO *target;
|
||||||
|
|
||||||
|
if (len < 9 || !cred_decode( cred + 3, 6, (char *)&size ) || !size || size % sizeof(WCHAR))
|
||||||
|
{
|
||||||
|
SetLastError( ERROR_INVALID_PARAMETER );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
buflen = sizeof(*target) + size + sizeof(WCHAR);
|
||||||
|
if (!(target = HeapAlloc( GetProcessHeap(), 0, buflen ))) return FALSE;
|
||||||
|
if (!cred_decode( cred + 9, len - 6, (char *)(target + 1) ))
|
||||||
|
{
|
||||||
|
HeapFree( GetProcessHeap(), 0, target );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
target->UserName = (WCHAR *)(target + 1);
|
||||||
|
target->UserName[size / sizeof(WCHAR)] = 0;
|
||||||
|
*type = UsernameTargetCredential;
|
||||||
|
*out = target;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case BinaryBlobCredential:
|
||||||
|
FIXME("BinaryBlobCredential not implemented\n");
|
||||||
|
return FALSE;
|
||||||
|
default:
|
||||||
|
WARN("unhandled type %u\n", cred[2] - 'A');
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
|
@ -35,7 +35,8 @@ static BOOL (WINAPI *pCredReadA)(LPCSTR,DWORD,DWORD,PCREDENTIALA *);
|
||||||
static BOOL (WINAPI *pCredRenameA)(LPCSTR,LPCSTR,DWORD,DWORD);
|
static BOOL (WINAPI *pCredRenameA)(LPCSTR,LPCSTR,DWORD,DWORD);
|
||||||
static BOOL (WINAPI *pCredWriteA)(PCREDENTIALA,DWORD);
|
static BOOL (WINAPI *pCredWriteA)(PCREDENTIALA,DWORD);
|
||||||
static BOOL (WINAPI *pCredReadDomainCredentialsA)(PCREDENTIAL_TARGET_INFORMATIONA,DWORD,DWORD*,PCREDENTIALA**);
|
static BOOL (WINAPI *pCredReadDomainCredentialsA)(PCREDENTIAL_TARGET_INFORMATIONA,DWORD,DWORD*,PCREDENTIALA**);
|
||||||
|
static BOOL (WINAPI *pCredMarshalCredentialA)(CRED_MARSHAL_TYPE,PVOID,LPSTR *);
|
||||||
|
static BOOL (WINAPI *pCredUnmarshalCredentialA)(LPCSTR,PCRED_MARSHAL_TYPE,PVOID);
|
||||||
|
|
||||||
#define TEST_TARGET_NAME "credtest.winehq.org"
|
#define TEST_TARGET_NAME "credtest.winehq.org"
|
||||||
#define TEST_TARGET_NAME2 "credtest2.winehq.org"
|
#define TEST_TARGET_NAME2 "credtest2.winehq.org"
|
||||||
|
@ -336,6 +337,297 @@ static void test_domain_password(DWORD cred_type)
|
||||||
ok(ret, "CredDeleteA failed with error %d\n", GetLastError());
|
ok(ret, "CredDeleteA failed with error %d\n", GetLastError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_CredMarshalCredentialA(void)
|
||||||
|
{
|
||||||
|
static WCHAR emptyW[] = {0};
|
||||||
|
static WCHAR tW[] = {'t',0};
|
||||||
|
static WCHAR teW[] = {'t','e',0};
|
||||||
|
static WCHAR tesW[] = {'t','e','s',0};
|
||||||
|
static WCHAR testW[] = {'t','e','s','t',0};
|
||||||
|
static WCHAR test1W[] = {'t','e','s','t','1',0};
|
||||||
|
CERT_CREDENTIAL_INFO cert;
|
||||||
|
USERNAME_TARGET_CREDENTIAL_INFO username;
|
||||||
|
DWORD error;
|
||||||
|
char *str;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredMarshalCredentialA( 0, NULL, NULL );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
|
||||||
|
memset( cert.rgbHashOfCert, 0, sizeof(cert.rgbHashOfCert) );
|
||||||
|
cert.cbSize = sizeof(cert);
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredMarshalCredentialA( 0, &cert, NULL );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
|
||||||
|
str = (char *)0xdeadbeef;
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredMarshalCredentialA( 0, &cert, &str );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
ok( str == (char *)0xdeadbeef, "got %p\n", str );
|
||||||
|
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredMarshalCredentialA( CertCredential, NULL, NULL );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
|
||||||
|
if (0) { /* crash */
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredMarshalCredentialA( CertCredential, &cert, NULL );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
}
|
||||||
|
|
||||||
|
cert.cbSize = 0;
|
||||||
|
str = (char *)0xdeadbeef;
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
ok( str == (char *)0xdeadbeef, "got %p\n", str );
|
||||||
|
|
||||||
|
cert.cbSize = sizeof(cert) + 4;
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
|
||||||
|
cert.cbSize = sizeof(cert);
|
||||||
|
cert.rgbHashOfCert[0] = 2;
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@BCAAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
|
||||||
|
cert.rgbHashOfCert[0] = 255;
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@B-DAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
|
||||||
|
cert.rgbHashOfCert[0] = 1;
|
||||||
|
cert.rgbHashOfCert[1] = 1;
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@BBEAAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
|
||||||
|
cert.rgbHashOfCert[0] = 1;
|
||||||
|
cert.rgbHashOfCert[1] = 1;
|
||||||
|
cert.rgbHashOfCert[2] = 1;
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@BBEQAAAAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
|
||||||
|
memset( cert.rgbHashOfCert, 0, sizeof(cert.rgbHashOfCert) );
|
||||||
|
cert.rgbHashOfCert[0] = 'W';
|
||||||
|
cert.rgbHashOfCert[1] = 'i';
|
||||||
|
cert.rgbHashOfCert[2] = 'n';
|
||||||
|
cert.rgbHashOfCert[3] = 'e';
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@BXlmblBAAAAAAAAAAAAAAAAAAAAA" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
|
||||||
|
memset( cert.rgbHashOfCert, 0xff, sizeof(cert.rgbHashOfCert) );
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( CertCredential, &cert, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@B--------------------------P" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
|
||||||
|
username.UserName = NULL;
|
||||||
|
str = (char *)0xdeadbeef;
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
ok( str == (char *)0xdeadbeef, "got %p\n", str );
|
||||||
|
|
||||||
|
username.UserName = emptyW;
|
||||||
|
str = (char *)0xdeadbeef;
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
ok( str == (char *)0xdeadbeef, "got %p\n", str );
|
||||||
|
|
||||||
|
username.UserName = tW;
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@CCAAAAA0BA" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
|
||||||
|
username.UserName = teW;
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@CEAAAAA0BQZAA" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
|
||||||
|
username.UserName = tesW;
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@CGAAAAA0BQZAMHA" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
|
||||||
|
username.UserName = testW;
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@CIAAAAA0BQZAMHA0BA" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
|
||||||
|
username.UserName = test1W;
|
||||||
|
str = NULL;
|
||||||
|
ret = pCredMarshalCredentialA( UsernameTargetCredential, &username, &str );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( str != NULL, "str not set\n" );
|
||||||
|
ok( !lstrcmpA( str, "@@CKAAAAA0BQZAMHA0BQMAA" ), "got %s\n", str );
|
||||||
|
pCredFree( str );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_CredUnmarshalCredentialA(void)
|
||||||
|
{
|
||||||
|
static WCHAR tW[] = {'t',0};
|
||||||
|
static WCHAR testW[] = {'t','e','s','t',0};
|
||||||
|
CERT_CREDENTIAL_INFO *cert;
|
||||||
|
USERNAME_TARGET_CREDENTIAL_INFO *username;
|
||||||
|
CRED_MARSHAL_TYPE type;
|
||||||
|
unsigned int i;
|
||||||
|
DWORD error;
|
||||||
|
BOOL ret;
|
||||||
|
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredUnmarshalCredentialA( NULL, NULL, NULL );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
|
||||||
|
cert = NULL;
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredUnmarshalCredentialA( NULL, NULL, (void **)&cert );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
|
||||||
|
type = 0;
|
||||||
|
cert = NULL;
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredUnmarshalCredentialA( NULL, &type, (void **)&cert );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
|
||||||
|
type = 0;
|
||||||
|
cert = NULL;
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredUnmarshalCredentialA( "", &type, (void **)&cert );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
|
||||||
|
if (0) { /* crash */
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", &type, NULL );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", NULL, (void **)&cert );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
}
|
||||||
|
|
||||||
|
type = 0;
|
||||||
|
cert = NULL;
|
||||||
|
ret = pCredUnmarshalCredentialA( "@@BAAAAAAAAAAAAAAAAAAAAAAAAAAA", &type, (void **)&cert );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( type == CertCredential, "got %u\n", type );
|
||||||
|
ok( cert != NULL, "cert is NULL\n" );
|
||||||
|
ok( cert->cbSize == sizeof(*cert), "wrong size %u\n", cert->cbSize );
|
||||||
|
for (i = 0; i < sizeof(cert->rgbHashOfCert); i++) ok( !cert->rgbHashOfCert[i], "wrong data\n" );
|
||||||
|
pCredFree( cert );
|
||||||
|
|
||||||
|
type = 0;
|
||||||
|
cert = NULL;
|
||||||
|
ret = pCredUnmarshalCredentialA( "@@BXlmblBAAAAAAAAAAAAAAAAAAAAA", &type, (void **)&cert );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( type == CertCredential, "got %u\n", type );
|
||||||
|
ok( cert != NULL, "cert is NULL\n" );
|
||||||
|
ok( cert->cbSize == sizeof(*cert), "wrong size %u\n", cert->cbSize );
|
||||||
|
ok( cert->rgbHashOfCert[0] == 'W', "wrong data)\n" );
|
||||||
|
ok( cert->rgbHashOfCert[1] == 'i', "wrong data\n" );
|
||||||
|
ok( cert->rgbHashOfCert[2] == 'n', "wrong data\n" );
|
||||||
|
ok( cert->rgbHashOfCert[3] == 'e', "wrong data\n" );
|
||||||
|
for (i = 4; i < sizeof(cert->rgbHashOfCert); i++) ok( !cert->rgbHashOfCert[i], "wrong data\n" );
|
||||||
|
pCredFree( cert );
|
||||||
|
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredUnmarshalCredentialA( "@@CAAAAAA", &type, (void **)&username );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
|
||||||
|
SetLastError( 0xdeadbeef );
|
||||||
|
ret = pCredUnmarshalCredentialA( "@@CAAAAAA0BA", &type, (void **)&username );
|
||||||
|
error = GetLastError();
|
||||||
|
ok( !ret, "unexpected success\n" );
|
||||||
|
ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error );
|
||||||
|
|
||||||
|
type = 0;
|
||||||
|
username = NULL;
|
||||||
|
ret = pCredUnmarshalCredentialA( "@@CCAAAAA0BA", &type, (void **)&username );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( type == UsernameTargetCredential, "got %u\n", type );
|
||||||
|
ok( username != NULL, "username is NULL\n" );
|
||||||
|
ok( username->UserName != NULL, "UserName is NULL\n" );
|
||||||
|
ok( !lstrcmpW( username->UserName, tW ), "got %s\n", wine_dbgstr_w(username->UserName) );
|
||||||
|
pCredFree( username );
|
||||||
|
|
||||||
|
type = 0;
|
||||||
|
username = NULL;
|
||||||
|
ret = pCredUnmarshalCredentialA( "@@CIAAAAA0BQZAMHA0BA", &type, (void **)&username );
|
||||||
|
ok( ret, "unexpected failure %u\n", GetLastError() );
|
||||||
|
ok( type == UsernameTargetCredential, "got %u\n", type );
|
||||||
|
ok( username != NULL, "username is NULL\n" );
|
||||||
|
ok( username->UserName != NULL, "UserName is NULL\n" );
|
||||||
|
ok( !lstrcmpW( username->UserName, testW ), "got %s\n", wine_dbgstr_w(username->UserName) );
|
||||||
|
pCredFree( username );
|
||||||
|
}
|
||||||
|
|
||||||
START_TEST(cred)
|
START_TEST(cred)
|
||||||
{
|
{
|
||||||
DWORD persists[CRED_TYPE_MAXIMUM];
|
DWORD persists[CRED_TYPE_MAXIMUM];
|
||||||
|
@ -348,9 +640,10 @@ START_TEST(cred)
|
||||||
pCredReadA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredReadA");
|
pCredReadA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredReadA");
|
||||||
pCredRenameA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredRenameA");
|
pCredRenameA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredRenameA");
|
||||||
pCredReadDomainCredentialsA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredReadDomainCredentialsA");
|
pCredReadDomainCredentialsA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredReadDomainCredentialsA");
|
||||||
|
pCredMarshalCredentialA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredMarshalCredentialA");
|
||||||
|
pCredUnmarshalCredentialA = (void *)GetProcAddress(GetModuleHandle("advapi32.dll"), "CredUnmarshalCredentialA");
|
||||||
|
|
||||||
if (!pCredEnumerateA || !pCredFree || !pCredWriteA || !pCredDeleteA ||
|
if (!pCredEnumerateA || !pCredFree || !pCredWriteA || !pCredDeleteA || !pCredReadA)
|
||||||
!pCredReadA)
|
|
||||||
{
|
{
|
||||||
win_skip("credentials functions not present in advapi32.dll\n");
|
win_skip("credentials functions not present in advapi32.dll\n");
|
||||||
return;
|
return;
|
||||||
|
@ -392,4 +685,7 @@ START_TEST(cred)
|
||||||
skip("CRED_TYPE_DOMAIN_VISIBLE_PASSWORD credentials are not supported or are disabled. Skipping\n");
|
skip("CRED_TYPE_DOMAIN_VISIBLE_PASSWORD credentials are not supported or are disabled. Skipping\n");
|
||||||
else
|
else
|
||||||
test_domain_password(CRED_TYPE_DOMAIN_VISIBLE_PASSWORD);
|
test_domain_password(CRED_TYPE_DOMAIN_VISIBLE_PASSWORD);
|
||||||
|
|
||||||
|
test_CredMarshalCredentialA();
|
||||||
|
test_CredUnmarshalCredentialA();
|
||||||
}
|
}
|
||||||
|
|
|
@ -150,6 +150,32 @@ typedef struct _CREDUI_INFOW
|
||||||
DECL_WINELIB_TYPE_AW(CREDUI_INFO)
|
DECL_WINELIB_TYPE_AW(CREDUI_INFO)
|
||||||
DECL_WINELIB_TYPE_AW(PCREDUI_INFO)
|
DECL_WINELIB_TYPE_AW(PCREDUI_INFO)
|
||||||
|
|
||||||
|
typedef enum _CRED_MARSHAL_TYPE
|
||||||
|
{
|
||||||
|
CertCredential = 1,
|
||||||
|
UsernameTargetCredential,
|
||||||
|
BinaryBlobCredential
|
||||||
|
} CRED_MARSHAL_TYPE, *PCRED_MARSHAL_TYPE;
|
||||||
|
|
||||||
|
#define CERT_HASH_LENGTH 20
|
||||||
|
|
||||||
|
typedef struct _CERT_CREDENTIAL_INFO
|
||||||
|
{
|
||||||
|
ULONG cbSize;
|
||||||
|
UCHAR rgbHashOfCert[CERT_HASH_LENGTH];
|
||||||
|
} CERT_CREDENTIAL_INFO, *PCERT_CREDENTIAL_INFO;
|
||||||
|
|
||||||
|
typedef struct _USERNAME_TARGET_CREDENTIAL_INFO
|
||||||
|
{
|
||||||
|
LPWSTR UserName;
|
||||||
|
} USERNAME_TARGET_CREDENTIAL_INFO;
|
||||||
|
|
||||||
|
typedef struct _BINARY_BLOB_CREDENTIAL_INFO
|
||||||
|
{
|
||||||
|
ULONG cbBlob;
|
||||||
|
LPBYTE pbBlob;
|
||||||
|
} BINARY_BLOB_CREDENTIAL_INFO, *PBINARY_BLOB_CREDENTIAL_INFO;
|
||||||
|
|
||||||
#define CRED_MAX_STRING_LENGTH 256
|
#define CRED_MAX_STRING_LENGTH 256
|
||||||
#define CRED_MAX_USERNAME_LENGTH 513
|
#define CRED_MAX_USERNAME_LENGTH 513
|
||||||
#define CRED_MAX_GENERIC_TARGET_NAME_LENGTH 32767
|
#define CRED_MAX_GENERIC_TARGET_NAME_LENGTH 32767
|
||||||
|
@ -222,6 +248,9 @@ WINADVAPI BOOL WINAPI CredEnumerateW(LPCWSTR,DWORD,DWORD *,PCREDENTIALW **);
|
||||||
#define CredEnumerate WINELIB_NAME_AW(CredEnumerate)
|
#define CredEnumerate WINELIB_NAME_AW(CredEnumerate)
|
||||||
WINADVAPI VOID WINAPI CredFree(PVOID);
|
WINADVAPI VOID WINAPI CredFree(PVOID);
|
||||||
WINADVAPI BOOL WINAPI CredGetSessionTypes(DWORD,LPDWORD);
|
WINADVAPI BOOL WINAPI CredGetSessionTypes(DWORD,LPDWORD);
|
||||||
|
WINADVAPI BOOL WINAPI CredMarshalCredentialA(CRED_MARSHAL_TYPE,PVOID,LPSTR *);
|
||||||
|
WINADVAPI BOOL WINAPI CredMarshalCredentialW(CRED_MARSHAL_TYPE,PVOID,LPWSTR *);
|
||||||
|
#define CredMarshalCredential WINELIB_NAME_AW(CredMarshalCredential)
|
||||||
WINADVAPI BOOL WINAPI CredReadA(LPCSTR,DWORD,DWORD,PCREDENTIALA *);
|
WINADVAPI BOOL WINAPI CredReadA(LPCSTR,DWORD,DWORD,PCREDENTIALA *);
|
||||||
WINADVAPI BOOL WINAPI CredReadW(LPCWSTR,DWORD,DWORD,PCREDENTIALW *);
|
WINADVAPI BOOL WINAPI CredReadW(LPCWSTR,DWORD,DWORD,PCREDENTIALW *);
|
||||||
#define CredRead WINELIB_NAME_AW(CredRead)
|
#define CredRead WINELIB_NAME_AW(CredRead)
|
||||||
|
@ -231,6 +260,9 @@ WINADVAPI BOOL WINAPI CredReadDomainCredentialsW(PCREDENTIAL_TARGET_INFORMATION
|
||||||
WINADVAPI BOOL WINAPI CredRenameA(LPCSTR,LPCSTR,DWORD,DWORD);
|
WINADVAPI BOOL WINAPI CredRenameA(LPCSTR,LPCSTR,DWORD,DWORD);
|
||||||
WINADVAPI BOOL WINAPI CredRenameW(LPCWSTR,LPCWSTR,DWORD,DWORD);
|
WINADVAPI BOOL WINAPI CredRenameW(LPCWSTR,LPCWSTR,DWORD,DWORD);
|
||||||
#define CredRename WINELIB_NAME_AW(CredRename)
|
#define CredRename WINELIB_NAME_AW(CredRename)
|
||||||
|
WINADVAPI BOOL WINAPI CredUnmarshalCredentialA(LPCSTR,PCRED_MARSHAL_TYPE,PVOID *);
|
||||||
|
WINADVAPI BOOL WINAPI CredUnmarshalCredentialW(LPCWSTR,PCRED_MARSHAL_TYPE,PVOID *);
|
||||||
|
#define CredUnmarshalCredential WINELIB_NAME_AW(CredUnmarshalCredential)
|
||||||
WINADVAPI BOOL WINAPI CredWriteA(PCREDENTIALA,DWORD);
|
WINADVAPI BOOL WINAPI CredWriteA(PCREDENTIALA,DWORD);
|
||||||
WINADVAPI BOOL WINAPI CredWriteW(PCREDENTIALW,DWORD);
|
WINADVAPI BOOL WINAPI CredWriteW(PCREDENTIALW,DWORD);
|
||||||
#define CredWrite WINELIB_NAME_AW(CredWrite)
|
#define CredWrite WINELIB_NAME_AW(CredWrite)
|
||||||
|
|
Loading…
Reference in New Issue