1561 lines
47 KiB
C
1561 lines
47 KiB
C
/*++
|
|
|
|
Copyright (c) 1993 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
tex.c
|
|
|
|
Abstract:
|
|
|
|
User mode test program for the Microsoft Netware redir file system.
|
|
|
|
This test program can be built from the command line using the
|
|
command 'nmake UMTEST=tex'.
|
|
|
|
Author:
|
|
|
|
Manny Weiser (mannyw) 7-Jun-1993
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include <conio.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <ntddnwfs.h>
|
|
#include <ntddnwp.h>
|
|
#include <STDARG.H>
|
|
|
|
#define OT_USER 1
|
|
|
|
|
|
// Hex dump
|
|
ULONG MaxDump = 256;
|
|
|
|
VOID
|
|
dump(
|
|
IN PVOID far_p,
|
|
IN ULONG len
|
|
);
|
|
|
|
VOID
|
|
HexDumpLine (
|
|
PCHAR pch,
|
|
ULONG len,
|
|
PCHAR s,
|
|
PCHAR t,
|
|
USHORT flag
|
|
);
|
|
|
|
|
|
// End Hex dump
|
|
|
|
VOID
|
|
ResetPassword(
|
|
PUCHAR Vnew
|
|
);
|
|
|
|
UCHAR
|
|
LookUp(
|
|
UCHAR Value,
|
|
UCHAR Mask,
|
|
int index
|
|
);
|
|
|
|
SendMessage(
|
|
IN char* Format,
|
|
...
|
|
);
|
|
|
|
NTSTATUS
|
|
FormatRequest(
|
|
PCHAR SendBuffer,
|
|
PULONG SendBufferLength,
|
|
char* Format,
|
|
va_list a
|
|
);
|
|
|
|
BOOLEAN
|
|
OpenServer(
|
|
PHANDLE Handle,
|
|
PWCH ServerName
|
|
);
|
|
|
|
NTSTATUS
|
|
_cdecl
|
|
ParseResponse(
|
|
char* FormatString,
|
|
... // format specific parameters
|
|
);
|
|
|
|
VOID
|
|
Shuffle(
|
|
UCHAR *achObjectId,
|
|
UCHAR *szUpperPassword,
|
|
int iPasswordLen,
|
|
UCHAR *achOutputBuffer
|
|
);
|
|
|
|
int
|
|
Scramble(
|
|
int iSeed,
|
|
UCHAR achBuffer[32]
|
|
);
|
|
|
|
VOID
|
|
RespondToChallenge(
|
|
IN PUCHAR achObjectId,
|
|
IN POEM_STRING Password,
|
|
IN PUCHAR pChallenge,
|
|
OUT PUCHAR pResponse
|
|
);
|
|
|
|
VOID
|
|
RespondToChallengePart1(
|
|
IN PUCHAR achObjectId,
|
|
IN POEM_STRING Password,
|
|
OUT PUCHAR pResponse
|
|
);
|
|
|
|
VOID
|
|
RespondToChallengePart2(
|
|
IN PUCHAR pResponsePart1,
|
|
IN PUCHAR pChallenge,
|
|
OUT PUCHAR pResponse
|
|
);
|
|
|
|
NTSTATUS
|
|
GetCurrentPasswordValue (
|
|
IN OUT PCHAR OutputValue
|
|
);
|
|
|
|
#define BUFFER_SIZE 200
|
|
|
|
WCHAR *ServerName = L"NETWARE311";
|
|
UCHAR Pid = 255;
|
|
UCHAR Object[4];
|
|
|
|
WCHAR FileNameBuffer[100];
|
|
UNICODE_STRING FileName;
|
|
|
|
|
|
HANDLE ServerHandle;
|
|
_cdecl
|
|
main(
|
|
int argc,
|
|
char *argv[],
|
|
)
|
|
{
|
|
BOOLEAN success;
|
|
UCHAR Challenge[8];
|
|
UCHAR fileValue[17];
|
|
UCHAR ResponseP2[16];
|
|
int x, y;
|
|
NTSTATUS status;
|
|
|
|
|
|
#if 0
|
|
UCHAR Vold[] = {
|
|
0x31, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
|
0x31, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x22,
|
|
0x32, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x11,
|
|
0x32, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
|
|
0x23, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x11,
|
|
0x23, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x22,
|
|
0x54, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x11,
|
|
0x54, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x22,
|
|
0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x11,
|
|
0x75, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x22,
|
|
0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x11,
|
|
0x76, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x22,
|
|
0xF7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x11,
|
|
0xF7, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x22,
|
|
0x98, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x11,
|
|
0x98, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x22,
|
|
0x89, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x11,
|
|
0x89, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x22,
|
|
0xba, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x11,
|
|
0xba, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x22,
|
|
0xab, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x11,
|
|
0xab, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0x22,
|
|
0xdc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x11,
|
|
0xdc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x22,
|
|
0xcd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x11,
|
|
0xcd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0x22,
|
|
0xfe, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x11,
|
|
0xfe, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0x22,
|
|
0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
|
|
0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22 };
|
|
|
|
|
|
UCHAR Vc[] = {
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
|
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
|
|
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
|
|
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
|
|
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
|
0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77, 0x77,
|
|
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
|
|
0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x88, 0x88, 0x88,
|
|
0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
|
|
0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
|
|
0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
|
|
0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd,
|
|
0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
|
#endif
|
|
|
|
UCHAR Vold[] = {
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xfe, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xfe, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0xff, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xfd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfb, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xef, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x22,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x11,
|
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbf, 0x22 };
|
|
|
|
UCHAR Vc[] = {
|
|
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11 };
|
|
|
|
|
|
success = OpenServer( &ServerHandle, ServerName );
|
|
if ( !success) {
|
|
return 1;
|
|
}
|
|
|
|
printf("Opened server, %wS\n", ServerName );
|
|
|
|
//
|
|
// Setup the file name that we'll be opening every time.
|
|
//
|
|
|
|
FileName.Buffer = FileNameBuffer;
|
|
FileName.Length = 0;
|
|
FileName.MaximumLength = 100;
|
|
|
|
status = RtlAppendUnicodeToString( &FileName, DD_NWFS_DEVICE_NAME_U );
|
|
ASSERT( status == STATUS_SUCCESS );
|
|
status = RtlAppendUnicodeToString( &FileName, L"\\" );
|
|
status = RtlAppendUnicodeToString( &FileName, ServerName );
|
|
status = RtlAppendUnicodeToString( &FileName, L"\\SYS:\\SYSTEM\\NET$VAL.SYS" );
|
|
|
|
// Get objectid
|
|
SendMessage(
|
|
"Swp",
|
|
0x17, 0x35,
|
|
OT_USER,
|
|
"SUPERVISOR");
|
|
|
|
ParseResponse("r", Object, 4 );
|
|
|
|
for ( x = 0 ; x < sizeof(Vold) ; x+= 17 ) {
|
|
|
|
for ( y = 0 ; y < sizeof(Vc) ; y+= 17 ) {
|
|
|
|
//
|
|
// Set the password on the server to be the value of Vold required for
|
|
// the second part of the test.
|
|
//
|
|
|
|
ResetPassword( Vold + x );
|
|
|
|
//
|
|
// We now know that Vold on the server is the same as the Vold vector.
|
|
// We can now set the password to any Vnew.
|
|
// We can do this without the real password because the
|
|
// server will believe we know the real password if we give it
|
|
// the result of taking Vold and the Challenge key and passing
|
|
// it through RespondToChallengePart2
|
|
//
|
|
|
|
printf( "Getting a challenge key.... " );
|
|
|
|
SendMessage(
|
|
"S",
|
|
0x17, 0x17);
|
|
|
|
ParseResponse("r", Challenge, sizeof(Challenge) );
|
|
|
|
// Fabricate the number the server will use to validate the password change
|
|
RespondToChallengePart2( Vold + x, Challenge, ResponseP2 );
|
|
|
|
printf( "Vold= " ); dump( Vold + x, 17);
|
|
|
|
// Put out results to console...
|
|
|
|
status = GetCurrentPasswordValue( &fileValue[0] );
|
|
|
|
if ( NT_SUCCESS( status ) ) {
|
|
|
|
printf( "File= " );
|
|
dump( fileValue, 17);
|
|
}
|
|
printf( " Vc= "); dump( Vc + y, 17);
|
|
|
|
printf( "Setting the new password... " );
|
|
|
|
// Send the set password
|
|
SendMessage("Srwpr", 0x17, 0x4b,
|
|
ResponseP2, 8,
|
|
OT_USER,
|
|
"SUPERVISOR",
|
|
Vc + y, 17 );
|
|
|
|
status = GetCurrentPasswordValue( &fileValue[0] );
|
|
|
|
if ( NT_SUCCESS( status ) ) {
|
|
|
|
printf( "Vnew= ");
|
|
dump( fileValue, 17);
|
|
}
|
|
|
|
printf( "\n\n" );
|
|
}
|
|
}
|
|
|
|
printf( "%s exiting\n", argv[0]);
|
|
return 0;
|
|
}
|
|
|
|
NTSTATUS
|
|
GetCurrentPasswordValue (
|
|
IN OUT PCHAR OutputValue
|
|
)
|
|
//
|
|
// This routine reads the current password from the file.
|
|
//
|
|
{
|
|
HANDLE fileHandle;
|
|
LARGE_INTEGER filePosition;
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
int i;
|
|
PCHAR ch;
|
|
NTSTATUS status;
|
|
|
|
ch = OutputValue;
|
|
for (i = 0; i < 17; i++) {
|
|
|
|
*(ch++) = '0';
|
|
}
|
|
|
|
// Send a Close Bindery to the server
|
|
|
|
printf( "Closing the bindery... " );
|
|
|
|
SendMessage(
|
|
"S",
|
|
0x17, 0x44);
|
|
|
|
//
|
|
// Open the server\sys:system\net$val.sys file which the server just
|
|
// closed.
|
|
//
|
|
|
|
InitializeObjectAttributes(
|
|
&objectAttributes,
|
|
&FileName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
status = NtOpenFile (
|
|
&fileHandle,
|
|
FILE_GENERIC_READ | SYNCHRONIZE,
|
|
&objectAttributes,
|
|
&ioStatusBlock,
|
|
FILE_SHARE_WRITE | FILE_SHARE_READ,
|
|
0L
|
|
);
|
|
|
|
if (!NT_SUCCESS(status) ) {
|
|
|
|
printf( " Open failed. Status = 0x%x\n", status );
|
|
|
|
} else {
|
|
|
|
//
|
|
// Seek to the spot in the file that has the supervisor's password.
|
|
// This will be different for different servers. Here's a table :
|
|
//
|
|
// Netware311 : 0x097C
|
|
//
|
|
|
|
filePosition.HighPart = 0L;
|
|
filePosition.LowPart = 0x097C;
|
|
|
|
// Read the 17 bytes at that offset and close the file
|
|
|
|
status = NtReadFile (
|
|
fileHandle,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ioStatusBlock,
|
|
OutputValue,
|
|
17,
|
|
&filePosition,
|
|
NULL
|
|
);
|
|
|
|
if (!NT_SUCCESS(status) ) {
|
|
|
|
printf( " Read failed. Status = 0x%x\n", status );
|
|
}
|
|
|
|
NtClose( fileHandle );
|
|
}
|
|
|
|
// Send an Open Bindery to the server
|
|
|
|
printf( "Opening the bindery... " );
|
|
SendMessage(
|
|
"S",
|
|
0x17, 0x45);
|
|
|
|
return(status);
|
|
}
|
|
|
|
VOID
|
|
ResetPassword(
|
|
PUCHAR Vnew
|
|
)
|
|
{
|
|
//
|
|
// Note Vc[0] specifies the length. To derive new values of Vnew use the following
|
|
// table. For each nibble desired in Vnew, scan the appropriate column and
|
|
// read off the corresponding Vc nibble value on the left.
|
|
//
|
|
|
|
UCHAR Vc[17];
|
|
|
|
UCHAR Challenge[8];
|
|
OEM_STRING Password = {0,0,""};
|
|
UCHAR EncryptKey[8];
|
|
|
|
int x;
|
|
|
|
//printf( "Get Login key for set password using NULL password\n");
|
|
|
|
printf( "Getting a challenge key.... " );
|
|
|
|
SendMessage(
|
|
"S",
|
|
0x17, 0x17);
|
|
|
|
ParseResponse("r", Challenge, sizeof(Challenge) );
|
|
|
|
RespondToChallenge( Object, &Password, Challenge, EncryptKey );
|
|
// dump( EncryptKey, 8);
|
|
|
|
//
|
|
// Build Vc so that the server will get Vnew stored in the bindery.
|
|
// Note Vols/Vnew have the length at V[17] whereas Vc has it at Vc[0].
|
|
//
|
|
|
|
for ( x = 0 ; x < 16; x++ ) {
|
|
Vc[x+1] = LookUp( Vnew[x], 0xf0, x) | LookUp( Vnew[x], 0x0f, x);
|
|
}
|
|
|
|
Vc[0] = LookUp( Vnew[16], 0xf0, 16) | LookUp( Vnew[16], 0x0f, 16);
|
|
|
|
//printf( "Vnew "); dump( Vnew, 17);
|
|
//printf( "Vc "); dump( Vc, 17);
|
|
|
|
//
|
|
// This uses the null password, objectid=1 and our supervisor privilege
|
|
// to set it, regardless of the and our ability to figure out what
|
|
// Vnew will be created for a particular Vc.
|
|
//
|
|
|
|
printf( "Setting the old password... " );
|
|
|
|
SendMessage("Srwpr", 0x17, 0x4b,
|
|
EncryptKey, sizeof(EncryptKey),
|
|
OT_USER,
|
|
"SUPERVISOR",
|
|
Vc, 17 );
|
|
|
|
ParseResponse( "" );
|
|
}
|
|
|
|
UCHAR
|
|
LookUp(
|
|
UCHAR Value,
|
|
UCHAR Mask,
|
|
int index
|
|
)
|
|
{
|
|
UCHAR Vtab[] = {
|
|
|
|
0x97, 0xE3, 0x73, 0xD8, 0x70, 0x5B, 0x85, 0xD3, 0xF5, 0xCD, 0xDB, 0xFA, 0xDC, 0xEB, 0x98, 0x64, 0x18, //0//
|
|
0x31, 0x6B, 0x88, 0x1E, 0x88, 0x09, 0x10, 0x29, 0x0B, 0x84, 0x61, 0x03, 0x43, 0xA1, 0xD5, 0x5A, 0x09, //1//
|
|
0xCB, 0xFF, 0x67, 0x70, 0xB6, 0xE3, 0x4E, 0x9A, 0x63, 0x27, 0x1A, 0x3C, 0x5A, 0x9A, 0x3B, 0xFC, 0x3A, //2//
|
|
0xEF, 0xA8, 0x44, 0x42, 0xDB, 0x1E, 0x59, 0x31, 0x17, 0xEB, 0xF5, 0x99, 0x18, 0x8E, 0x63, 0xAE, 0x2B, //3//
|
|
0x23, 0x07, 0xEB, 0xC9, 0xCD, 0xD6, 0xC7, 0xCF, 0xC8, 0xBF, 0x0F, 0xE2, 0x01, 0x16, 0x42, 0xD3, 0x1C, //4//
|
|
0x8A, 0xC4, 0x06, 0xB6, 0x51, 0xCA, 0x6F, 0xA7, 0x2E, 0x33, 0x82, 0xBD, 0x65, 0x58, 0xC0, 0xCB, 0x0D, //5//
|
|
0x0D, 0xBD, 0x5D, 0x65, 0x92, 0x77, 0x0D, 0x50, 0xAC, 0x79, 0x40, 0x86, 0x34, 0x45, 0x8F, 0x42, 0x3E, //6//
|
|
0x12, 0x8C, 0xA0, 0xAF, 0x07, 0xA1, 0xD3, 0x7D, 0x86, 0x5C, 0xA3, 0x2B, 0x80, 0x3F, 0x1D, 0x29, 0x2F, //7//
|
|
0x68, 0x15, 0xD1, 0x34, 0xE4, 0x2F, 0xF6, 0xFC, 0xEF, 0xDA, 0x5C, 0x57, 0xCF, 0xB4, 0x5A, 0x90, 0x10, //8//
|
|
0x7C, 0x49, 0xF2, 0x5A, 0xF3, 0x34, 0xBC, 0x88, 0x3A, 0x91, 0xB8, 0xC8, 0xAD, 0x03, 0x01, 0x77, 0x01, //9//
|
|
0xB0, 0x91, 0xBA, 0x23, 0x1E, 0x42, 0x72, 0xEB, 0xD2, 0xF8, 0x7E, 0x1E, 0xF7, 0x69, 0xE9, 0x0F, 0x32, //a//
|
|
0xA6, 0x32, 0x9C, 0x9D, 0x49, 0xB5, 0x98, 0x4E, 0x49, 0x00, 0xC9, 0x7F, 0x92, 0xC0, 0x2E, 0x3D, 0x23, //b//
|
|
0x54, 0x2A, 0x25, 0x07, 0x6C, 0x6C, 0xAA, 0xB2, 0xB1, 0x45, 0x27, 0xD4, 0x76, 0x27, 0xBC, 0xE8, 0x14, //c//
|
|
0xD9, 0xD0, 0xCE, 0x8C, 0x25, 0x98, 0xEB, 0x66, 0x74, 0x62, 0xE6, 0xA0, 0xEE, 0xFD, 0xF4, 0x86, 0x05, //d//
|
|
0xF5, 0x7E, 0x1F, 0xEB, 0x3F, 0xFD, 0x34, 0x04, 0x50, 0x16, 0x3D, 0x61, 0x29, 0xDC, 0xA7, 0xB5, 0x36, //e//
|
|
0x4E, 0x56, 0x39, 0xF1, 0xAA, 0x80, 0x21, 0x15, 0x9D, 0xAE, 0x94, 0x45, 0xBB, 0x72, 0x76, 0x11, 0x27 //f//
|
|
};
|
|
|
|
UCHAR Ch = Value & Mask;
|
|
int x;
|
|
|
|
//
|
|
// Scan down the column of Vtab looking for a nibble that matches Ch
|
|
// return the index in the nibble indicated by Mask.
|
|
//
|
|
|
|
for ( x = 0 ; x < 16 ; x++) {
|
|
|
|
if ( (Vtab[ (x*17) + index] & Mask) == Ch ) {
|
|
|
|
x |= x << 4; // Copy into both nibbles
|
|
return( x & Mask );
|
|
|
|
}
|
|
}
|
|
|
|
printf(" Not found Value %x, Mask %x, Index %x\n", Value, Mask, index);
|
|
return( 0 );
|
|
|
|
}
|
|
|
|
BOOLEAN
|
|
OpenServer(
|
|
PHANDLE Handle,
|
|
PWCH ServerName
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
WCHAR ServerNameBuffer[100];
|
|
UNICODE_STRING ServerNameString;
|
|
|
|
ServerNameString.Buffer = ServerNameBuffer;
|
|
ServerNameString.Length = 0;
|
|
ServerNameString.MaximumLength = 100;
|
|
|
|
status = RtlAppendUnicodeToString( &ServerNameString, DD_NWFS_DEVICE_NAME_U );
|
|
ASSERT( status == STATUS_SUCCESS );
|
|
status = RtlAppendUnicodeToString( &ServerNameString, L"\\" );
|
|
ASSERT( status == STATUS_SUCCESS );
|
|
status = RtlAppendUnicodeToString( &ServerNameString, ServerName );
|
|
ASSERT( status == STATUS_SUCCESS );
|
|
|
|
//
|
|
// Open the file
|
|
//
|
|
|
|
InitializeObjectAttributes(
|
|
&objectAttributes,
|
|
&ServerNameString,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
status = NtOpenFile (
|
|
Handle,
|
|
FILE_GENERIC_READ | SYNCHRONIZE,
|
|
&objectAttributes,
|
|
&ioStatusBlock,
|
|
FILE_SHARE_WRITE | FILE_SHARE_READ,
|
|
0L
|
|
);
|
|
|
|
if (!NT_SUCCESS(status) ) {
|
|
printf( "Open status = %x for file %Z\n", status, &ServerName );
|
|
}
|
|
|
|
return ( (BOOLEAN) NT_SUCCESS( status ) );
|
|
}
|
|
|
|
|
|
CHAR Buffer1[100];
|
|
CHAR Buffer2[100];
|
|
|
|
SendMessage(
|
|
IN char* Format,
|
|
...
|
|
)
|
|
{
|
|
NTSTATUS status = -1;
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
va_list Arguments;
|
|
NTSTATUS Status;
|
|
ULONG ReceiveBufferSize = 100;
|
|
ULONG SendBufferSize = 100;
|
|
|
|
va_start( Arguments, Format );
|
|
|
|
Buffer1[0] = Pid;
|
|
|
|
Status = FormatRequest( &Buffer1[1], &SendBufferSize, Format, Arguments );
|
|
if ( !NT_SUCCESS( Status ) ) {
|
|
return( Status );
|
|
}
|
|
|
|
//printf("Sending message\n" );
|
|
//dump( Buffer1, SendBufferSize + 1);
|
|
|
|
status = NtFsControlFile(
|
|
ServerHandle,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&IoStatusBlock,
|
|
FSCTL_NWR_ANY_NCP,
|
|
Buffer1,
|
|
SendBufferSize + 1,
|
|
Buffer2,
|
|
ReceiveBufferSize
|
|
);
|
|
if ( NT_SUCCESS( status ) ) {
|
|
|
|
status = NtWaitForSingleObject( ServerHandle, FALSE, NULL );
|
|
if ( NT_SUCCESS( status )) {
|
|
status = IoStatusBlock.Status;
|
|
}
|
|
}
|
|
|
|
|
|
if ( !NT_SUCCESS( status ) ) {
|
|
printf("SendPacket returns %08lx\n", status );
|
|
} else {
|
|
printf("Send succeeded.\n" );
|
|
//dump( Buffer2, IoStatusBlock.Information );
|
|
}
|
|
return( status );
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
FormatRequest(
|
|
PCHAR SendBuffer,
|
|
PULONG SendBufferLength,
|
|
char* Format,
|
|
va_list a
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Send the packet described by Format and the additional parameters.
|
|
|
|
Arguments:
|
|
|
|
Format - the information needed to create the request to the
|
|
server. The first byte indicates the packet type and the
|
|
following bytes contain field types.
|
|
|
|
Packet types:
|
|
|
|
'A' SAP broadcast ( void )
|
|
'C' NCP connect ( void )
|
|
'F' NCP function ( byte )
|
|
'S' NCP subfunction ( byte, byte )
|
|
'D' NCP disconnect ( void )
|
|
|
|
Field types, request/response:
|
|
|
|
'b' byte ( byte / byte* )
|
|
'w' hi-lo word ( word / word* )
|
|
'd' hi-lo dword ( dword / dword* )
|
|
'-' zero/skip byte ( void )
|
|
'=' zero/skip word ( void )
|
|
._. zero/skip string ( word )
|
|
'p' pstring ( char* )
|
|
'u' p unicode string ( UNICODE_STRING * )
|
|
'c' cstring ( char* )
|
|
'r' raw bytes ( byte*, word )
|
|
'u' p unicode string ( UNICODE_STRING * )
|
|
'U' p uppercase string( UNICODE_STRING * )
|
|
'f' separate fragment ( PMDL )
|
|
|
|
An 'f' field must be last, and in a response it cannot be
|
|
preceeded by 'p' or 'c' fields.
|
|
|
|
|
|
Return Value:
|
|
|
|
Normally returns STATUS_PENDING.
|
|
|
|
--*/
|
|
{
|
|
NTSTATUS status;
|
|
char* pFormatCharacter;
|
|
USHORT t = 1;
|
|
ULONG data_size;
|
|
ULONG length;
|
|
|
|
data_size = 1;
|
|
|
|
SendBuffer[ 0 ] = va_arg( a, UCHAR );
|
|
|
|
if ( *Format == 'S' ) {
|
|
data_size += 2;
|
|
SendBuffer[data_size++] = va_arg( a, UCHAR );
|
|
}
|
|
|
|
pFormatCharacter = Format;
|
|
|
|
while ( *++pFormatCharacter && *pFormatCharacter != 'f' )
|
|
{
|
|
switch ( *pFormatCharacter ) {
|
|
|
|
case '=':
|
|
SendBuffer[data_size++] = 0;
|
|
case '-':
|
|
SendBuffer[data_size++] = 0;
|
|
break;
|
|
|
|
case '_':
|
|
length = va_arg ( a, USHORT );
|
|
|
|
if ( data_size + length > *SendBufferLength ) {
|
|
printf("***exch:!0!\n");
|
|
return( FALSE );
|
|
}
|
|
|
|
while ( length-- ) {
|
|
SendBuffer[data_size++] = 0;
|
|
}
|
|
|
|
break;
|
|
|
|
case 'b':
|
|
SendBuffer[data_size++] = va_arg ( a, UCHAR );
|
|
break;
|
|
|
|
case 'w':
|
|
{
|
|
USHORT w = va_arg ( a, USHORT );
|
|
|
|
SendBuffer[data_size++] = (UCHAR) (w >> 8);
|
|
SendBuffer[data_size++] = (UCHAR) (w >> 0);
|
|
break;
|
|
}
|
|
|
|
case 'd':
|
|
{
|
|
ULONG d = va_arg ( a, ULONG );
|
|
|
|
SendBuffer[data_size++] = (UCHAR) (d >> 24);
|
|
SendBuffer[data_size++] = (UCHAR) (d >> 16);
|
|
SendBuffer[data_size++] = (UCHAR) (d >> 8);
|
|
SendBuffer[data_size++] = (UCHAR) (d >> 0);
|
|
break;
|
|
}
|
|
|
|
case 'c':
|
|
{
|
|
char* c = va_arg ( a, char* );
|
|
|
|
length = strlen( c );
|
|
|
|
if ( data_size + length > *SendBufferLength ) {
|
|
printf("***exch:!1!\n");
|
|
return( FALSE );
|
|
}
|
|
|
|
RtlCopyMemory( &SendBuffer[data_size], c, length + 1 );
|
|
data_size += length + 1;
|
|
break;
|
|
}
|
|
|
|
case 'p':
|
|
{
|
|
char* c = va_arg ( a, char* );
|
|
|
|
length = strlen( c );
|
|
|
|
if ( data_size + length > *SendBufferLength ) {
|
|
printf("***exch:!2!\n");
|
|
return FALSE;
|
|
}
|
|
|
|
SendBuffer[data_size++] = (UCHAR)length;
|
|
RtlCopyMemory( &SendBuffer[data_size], c, length );
|
|
data_size += length;
|
|
break;
|
|
}
|
|
|
|
case 'u':
|
|
{
|
|
PUNICODE_STRING pUString = va_arg ( a, PUNICODE_STRING );
|
|
OEM_STRING OemString;
|
|
|
|
//
|
|
// Calculate required string length, excluding trailing NUL.
|
|
//
|
|
|
|
length = (USHORT)RtlUnicodeStringToOemSize( pUString ) - 1;
|
|
ASSERT( length < 0x100 );
|
|
|
|
if ( data_size + length > *SendBufferLength ) {
|
|
printf("***exch:!4!\n");
|
|
return( FALSE );
|
|
}
|
|
|
|
SendBuffer[data_size++] = (UCHAR)length;
|
|
OemString.Buffer = &SendBuffer[data_size];
|
|
OemString.MaximumLength = (USHORT)length + 1;
|
|
status = RtlUnicodeStringToCountedOemString( &OemString, pUString, FALSE );
|
|
ASSERT( NT_SUCCESS( status ));
|
|
data_size += (USHORT)length;
|
|
break;
|
|
}
|
|
|
|
case 'U':
|
|
{
|
|
USHORT i;
|
|
|
|
//
|
|
// UPPERCASE the string, copy it from unicode to the packet
|
|
//
|
|
|
|
PUNICODE_STRING pUString = va_arg ( a, PUNICODE_STRING );
|
|
UNICODE_STRING UUppercaseString;
|
|
OEM_STRING OemString;
|
|
|
|
if ( pUString->Length > 0 ) {
|
|
|
|
RtlUpcaseUnicodeString( &UUppercaseString, pUString, TRUE );
|
|
|
|
//
|
|
// Change all '\' to '/'
|
|
//
|
|
|
|
for ( i = 0 ; i < UUppercaseString.Length ; i++ ) {
|
|
if ( UUppercaseString.Buffer[i] == L'\\' ) {
|
|
UUppercaseString.Buffer[i] = L'/';
|
|
}
|
|
}
|
|
|
|
//
|
|
// Calculate required string length, excluding trailing NUL.
|
|
//
|
|
|
|
length = (USHORT)RtlUnicodeStringToOemSize( &UUppercaseString ) - 1;
|
|
ASSERT( length < 0x100 );
|
|
|
|
} else {
|
|
UUppercaseString = *pUString;
|
|
length = 0;
|
|
}
|
|
|
|
if ( data_size + length > *SendBufferLength ) {
|
|
printf("***exch:!5!\n");
|
|
return( FALSE );
|
|
}
|
|
|
|
SendBuffer[data_size++] = (UCHAR)length;
|
|
OemString.Buffer = &SendBuffer[data_size];
|
|
OemString.MaximumLength = (USHORT)length + 1;
|
|
status = RtlUnicodeStringToCountedOemString( &OemString,
|
|
&UUppercaseString,
|
|
FALSE );
|
|
ASSERT( NT_SUCCESS( status ));
|
|
|
|
if ( pUString->Length > 0 ) {
|
|
RtlFreeUnicodeString( &UUppercaseString );
|
|
}
|
|
|
|
data_size += (USHORT)length;
|
|
break;
|
|
}
|
|
|
|
case 'r':
|
|
{
|
|
UCHAR* b = va_arg ( a, UCHAR* );
|
|
length = va_arg ( a, USHORT );
|
|
|
|
if ( data_size + length > *SendBufferLength ) {
|
|
printf("***exch:!6!\n");
|
|
return( FALSE );
|
|
}
|
|
|
|
RtlCopyMemory( &SendBuffer[data_size], b, length );
|
|
data_size += length;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
printf ( "*****exchange: invalid request field, %x\n", *pFormatCharacter);
|
|
return( FALSE );
|
|
}
|
|
|
|
if ( data_size > *SendBufferLength ) {
|
|
printf( "*****exchange: CORRUPT, too much request data\n" );
|
|
va_end( a );
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if ( *Format == 'S' )
|
|
{
|
|
SendBuffer[1] = (UCHAR)((data_size-3) >> 8);
|
|
SendBuffer[2] = (UCHAR)(data_size-3);
|
|
}
|
|
|
|
va_end( a );
|
|
|
|
*SendBufferLength = data_size;
|
|
return TRUE;
|
|
}
|
|
|
|
NTSTATUS
|
|
_cdecl
|
|
ParseResponse(
|
|
char* FormatString,
|
|
... // format specific parameters
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine parse an NCP response.
|
|
|
|
Arguments:
|
|
|
|
FormatString - supplies the information needed to create the request to the
|
|
server. The first byte indicates the packet type and the
|
|
following bytes contain field types.
|
|
|
|
Field types, request/response:
|
|
|
|
'b' byte ( byte* )
|
|
'w' hi-lo word ( word* )
|
|
'd' hi-lo dword ( dword* )
|
|
'-' zero/skip byte ( void )
|
|
'=' zero/skip word ( void )
|
|
._. zero/skip string ( word )
|
|
'p' pstring ( char* )
|
|
'c' cstring ( char* )
|
|
'r' raw bytes ( byte*, word )
|
|
'R' ASCIIZ to Unicode ( UNICODE_STRING *, word )
|
|
|
|
Return Value:
|
|
|
|
STATUS - The converted error code from the NCP response.
|
|
|
|
--*/
|
|
|
|
{
|
|
PCHAR FormatByte;
|
|
va_list Arguments;
|
|
int Length = 0;
|
|
|
|
va_start( Arguments, FormatString );
|
|
|
|
FormatByte = FormatString;
|
|
while ( *FormatByte ) {
|
|
|
|
switch ( *FormatByte ) {
|
|
|
|
case '-':
|
|
Length += 1;
|
|
break;
|
|
|
|
case '=':
|
|
Length += 2;
|
|
break;
|
|
|
|
case '_':
|
|
{
|
|
USHORT l = va_arg ( Arguments, USHORT );
|
|
Length += l;
|
|
break;
|
|
}
|
|
|
|
case 'b':
|
|
{
|
|
UCHAR* b = va_arg ( Arguments, UCHAR* );
|
|
*b = Buffer2[Length++];
|
|
break;
|
|
}
|
|
|
|
case 'w':
|
|
{
|
|
UCHAR* b = va_arg ( Arguments, UCHAR* );
|
|
b[1] = Buffer2[Length++];
|
|
b[0] = Buffer2[Length++];
|
|
break;
|
|
}
|
|
|
|
case 'd':
|
|
{
|
|
UCHAR* b = va_arg ( Arguments, UCHAR* );
|
|
b[3] = Buffer2[Length++];
|
|
b[2] = Buffer2[Length++];
|
|
b[1] = Buffer2[Length++];
|
|
b[0] = Buffer2[Length++];
|
|
break;
|
|
}
|
|
|
|
case 'c':
|
|
{
|
|
char* c = va_arg ( Arguments, char* );
|
|
USHORT l = strlen( &Buffer2[Length] );
|
|
memcpy ( c, &Buffer2[Length], l+1 );
|
|
Length += l+1;
|
|
break;
|
|
}
|
|
|
|
case 'p':
|
|
{
|
|
char* c = va_arg ( Arguments, char* );
|
|
UCHAR l = Buffer2[Length++];
|
|
memcpy ( c, &Buffer2[Length], l );
|
|
c[l+1] = 0;
|
|
break;
|
|
}
|
|
|
|
#if 0
|
|
case 'P':
|
|
{
|
|
PUNICODE_STRING pUString = va_arg ( Arguments, PUNICODE_STRING );
|
|
OEM_STRING OemString;
|
|
|
|
OemString.Length = Buffer2[Length++];
|
|
OemString.Buffer = &Buffer2[Length];
|
|
|
|
Status = RtlOemStringToCountedUnicodeString( pUString, &OemString, FALSE );
|
|
ASSERT( NT_SUCCESS( Status ));
|
|
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
case 'r':
|
|
{
|
|
UCHAR* b = va_arg ( Arguments, UCHAR* );
|
|
USHORT l = va_arg ( Arguments, USHORT );
|
|
RtlCopyMemory( b, &Buffer2[Length], l );
|
|
Length += l;
|
|
break;
|
|
}
|
|
|
|
#if 0
|
|
case 'R':
|
|
{
|
|
//
|
|
// Interpret the buffer as an ASCIIZ string. Convert
|
|
// it to unicode in the preallocated buffer.
|
|
//
|
|
|
|
PUNICODE_STRING pUString = va_arg ( Arguments, PUNICODE_STRING );
|
|
OEM_STRING OemString;
|
|
USHORT len = va_arg ( Arguments, USHORT );
|
|
|
|
OemString.Buffer = &Buffer2[Length];
|
|
OemString.Length = strlen( OemString.Buffer );
|
|
OemString.MaximumLength = OemString.Length;
|
|
|
|
Status = RtlOemStringToCountedUnicodeString( pUString, &OemString, FALSE );
|
|
ASSERT( NT_SUCCESS( Status ));
|
|
Length += len;
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
default:
|
|
printf ( "*****exchange: invalid response field, %x\n", *FormatByte );
|
|
return( FALSE );
|
|
}
|
|
|
|
#if 0
|
|
if ( Length > PacketLength )
|
|
{
|
|
printf ( "*****exchange: not enough response data, %d\n", i );
|
|
}
|
|
#endif
|
|
FormatByte++;
|
|
}
|
|
|
|
va_end( Arguments );
|
|
}
|
|
|
|
|
|
// Hex dump
|
|
|
|
VOID
|
|
dump(
|
|
IN PVOID far_p,
|
|
IN ULONG len
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
Dump Min(len, MaxDump) bytes in classic hex dump style.
|
|
|
|
Arguments:
|
|
|
|
IN far_p - address of buffer to start dumping from.
|
|
|
|
IN len - length in bytes of buffer.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
ULONG l;
|
|
char s[80], t[80];
|
|
PCHAR far_pchar = (PCHAR)far_p;
|
|
|
|
if (len > MaxDump)
|
|
len = MaxDump;
|
|
|
|
while (len) {
|
|
l = len < 17 ? len : 17;
|
|
|
|
// printf("\n%lx ", far_pchar);
|
|
HexDumpLine (far_pchar, l, s, t, 0);
|
|
// printf("%s%.*s%s", s, 1 + ((16 - l) * 3), "", t);
|
|
printf("%s", s);
|
|
|
|
len -= l;
|
|
far_pchar += l;
|
|
}
|
|
printf("\n");
|
|
}
|
|
|
|
VOID
|
|
HexDumpLine (
|
|
PCHAR pch,
|
|
ULONG len,
|
|
PCHAR s,
|
|
PCHAR t,
|
|
USHORT flag
|
|
)
|
|
{
|
|
static UCHAR rghex[] = "0123456789ABCDEF";
|
|
|
|
UCHAR c;
|
|
UCHAR *hex, *asc;
|
|
|
|
|
|
hex = s;
|
|
asc = t;
|
|
|
|
*(asc++) = '*';
|
|
while (len--) {
|
|
c = *(pch++);
|
|
*(hex++) = rghex [c >> 4] ;
|
|
*(hex++) = rghex [c & 0x0F];
|
|
*(hex++) = ' ';
|
|
*(asc++) = (c < ' ' || c > '~') ? (CHAR )'.' : c;
|
|
}
|
|
*(asc++) = '*';
|
|
*asc = 0;
|
|
*hex = 0;
|
|
|
|
flag;
|
|
}
|
|
|
|
// End Hex dump
|
|
|
|
UCHAR Table[] =
|
|
{0x7,0x8,0x0,0x8,0x6,0x4,0xE,0x4,0x5,0xC,0x1,0x7,0xB,0xF,0xA,0x8,
|
|
0xF,0x8,0xC,0xC,0x9,0x4,0x1,0xE,0x4,0x6,0x2,0x4,0x0,0xA,0xB,0x9,
|
|
0x2,0xF,0xB,0x1,0xD,0x2,0x1,0x9,0x5,0xE,0x7,0x0,0x0,0x2,0x6,0x6,
|
|
0x0,0x7,0x3,0x8,0x2,0x9,0x3,0xF,0x7,0xF,0xC,0xF,0x6,0x4,0xA,0x0,
|
|
0x2,0x3,0xA,0xB,0xD,0x8,0x3,0xA,0x1,0x7,0xC,0xF,0x1,0x8,0x9,0xD,
|
|
0x9,0x1,0x9,0x4,0xE,0x4,0xC,0x5,0x5,0xC,0x8,0xB,0x2,0x3,0x9,0xE,
|
|
0x7,0x7,0x6,0x9,0xE,0xF,0xC,0x8,0xD,0x1,0xA,0x6,0xE,0xD,0x0,0x7,
|
|
0x7,0xA,0x0,0x1,0xF,0x5,0x4,0xB,0x7,0xB,0xE,0xC,0x9,0x5,0xD,0x1,
|
|
0xB,0xD,0x1,0x3,0x5,0xD,0xE,0x6,0x3,0x0,0xB,0xB,0xF,0x3,0x6,0x4,
|
|
0x9,0xD,0xA,0x3,0x1,0x4,0x9,0x4,0x8,0x3,0xB,0xE,0x5,0x0,0x5,0x2,
|
|
0xC,0xB,0xD,0x5,0xD,0x5,0xD,0x2,0xD,0x9,0xA,0xC,0xA,0x0,0xB,0x3,
|
|
0x5,0x3,0x6,0x9,0x5,0x1,0xE,0xE,0x0,0xE,0x8,0x2,0xD,0x2,0x2,0x0,
|
|
0x4,0xF,0x8,0x5,0x9,0x6,0x8,0x6,0xB,0xA,0xB,0xF,0x0,0x7,0x2,0x8,
|
|
0xC,0x7,0x3,0xA,0x1,0x4,0x2,0x5,0xF,0x7,0xA,0xC,0xE,0x5,0x9,0x3,
|
|
0xE,0x7,0x1,0x2,0xE,0x1,0xF,0x4,0xA,0x6,0xC,0x6,0xF,0x4,0x3,0x0,
|
|
0xC,0x0,0x3,0x6,0xF,0x8,0x7,0xB,0x2,0xD,0xC,0x6,0xA,0xA,0x8,0xD};
|
|
|
|
UCHAR Keys[32] =
|
|
{0x48,0x93,0x46,0x67,0x98,0x3D,0xE6,0x8D,
|
|
0xB7,0x10,0x7A,0x26,0x5A,0xB9,0xB1,0x35,
|
|
0x6B,0x0F,0xD5,0x70,0xAE,0xFB,0xAD,0x11,
|
|
0xF4,0x47,0xDC,0xA7,0xEC,0xCF,0x50,0xC0};
|
|
|
|
#define XorArray( DEST, SRC ) { \
|
|
PULONG D = (PULONG)DEST; \
|
|
PULONG S = (PULONG)SRC; \
|
|
int i; \
|
|
for ( i = 0; i <= 7 ; i++ ) { \
|
|
D[i] ^= S[i]; \
|
|
} \
|
|
}
|
|
|
|
VOID
|
|
RespondToChallenge(
|
|
IN PUCHAR achObjectId,
|
|
IN POEM_STRING Password,
|
|
IN PUCHAR pChallenge,
|
|
OUT PUCHAR pResponse
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine takes the ObjectId and Challenge key from the server and
|
|
encrypts the user supplied password to develop a credential for the
|
|
server to verify.
|
|
|
|
Arguments:
|
|
IN PUCHAR achObjectId - Supplies the 4 byte user's bindery object id
|
|
IN POEM_STRING Password - Supplies the user's uppercased password
|
|
IN PUCHAR pChallenge - Supplies the 8 byte challenge key
|
|
OUT PUCHAR pResponse - Returns the 8 byte response
|
|
|
|
Return Value:
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
int index;
|
|
UCHAR achK[32];
|
|
UCHAR achBuf[32];
|
|
|
|
Shuffle(achObjectId, Password->Buffer, Password->Length, achBuf);
|
|
Shuffle( &pChallenge[0], achBuf, 16, &achK[0] );
|
|
Shuffle( &pChallenge[4], achBuf, 16, &achK[16] );
|
|
|
|
for (index = 0; index < 16; index++)
|
|
achK[index] ^= achK[31-index];
|
|
|
|
for (index = 0; index < 8; index++)
|
|
pResponse[index] = achK[index] ^ achK[15-index];
|
|
}
|
|
|
|
VOID
|
|
RespondToChallengePart1(
|
|
IN PUCHAR achObjectId,
|
|
IN POEM_STRING Password,
|
|
OUT PUCHAR pResponse
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine takes the ObjectId and Challenge key from the server and
|
|
encrypts the user supplied password to develop a credential for the
|
|
server to verify.
|
|
|
|
Arguments:
|
|
IN PUCHAR achObjectId - Supplies the 4 byte user's bindery object id
|
|
IN POEM_STRING Password - Supplies the user's uppercased password
|
|
IN PUCHAR pChallenge - Supplies the 8 byte challenge key
|
|
OUT PUCHAR pResponse - Returns the 16 byte response held by the server
|
|
|
|
Return Value:
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
UCHAR achBuf[32];
|
|
|
|
Shuffle(achObjectId, Password->Buffer, Password->Length, achBuf);
|
|
memmove(pResponse, achBuf, 16);
|
|
}
|
|
|
|
VOID
|
|
RespondToChallengePart2(
|
|
IN PUCHAR pResponsePart1,
|
|
IN PUCHAR pChallenge,
|
|
OUT PUCHAR pResponse
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine takes the result of Shuffling the ObjectId and the Password
|
|
and processes it with a challenge key.
|
|
|
|
Arguments:
|
|
IN PUCHAR pResponsePart1 - Supplies the 16 byte output of
|
|
RespondToChallengePart1.
|
|
IN PUCHAR pChallenge - Supplies the 8 byte challenge key
|
|
OUT PUCHAR pResponse - Returns the 8 byte response
|
|
|
|
Return Value:
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
int index;
|
|
UCHAR achK[32];
|
|
|
|
Shuffle( &pChallenge[0], pResponsePart1, 16, &achK[0] );
|
|
Shuffle( &pChallenge[4], pResponsePart1, 16, &achK[16] );
|
|
|
|
for (index = 0; index < 16; index++)
|
|
achK[index] ^= achK[31-index];
|
|
|
|
for (index = 0; index < 8; index++)
|
|
pResponse[index] = achK[index] ^ achK[15-index];
|
|
}
|
|
|
|
VOID
|
|
Shuffle(
|
|
UCHAR *achObjectId,
|
|
UCHAR *szUpperPassword,
|
|
int iPasswordLen,
|
|
UCHAR *achOutputBuffer
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine shuffles around the object ID with the password
|
|
|
|
Arguments:
|
|
|
|
IN achObjectId - Supplies the 4 byte user's bindery object id
|
|
|
|
IN szUpperPassword - Supplies the user's uppercased password on the
|
|
first call to process the password. On the second and third calls
|
|
this parameter contains the OutputBuffer from the first call
|
|
|
|
IN iPasswordLen - length of uppercased password
|
|
|
|
OUT achOutputBuffer - Returns the 8 byte sub-calculation
|
|
|
|
Return Value:
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
int iTempIndex;
|
|
int iOutputIndex;
|
|
UCHAR achTemp[32];
|
|
|
|
//
|
|
// Initialize the achTemp buffer. Initialization consists of taking
|
|
// the password and dividing it up into chunks of 32. Any bytes left
|
|
// over are the remainder and do not go into the initialization.
|
|
//
|
|
// achTemp[0] = szUpperPassword[0] ^ szUpperPassword[32] ^ szUpper...
|
|
// achTemp[1] = szUpperPassword[1] ^ szUpperPassword[33] ^ szUpper...
|
|
// etc.
|
|
//
|
|
|
|
if ( iPasswordLen > 32) {
|
|
|
|
// At least one chunk of 32. Set the buffer to the first chunk.
|
|
|
|
RtlCopyMemory( achTemp, szUpperPassword, 32 );
|
|
|
|
szUpperPassword +=32; // Remove the first chunk
|
|
iPasswordLen -=32;
|
|
|
|
while ( iPasswordLen >= 32 ) {
|
|
//
|
|
// Xor this chunk with the characters already loaded into
|
|
// achTemp.
|
|
//
|
|
|
|
XorArray( achTemp, szUpperPassword);
|
|
|
|
szUpperPassword +=32; // Remove this chunk
|
|
iPasswordLen -=32;
|
|
}
|
|
|
|
} else {
|
|
|
|
// No chunks of 32 so set the buffer to zero's
|
|
|
|
RtlZeroMemory( achTemp, sizeof(achTemp));
|
|
|
|
}
|
|
|
|
//
|
|
// achTemp is now initialized. Load the remainder into achTemp.
|
|
// The remainder is repeated to fill achTemp.
|
|
//
|
|
// The corresponding character from Keys is taken to seperate
|
|
// each repitition.
|
|
//
|
|
// As an example, take the remainder "ABCDEFG". The remainder is expanded
|
|
// to "ABCDEFGwABCDEFGxABCDEFGyABCDEFGz" where w is Keys[7],
|
|
// x is Keys[15], y is Keys[23] and z is Keys[31].
|
|
//
|
|
//
|
|
|
|
if (iPasswordLen > 0) {
|
|
int iPasswordOffset = 0;
|
|
for (iTempIndex = 0; iTempIndex < 32; iTempIndex++) {
|
|
|
|
if (iPasswordLen == iPasswordOffset) {
|
|
iPasswordOffset = 0;
|
|
achTemp[iTempIndex] ^= Keys[iTempIndex];
|
|
} else {
|
|
achTemp[iTempIndex] ^= szUpperPassword[iPasswordOffset++];
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// achTemp has been loaded with the users password packed into 32
|
|
// bytes. Now take the objectid that came from the server and use
|
|
// that to munge every byte in achTemp.
|
|
//
|
|
|
|
for (iTempIndex = 0; iTempIndex < 32; iTempIndex++)
|
|
achTemp[iTempIndex] ^= achObjectId[ iTempIndex & 3];
|
|
|
|
Scramble( Scramble( 0, achTemp ), achTemp );
|
|
|
|
//
|
|
// Finally take pairs of bytes in achTemp and return the two
|
|
// nibbles obtained from Table. The pairs of bytes used
|
|
// are achTemp[n] and achTemp[n+16].
|
|
//
|
|
|
|
for (iOutputIndex = 0; iOutputIndex < 16; iOutputIndex++) {
|
|
|
|
achOutputBuffer[iOutputIndex] =
|
|
Table[achTemp[iOutputIndex << 1]] |
|
|
(Table[achTemp[(iOutputIndex << 1) + 1]] << 4);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
int
|
|
Scramble(
|
|
int iSeed,
|
|
UCHAR achBuffer[32]
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine scrambles around the contents of the buffer. Each buffer
|
|
position is updated to include the contents of at least two character
|
|
positions plus an EncryptKey value. The buffer is processed left to right
|
|
and so if a character position chooses to merge with a buffer position
|
|
to its left then this buffer position will include bits derived from at
|
|
least 3 bytes of the original buffer contents.
|
|
|
|
Arguments:
|
|
|
|
IN iSeed
|
|
IN OUT achBuffer[32]
|
|
|
|
Return Value:
|
|
|
|
none.
|
|
|
|
--*/
|
|
|
|
{
|
|
int iBufferIndex;
|
|
|
|
for (iBufferIndex = 0; iBufferIndex < 32; iBufferIndex++) {
|
|
achBuffer[iBufferIndex] =
|
|
(UCHAR)(
|
|
((UCHAR)(achBuffer[iBufferIndex] + iSeed)) ^
|
|
((UCHAR)( achBuffer[(iBufferIndex+iSeed) & 31] -
|
|
Keys[iBufferIndex] )));
|
|
|
|
iSeed += achBuffer[iBufferIndex];
|
|
}
|
|
return iSeed;
|
|
}
|
|
|