https://git.reactos.org/?p=reactos.git;a=commitdiff;h=782ff23261613bb745d553d95addbe1befbd4c8f

commit 782ff23261613bb745d553d95addbe1befbd4c8f
Author:     Andreas Maier <[email protected]>
AuthorDate: Sun Feb 16 11:05:25 2020 +0100
Commit:     Thomas Faber <[email protected]>
CommitDate: Sat Mar 28 23:27:34 2020 +0100

    [MSV1_0] LsaApLogonUserEx2: use RtlRunDecodeUnicodeString to decode password
---
 dll/win32/msv1_0/msv1_0.c  | 29 +++++++++++++++++++++++++++++
 sdk/include/ndk/rtlfuncs.h | 16 ++++++++++++++++
 2 files changed, 45 insertions(+)

diff --git a/dll/win32/msv1_0/msv1_0.c b/dll/win32/msv1_0/msv1_0.c
index 6994940290c..6db439cc762 100644
--- a/dll/win32/msv1_0/msv1_0.c
+++ b/dll/win32/msv1_0/msv1_0.c
@@ -1193,6 +1193,8 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest,
     LARGE_INTEGER PasswordLastSet;
     DWORD ComputerNameSize;
     BOOL SpecialAccount = FALSE;
+    UCHAR LogonPassHash;
+    PUNICODE_STRING ErasePassword = NULL;
 
     TRACE("LsaApLogonUserEx2()\n");
 
@@ -1268,6 +1270,18 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest,
         Status = RtlValidateUnicodeString(0, &LogonInfo->UserName);
         if (!NT_SUCCESS(Status))
             return STATUS_INVALID_PARAMETER;
+
+        /* MS docs says max length is 0xFF bytes. But thats not the full story:
+         *
+         * A Quote from 
https://groups.google.com/forum/#!topic/microsoft.public.win32.programmer.kernel/eFGcCo_ZObk:
+         * "... At least on my WinXP SP2. Domain and UserName are passed
+         * in clear text, but the Password is NOT. ..."
+         *
+         * If the higher byte of length != 0 we have to use 
RtlRunDecodeUnicodeString.
+         */
+        LogonPassHash = (LogonInfo->Password.Length >> 8) & 0xFF;
+        LogonInfo->Password.Length = LogonInfo->Password.Length & 0xFF;
+
         /* Password is optional and can be an empty string */
         if (LogonInfo->Password.Length)
         {
@@ -1281,6 +1295,15 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest,
             LogonInfo->Password.MaximumLength = 0;
         }
 
+        /* Decode password */
+        if (LogonPassHash > 0)
+        {
+            RtlRunDecodeUnicodeString(LogonPassHash, &LogonInfo->Password);
+        }
+
+        /* ErasePassword will be "erased" before we return */
+        ErasePassword = &LogonInfo->Password;
+
         Status = RtlValidateUnicodeString(0, &LogonInfo->Password);
         if (!NT_SUCCESS(Status))
             return STATUS_INVALID_PARAMETER;
@@ -1574,6 +1597,12 @@ LsaApLogonUserEx2(IN PLSA_CLIENT_REQUEST ClientRequest,
     }
 
 done:
+    /* Erase password */
+    if (ErasePassword)
+    {
+        RtlEraseUnicodeString(ErasePassword);
+    }
+
     /* Update the logon time/count or the bad password time/count */
     if ((UserHandle != NULL) &&
         (Status == STATUS_SUCCESS || Status == STATUS_WRONG_PASSWORD))
diff --git a/sdk/include/ndk/rtlfuncs.h b/sdk/include/ndk/rtlfuncs.h
index 68f43745199..1e386af2861 100644
--- a/sdk/include/ndk/rtlfuncs.h
+++ b/sdk/include/ndk/rtlfuncs.h
@@ -2435,6 +2435,22 @@ RtlFreeBuffer(
     Buffer->Size = Buffer->StaticSize;
 }
 
+NTSYSAPI
+VOID
+NTAPI
+RtlRunEncodeUnicodeString(
+    _Inout_ PUCHAR Hash,
+    _Inout_ PUNICODE_STRING String
+);
+
+NTSYSAPI
+VOID
+NTAPI
+RtlRunDecodeUnicodeString(
+    _In_ UCHAR Hash,
+    _Inout_ PUNICODE_STRING String
+);
+
 #endif /* NTOS_MODE_USER */
 
 //

Reply via email to