summaryrefslogtreecommitdiffstats
path: root/private/nw/test/tp2.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/nw/test/tp2.c')
-rw-r--r--private/nw/test/tp2.c1560
1 files changed, 1560 insertions, 0 deletions
diff --git a/private/nw/test/tp2.c b/private/nw/test/tp2.c
new file mode 100644
index 000000000..004161df8
--- /dev/null
+++ b/private/nw/test/tp2.c
@@ -0,0 +1,1560 @@
+/*++
+
+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;
+}
+