https://git.reactos.org/?p=reactos.git;a=commitdiff;h=782ff23261613bb745d553...
commit 782ff23261613bb745d553d95addbe1befbd4c8f Author: Andreas Maier staubim@quantentunnel.de AuthorDate: Sun Feb 16 11:05:25 2020 +0100 Commit: Thomas Faber thomas.faber@reactos.org 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.ke...: + * "... 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 */
//