You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
474 lines
15 KiB
474 lines
15 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ctcred.c
|
|
|
|
Abstract:
|
|
|
|
Component test for cred marshaling and unmarshaling
|
|
|
|
Author:
|
|
|
|
Cliff Van Dyke (CliffV) March 22, 2000
|
|
|
|
Environment:
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <wincred.h>
|
|
#include <credp.h>
|
|
#include <stdio.h>
|
|
#include <winnetwk.h>
|
|
|
|
#include <lmerr.h>
|
|
|
|
int __cdecl
|
|
main(
|
|
IN int argc,
|
|
IN char ** argv
|
|
)
|
|
{
|
|
DWORD WinStatus;
|
|
NTSTATUS Status;
|
|
UCHAR Buffer[1024];
|
|
UCHAR Buffer2[1024];
|
|
PCERT_CREDENTIAL_INFO CertCred1 = (PCERT_CREDENTIAL_INFO)Buffer;
|
|
PCERT_CREDENTIAL_INFO CertCred2;
|
|
PUSERNAME_TARGET_CREDENTIAL_INFO UsernameTargetCred1 = (PUSERNAME_TARGET_CREDENTIAL_INFO)Buffer;
|
|
PUSERNAME_TARGET_CREDENTIAL_INFO UsernameTargetCred2;
|
|
LONG Size;
|
|
ULONG i;
|
|
int j;
|
|
NETRESOURCEW NetRes;
|
|
|
|
LPWSTR MarshaledCredential;
|
|
|
|
LPSTR argument;
|
|
BOOLEAN TestCert = FALSE;
|
|
BOOLEAN TestUsernameTarget = FALSE;
|
|
BOOLEAN TestValidateTarget = FALSE;
|
|
BOOLEAN TestNetUse = FALSE;
|
|
BOOLEAN TestAll = TRUE;
|
|
|
|
|
|
//
|
|
// Loop through the arguments handle each in turn
|
|
//
|
|
|
|
for ( j=1; j<argc; j++ ) {
|
|
|
|
argument = argv[j];
|
|
|
|
|
|
//
|
|
// Handle /Cert
|
|
//
|
|
|
|
if ( _stricmp( argument, "/Cert" ) == 0 ) {
|
|
TestCert = TRUE;
|
|
TestAll = FALSE;
|
|
|
|
//
|
|
// Handle /UsernameTarget
|
|
//
|
|
|
|
}else if ( _stricmp( argument, "/UsernameTarget" ) == 0 ) {
|
|
TestUsernameTarget = TRUE;
|
|
TestAll = FALSE;
|
|
|
|
//
|
|
// Handle /ValidateTarget
|
|
//
|
|
|
|
}else if ( _stricmp( argument, "/ValidateTarget" ) == 0 ) {
|
|
TestValidateTarget = TRUE;
|
|
TestAll = FALSE;
|
|
|
|
//
|
|
// Handle /NetUse
|
|
//
|
|
|
|
}else if ( _stricmp( argument, "/NetUse" ) == 0 ) {
|
|
TestNetUse = TRUE;
|
|
TestAll = FALSE;
|
|
|
|
|
|
|
|
//
|
|
// Handle all other parameters
|
|
//
|
|
|
|
} else {
|
|
//Usage:
|
|
fprintf( stderr, "Usage: ctcred [/Cert] [/UsernameTarget] [ValidateTarget] [/NetUse]\n\n" );
|
|
return(1);
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Test cert marshaling
|
|
//
|
|
|
|
if ( TestCert || TestAll ) {
|
|
//
|
|
// NULL cred should fail
|
|
//
|
|
|
|
if ( CredMarshalCredentialW( CertCredential,
|
|
NULL,
|
|
&MarshaledCredential ) ) {
|
|
printf( "Cert: Marshal NULL cred should have failed\n" );
|
|
return 1;
|
|
} else if ( GetLastError() != ERROR_INVALID_PARAMETER ) {
|
|
printf( "Cert: Marshal NULL cred failed with wrong status: %ld\n", GetLastError() );
|
|
return 1;
|
|
}
|
|
|
|
|
|
//
|
|
// Short cred should fail
|
|
//
|
|
|
|
RtlZeroMemory( CertCred1, sizeof(*CertCred1) );
|
|
|
|
if ( CredMarshalCredentialW( CertCredential,
|
|
CertCred1,
|
|
&MarshaledCredential ) ) {
|
|
printf( "Cert: Marshal Short cred should have failed\n" );
|
|
return 1;
|
|
} else if ( GetLastError() != ERROR_INVALID_PARAMETER ) {
|
|
printf( "Cert: Marshal Short cred failed with wrong status: %ld\n", GetLastError() );
|
|
return 1;
|
|
}
|
|
|
|
|
|
//
|
|
// Loop marshalling buffers of various sizes
|
|
//
|
|
|
|
for ( Size=0; Size<512; Size ++ ) {
|
|
CRED_MARSHAL_TYPE CredType;
|
|
|
|
//
|
|
// Build a cred to marshal
|
|
//
|
|
|
|
CertCred1->cbSize = sizeof(*CertCred1);
|
|
|
|
for ( i=0; i<sizeof(CertCred1->rgbHashOfCert); i++ ) {
|
|
CertCred1->rgbHashOfCert[i] = (BYTE)Size;
|
|
}
|
|
|
|
|
|
//
|
|
// Marshal it.
|
|
//
|
|
|
|
if ( !CredMarshalCredentialW( CertCredential,
|
|
CertCred1,
|
|
&MarshaledCredential ) ) {
|
|
printf( "Cert: Cannot marshal cred: %ld %ld\n", Size, GetLastError() );
|
|
return 1;
|
|
}
|
|
|
|
printf( "Cert: %ld: %ws\n", Size, MarshaledCredential );
|
|
|
|
//
|
|
// Ensure it is a marshaled cred
|
|
//
|
|
|
|
if ( !CredIsMarshaledCredentialW( MarshaledCredential ) ) {
|
|
printf( "Cert: Cred isn't marshaled: %ld\n", Size );
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Unmarshal it
|
|
//
|
|
|
|
CredType = (CRED_MARSHAL_TYPE) 87;
|
|
if ( !CredUnmarshalCredentialW( MarshaledCredential,
|
|
&CredType,
|
|
&CertCred2 ) ) {
|
|
printf( "Cert: Cannot unmarshal cred: %ld %ld\n", Size, GetLastError() );
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Verify it
|
|
//
|
|
|
|
if ( CredType != CertCredential ) {
|
|
printf( "Cert: Bad CredType: %ld\n", Size );
|
|
return 1;
|
|
}
|
|
|
|
if ( !RtlEqualMemory( CertCred1, CertCred2, sizeof(*CertCred1) - 3 * sizeof(ULONG) ) ) {
|
|
printf( "Cert: Bad Cred structure: %ld\n", Size );
|
|
return 1;
|
|
}
|
|
|
|
if ( TestNetUse || TestAll ) {
|
|
NetRes.dwType = RESOURCETYPE_ANY;
|
|
NetRes.lpLocalName = NULL;
|
|
NetRes.lpRemoteName = L"\\\\CLIFFV1\\d$";
|
|
NetRes.lpProvider = NULL;
|
|
|
|
WinStatus = WNetAddConnection2W( &NetRes,
|
|
L"", // no password
|
|
MarshaledCredential,
|
|
0 );
|
|
|
|
if ( WinStatus != NO_ERROR ) {
|
|
printf( "Cert: Cannot connect: %ld %ld\n", Size, WinStatus );
|
|
}
|
|
}
|
|
|
|
|
|
CredFree( CertCred2 );
|
|
CredFree( MarshaledCredential );
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Test UsernameTarget marshaling
|
|
//
|
|
|
|
if ( TestUsernameTarget || TestAll ) {
|
|
//
|
|
// NULL cred should fail
|
|
//
|
|
|
|
if ( CredMarshalCredentialW( UsernameTargetCredential,
|
|
NULL,
|
|
&MarshaledCredential ) ) {
|
|
printf( "UsernameTarget: Marshal NULL cred should have failed\n" );
|
|
return 1;
|
|
} else if ( GetLastError() != ERROR_INVALID_PARAMETER ) {
|
|
printf( "UsernameTarget: Marshal NULL cred failed with wrong status: %ld\n", GetLastError() );
|
|
return 1;
|
|
}
|
|
|
|
|
|
//
|
|
// Empty cred should fail
|
|
//
|
|
|
|
RtlZeroMemory( UsernameTargetCred1, sizeof(*UsernameTargetCred1) );
|
|
|
|
if ( CredMarshalCredentialW( UsernameTargetCredential,
|
|
UsernameTargetCred1,
|
|
&MarshaledCredential ) ) {
|
|
printf( "UsernameTarget: Marshal Short cred should have failed\n" );
|
|
return 1;
|
|
} else if ( GetLastError() != ERROR_INVALID_PARAMETER ) {
|
|
printf( "UsernameTarget: Marshal Short cred failed with wrong status: %ld\n", GetLastError() );
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Loop marshalling buffers of various sizes
|
|
//
|
|
|
|
for ( Size=-3; Size<255; Size ++ ) {
|
|
CRED_MARSHAL_TYPE CredType;
|
|
|
|
//
|
|
// Build a cred to marshal
|
|
//
|
|
|
|
UsernameTargetCred1->UserName = (LPWSTR)Buffer2;
|
|
|
|
if ( Size == -3 ) {
|
|
wcscpy( UsernameTargetCred1->UserName, L"a" );
|
|
} else if ( Size == -2 ) {
|
|
wcscpy( UsernameTargetCred1->UserName, L"ntdev\\cliffv" );
|
|
} else if ( Size == -1 ) {
|
|
wcscpy( UsernameTargetCred1->UserName, L"[email protected]" );
|
|
} else {
|
|
for ( i=0; i<Size*sizeof(WCHAR); i++ ) {
|
|
Buffer2[i] = (BYTE)Size;
|
|
}
|
|
Buffer2[i*sizeof(WCHAR)] = 0;
|
|
Buffer2[i*sizeof(WCHAR)+1] = 0;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Marshal it.
|
|
//
|
|
|
|
if ( !CredMarshalCredentialW( UsernameTargetCredential,
|
|
UsernameTargetCred1,
|
|
&MarshaledCredential ) ) {
|
|
WinStatus = GetLastError();
|
|
if ( Size == 0 && WinStatus == ERROR_INVALID_PARAMETER ) {
|
|
// This is OK
|
|
continue;
|
|
} else {
|
|
printf( "UsernameTarget: Cannot marshal cred: %ld %ld\n", Size, WinStatus );
|
|
return 1;
|
|
}
|
|
} else {
|
|
if ( Size == 0 ) {
|
|
printf( "UsernameTarget: Marshal empty cred should have failed\n" );
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if ( Size < 0 ) {
|
|
printf( "UsernameTarget: %ld: %ws: %ws\n", Size, Buffer2, MarshaledCredential );
|
|
} else {
|
|
printf( "UsernameTarget: %ld: %ws\n", Size, MarshaledCredential );
|
|
}
|
|
|
|
//
|
|
// Ensure it is a marshaled cred
|
|
//
|
|
|
|
if ( !CredIsMarshaledCredentialW( MarshaledCredential ) ) {
|
|
printf( "UsernameTarget: Cred isn't marshaled: %ld\n", Size );
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Unmarshal it
|
|
//
|
|
|
|
CredType = (CRED_MARSHAL_TYPE) 87;
|
|
if ( !CredUnmarshalCredentialW( MarshaledCredential,
|
|
&CredType,
|
|
&UsernameTargetCred2 ) ) {
|
|
printf( "UsernameTarget: Cannot unmarshal cred: %ld %ld\n", Size, GetLastError() );
|
|
return 1;
|
|
}
|
|
|
|
//
|
|
// Verify it
|
|
//
|
|
|
|
if ( CredType != UsernameTargetCredential ) {
|
|
printf( "UsernameTarget: Bad CredType: %ld\n", Size );
|
|
return 1;
|
|
}
|
|
|
|
if ( Size < 0 ) {
|
|
|
|
if ( wcscmp( UsernameTargetCred1->UserName, UsernameTargetCred2->UserName ) != 0 ) {
|
|
printf( "UsernameTarget: %ws: Bad Cred structure: %ld\n", UsernameTargetCred1->UserName, Size );
|
|
return 1;
|
|
}
|
|
|
|
} else {
|
|
|
|
if ( !RtlEqualMemory( UsernameTargetCred1->UserName, UsernameTargetCred2->UserName, Size*sizeof(WCHAR) ) ) {
|
|
printf( "UsernameTarget: Bad Cred structure: %ld\n", Size );
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Connect using the credential
|
|
//
|
|
|
|
if ( TestNetUse || TestAll ) {
|
|
NetRes.dwType = RESOURCETYPE_ANY;
|
|
NetRes.lpLocalName = NULL;
|
|
NetRes.lpRemoteName = L"\\\\CLIFFV1\\d$";
|
|
NetRes.lpProvider = NULL;
|
|
|
|
WinStatus = WNetAddConnection2W( &NetRes,
|
|
L"", // no password
|
|
MarshaledCredential,
|
|
0 );
|
|
|
|
if ( WinStatus != NO_ERROR ) {
|
|
printf( "UsernameTarget: Cannot connect: %ld %ld\n", Size, WinStatus );
|
|
}
|
|
}
|
|
|
|
|
|
CredFree( UsernameTargetCred2 );
|
|
CredFree( MarshaledCredential );
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Test ValidateTargetName
|
|
//
|
|
|
|
if ( TestValidateTarget || TestAll ) {
|
|
|
|
struct {
|
|
LPWSTR TargetName;
|
|
ULONG Type;
|
|
TARGET_NAME_TYPE TargetNameType;
|
|
LPWSTR UserName;
|
|
DWORD Persist;
|
|
} ValidTests[] = {
|
|
L"DfsRoot\\DfsShare", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"www.dfsroot.com\\DfsShare", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"www.dfsroot.com.\\DfsShare", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"www.ms.com", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"www.ms.com.", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"products1", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"*.acme.com", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"*.acme.com.", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"redmond\\*", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"redmond.\\*", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"corp.ms.com\\*", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"corp.ms.com.\\*", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"*Session", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"*", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"[email protected]", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
L"[email protected].", CRED_TYPE_DOMAIN_PASSWORD, MightBeUsernameTarget, NULL, 0,
|
|
};
|
|
|
|
|
|
|
|
for ( i=0; i<sizeof(ValidTests)/sizeof(ValidTests[0]); i++ ) {
|
|
|
|
WCHAR TargetName[1024];
|
|
ULONG TargetNameSize;
|
|
WILDCARD_TYPE WildcardType;
|
|
UNICODE_STRING NonWildcardedTargetName;
|
|
|
|
// Copy to a buffer that can be canonicalized
|
|
wcscpy( TargetName, ValidTests[i].TargetName );
|
|
printf("Target %ws: ", TargetName );
|
|
|
|
Status = CredpValidateTargetName(
|
|
TargetName,
|
|
ValidTests[i].Type,
|
|
ValidTests[i].TargetNameType,
|
|
ValidTests[i].UserName == NULL ? NULL : &ValidTests[i].UserName,
|
|
ValidTests[i].Persist == 0 ? NULL : &ValidTests[i].Persist,
|
|
&TargetNameSize,
|
|
&WildcardType,
|
|
&NonWildcardedTargetName );
|
|
|
|
|
|
if ( !NT_SUCCESS(Status) ) {
|
|
printf("is not valid: 0x%lx\n", Status );
|
|
} else {
|
|
printf("\n %ws: ", TargetName );
|
|
printf("(%ld) %ld %wZ\n", TargetNameSize, WildcardType, &NonWildcardedTargetName );
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|