[ADVAPI32][SERVICES] Pass encrypted passwords to the service manager.
authorEric Kohl <eric.kohl@reactos.org>
Tue, 18 Sep 2018 19:33:29 +0000 (21:33 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Tue, 18 Sep 2018 19:33:29 +0000 (21:33 +0200)
- 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
dll/win32/advapi32/service/scm.c

index 14af8e5..4d1f247 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
 #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 *****************************************************************/
 
 
 /* FUNCTIONS *****************************************************************/
 
@@ -684,17 +698,51 @@ ScmDecryptPassword(
     _In_ DWORD dwPasswordSize,
     _Out_ PWSTR *pClearTextPassword)
 {
     _In_ DWORD dwPasswordSize,
     _Out_ PWSTR *pClearTextPassword)
 {
+    struct ustring inData, keyData, outData;
+    PCHAR pszKey = "TestEncryptionKey";
     PWSTR pBuffer;
     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;
 
     if (pBuffer == NULL)
         return ERROR_OUTOFMEMORY;
 
+    outData.MaximumLength = outData.Length;
+    outData.Buffer = (unsigned char *)pBuffer;
+
     /* Decrypt the password */
     /* 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;
 
 
     *pClearTextPassword = pBuffer;
 
index 022864b..efa19f2 100644 (file)
 #include <advapi32.h>
 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 
 #include <advapi32.h>
 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
 
+NTSTATUS
+WINAPI
+SystemFunction004(
+    const struct ustring *in,
+    const struct ustring *key,
+    struct ustring *out);
 
 /* FUNCTIONS *****************************************************************/
 
 
 /* FUNCTIONS *****************************************************************/
 
@@ -162,21 +168,54 @@ ScmEncryptPassword(
     _Out_ PBYTE *pEncryptedPassword,
     _Out_ PDWORD pEncryptedPasswordSize)
 {
     _Out_ PBYTE *pEncryptedPassword,
     _Out_ PDWORD pEncryptedPasswordSize)
 {
-    DWORD dwSize;
+    struct ustring inData, keyData, outData;
+    PCHAR pszKey = "TestEncryptionKey";
     PBYTE pBuffer;
     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;
 
     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;
 }
 
     return ERROR_SUCCESS;
 }
@@ -395,12 +434,12 @@ done:
     if (lpPasswordW != NULL)
     {
         /* Wipe and release the password buffers */
     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)
         {
         HeapFree(GetProcessHeap(), 0, lpPasswordW);
 
         if (lpEncryptedPassword != NULL)
         {
-            ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+            SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
             HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
         }
     }
             HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
         }
     }
@@ -498,7 +537,7 @@ done:
     if (lpEncryptedPassword != NULL)
     {
         /* Wipe and release the password buffer */
     if (lpEncryptedPassword != NULL)
     {
         /* Wipe and release the password buffer */
-        ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+        SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
         HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
     }
 
         HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
     }
 
@@ -723,12 +762,12 @@ done:
     if (lpPasswordW != NULL)
     {
         /* Wipe and release the password buffers */
     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)
         {
         HeapFree(GetProcessHeap(), 0, lpPasswordW);
 
         if (lpEncryptedPassword != NULL)
         {
-            ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+            SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
             HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
         }
     }
             HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
         }
     }
@@ -837,7 +876,7 @@ done:
     if (lpEncryptedPassword != NULL)
     {
         /* Wipe and release the password buffers */
     if (lpEncryptedPassword != NULL)
     {
         /* Wipe and release the password buffers */
-        ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+        SecureZeroMemory(lpEncryptedPassword, dwPasswordSize);
         HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
     }
 
         HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
     }