|
|
/*++
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 ); } } }
}
|