https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e5fcda922b0ad049f2281…
commit e5fcda922b0ad049f22815a6ea1258205fa17927
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Tue Sep 18 21:33:29 2018 +0200
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Tue Sep 18 21:33:29 2018 +0200
[ADVAPI32][SERVICES] Pass encrypted passwords to the service manager.
- Encrypt passwords before passing them to the service manager. Right now, we are
using a fixed encryption key. This will be fixed later.
- Replace the calls to ZeroMemory which are used to wipe the password buffers by calls
to SecureZeroMemory.
---
base/system/services/config.c | 58 +++++++++++++++++++++++++++++++---
dll/win32/advapi32/service/scm.c | 67 +++++++++++++++++++++++++++++++---------
2 files changed, 106 insertions(+), 19 deletions(-)
diff --git a/base/system/services/config.c b/base/system/services/config.c
index 14af8e5b0f..4d1f2471c6 100644
--- a/base/system/services/config.c
+++ b/base/system/services/config.c
@@ -15,6 +15,20 @@
#define NDEBUG
#include <debug.h>
+struct ustring
+{
+ DWORD Length;
+ DWORD MaximumLength;
+ unsigned char *Buffer;
+};
+
+NTSTATUS
+WINAPI
+SystemFunction005(
+ const struct ustring *in,
+ const struct ustring *key,
+ struct ustring *out);
+
/* FUNCTIONS *****************************************************************/
@@ -684,17 +698,51 @@ ScmDecryptPassword(
_In_ DWORD dwPasswordSize,
_Out_ PWSTR *pClearTextPassword)
{
+ struct ustring inData, keyData, outData;
+ PCHAR pszKey = "TestEncryptionKey";
PWSTR pBuffer;
+ NTSTATUS Status;
+
+ inData.Length = dwPasswordSize;
+ inData.MaximumLength = inData.Length;
+ inData.Buffer = pPassword;
+
+ keyData.Length = strlen(pszKey);
+ keyData.MaximumLength = keyData.Length;
+ keyData.Buffer = (unsigned char *)pszKey;
+
+ outData.Length = 0;
+ outData.MaximumLength = 0;
+ outData.Buffer = NULL;
+
+ /* Get the required buffer size */
+ Status = SystemFunction005(&inData,
+ &keyData,
+ &outData);
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ DPRINT1("SystemFunction005 failed (Status 0x%08lx)\n", Status);
+ return RtlNtStatusToDosError(Status);
+ }
- /* Allocate a buffer for the decrypted password */
- pBuffer = HeapAlloc(GetProcessHeap(), 0, dwPasswordSize);
+ /* Allocate a buffer for the clear text password */
+ pBuffer = HeapAlloc(GetProcessHeap(), 0, outData.Length);
if (pBuffer == NULL)
return ERROR_OUTOFMEMORY;
+ outData.MaximumLength = outData.Length;
+ outData.Buffer = (unsigned char *)pBuffer;
+
/* Decrypt the password */
- CopyMemory(pBuffer,
- pPassword,
- dwPasswordSize);
+ Status = SystemFunction005(&inData,
+ &keyData,
+ &outData);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("SystemFunction005 failed (Status 0x%08lx)\n", Status);
+ HeapFree(GetProcessHeap(), 0, pBuffer);
+ return RtlNtStatusToDosError(Status);
+ }
*pClearTextPassword = pBuffer;
diff --git a/dll/win32/advapi32/service/scm.c b/dll/win32/advapi32/service/scm.c
index 022864bba9..efa19f2b35 100644
--- a/dll/win32/advapi32/service/scm.c
+++ b/dll/win32/advapi32/service/scm.c
@@ -12,6 +12,12 @@
#include <advapi32.h>
WINE_DEFAULT_DEBUG_CHANNEL(advapi);
+NTSTATUS
+WINAPI
+SystemFunction004(
+ const struct ustring *in,
+ const struct ustring *key,
+ struct ustring *out);
/* FUNCTIONS *****************************************************************/
@@ -162,21 +168,54 @@ ScmEncryptPassword(
_Out_ PBYTE *pEncryptedPassword,
_Out_ PDWORD pEncryptedPasswordSize)
{
- DWORD dwSize;
+ struct ustring inData, keyData, outData;
+ PCHAR pszKey = "TestEncryptionKey";
PBYTE pBuffer;
+ NTSTATUS Status;
+
+ inData.Length = (wcslen(pClearTextPassword) + 1) * sizeof(WCHAR);
+ inData.MaximumLength = inData.Length;
+ inData.Buffer = (unsigned char *)pClearTextPassword;
+
+ keyData.Length = strlen(pszKey);
+ keyData.MaximumLength = keyData.Length;
+ keyData.Buffer = (unsigned char *)pszKey;
- dwSize = (wcslen(pClearTextPassword) + 1) * sizeof(WCHAR);
+ outData.Length = 0;
+ outData.MaximumLength = 0;
+ outData.Buffer = NULL;
- pBuffer = HeapAlloc(GetProcessHeap(), 0, dwSize);
+ /* Get the required buffer size */
+ Status = SystemFunction004(&inData,
+ &keyData,
+ &outData);
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ ERR("SystemFunction004 failed (Status 0x%08lx)\n", Status);
+ return RtlNtStatusToDosError(Status);
+ }
+
+ /* Allocate a buffer for the encrypted password */
+ pBuffer = HeapAlloc(GetProcessHeap(), 0, outData.Length);
if (pBuffer == NULL)
return ERROR_OUTOFMEMORY;
- CopyMemory(pBuffer,
- pClearTextPassword,
- dwSize);
+ outData.MaximumLength = outData.Length;
+ outData.Buffer = pBuffer;
+
+ /* Encrypt the password */
+ Status = SystemFunction004(&inData,
+ &keyData,
+ &outData);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("SystemFunction004 failed (Status 0x%08lx)\n", Status);
+ HeapFree(GetProcessHeap(), 0, pBuffer);
+ return RtlNtStatusToDosError(Status);
+ }
- *pEncryptedPassword = pBuffer;
- *pEncryptedPasswordSize = dwSize;
+ *pEncryptedPassword = outData.Buffer;
+ *pEncryptedPasswordSize = outData.Length;
return ERROR_SUCCESS;
}
@@ -395,12 +434,12 @@ done:
if (lpPasswordW != NULL)
{
/* Wipe and release the password buffers */
- ZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * sizeof(WCHAR));
+ SecureZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * sizeof(WCHAR));
HeapFree(GetProcessHeap(), 0, lpPasswordW);
if (lpEncryptedPassword != NULL)
{
- ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+ SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
}
}
@@ -498,7 +537,7 @@ done:
if (lpEncryptedPassword != NULL)
{
/* Wipe and release the password buffer */
- ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+ SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
}
@@ -723,12 +762,12 @@ done:
if (lpPasswordW != NULL)
{
/* Wipe and release the password buffers */
- ZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * sizeof(WCHAR));
+ SecureZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * sizeof(WCHAR));
HeapFree(GetProcessHeap(), 0, lpPasswordW);
if (lpEncryptedPassword != NULL)
{
- ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+ SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
}
}
@@ -837,7 +876,7 @@ done:
if (lpEncryptedPassword != NULL)
{
/* Wipe and release the password buffers */
- ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+ SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
}