[ADVAPI32][SERVICES] Add (dummy) password encryption/decryption functions to CreateSe...
authorEric Kohl <eric.kohl@reactos.org>
Mon, 17 Sep 2018 14:34:48 +0000 (16:34 +0200)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 17 Sep 2018 14:34:48 +0000 (16:34 +0200)
base/system/services/config.c
base/system/services/rpcserver.c
base/system/services/services.h
dll/win32/advapi32/service/scm.c

index 2099d64..14af8e5 100644 (file)
@@ -677,4 +677,28 @@ done:
     return dwError;
 }
 
+
+DWORD
+ScmDecryptPassword(
+    _In_ PBYTE pPassword,
+    _In_ DWORD dwPasswordSize,
+    _Out_ PWSTR *pClearTextPassword)
+{
+    PWSTR pBuffer;
+
+    /* Allocate a buffer for the decrypted password */
+    pBuffer = HeapAlloc(GetProcessHeap(), 0, dwPasswordSize);
+    if (pBuffer == NULL)
+        return ERROR_OUTOFMEMORY;
+
+    /* Decrypt the password */
+    CopyMemory(pBuffer,
+               pPassword,
+               dwPasswordSize);
+
+    *pClearTextPassword = pBuffer;
+
+    return ERROR_SUCCESS;
+}
+
 /* EOF */
index aa64233..454181b 100644 (file)
@@ -1934,6 +1934,7 @@ RChangeServiceConfigW(
     HKEY hServiceKey = NULL;
     LPWSTR lpDisplayNameW = NULL;
     LPWSTR lpImagePathW = NULL;
+    LPWSTR lpClearTextPassword = NULL;
 
     DPRINT("RChangeServiceConfigW() called\n");
     DPRINT("dwServiceType = 0x%lx\n", dwServiceType);
@@ -1941,6 +1942,9 @@ RChangeServiceConfigW(
     DPRINT("dwErrorControl = %lu\n", dwErrorControl);
     DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName);
     DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
+    DPRINT("lpServiceStartName = %S\n", lpServiceStartName);
+    DPRINT("lpPassword = %p\n", lpPassword);
+    DPRINT("dwPwSite = %lu\n", dwPwSize);
     DPRINT("lpDisplayName = %S\n", lpDisplayName);
 
     if (ScmShutdown)
@@ -2199,13 +2203,25 @@ RChangeServiceConfigW(
         {
             if (*(LPWSTR)lpPassword != 0)
             {
-                /* FIXME: Decrypt the password */
+                /* Decrypt the password */
+                dwError = ScmDecryptPassword(lpPassword,
+                                             dwPwSize,
+                                             &lpClearTextPassword);
+                if (dwError != ERROR_SUCCESS)
+                {
+                    DPRINT1("ScmDecryptPassword failed (Error %lu)\n", dwError);
+                    goto done;
+                }
+                DPRINT1("Clear text password: %S\n", lpClearTextPassword);
 
                 /* Write the password */
                 dwError = ScmSetServicePassword(lpService->szServiceName,
-                                                (LPCWSTR)lpPassword);
+                                                lpClearTextPassword);
                 if (dwError != ERROR_SUCCESS)
+                {
+                    DPRINT1("ScmSetServicePassword failed (Error %lu)\n", dwError);
                     goto done;
+                }
             }
             else
             {
@@ -2216,12 +2232,23 @@ RChangeServiceConfigW(
                     dwError = ERROR_SUCCESS;
 
                 if (dwError != ERROR_SUCCESS)
+                {
+                    DPRINT1("ScmSetServicePassword failed (Error %lu)\n", dwError);
                     goto done;
+                }
             }
         }
     }
 
 done:
+    if (lpClearTextPassword != NULL)
+    {
+        /* Wipe and release the password buffer */
+        ZeroMemory(lpClearTextPassword,
+                   (wcslen(lpClearTextPassword) + 1) * sizeof(WCHAR));
+        HeapFree(GetProcessHeap(), 0, lpClearTextPassword);
+    }
+
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
@@ -2260,6 +2287,7 @@ RCreateServiceW(
     PSERVICE lpService = NULL;
     SC_HANDLE hServiceHandle = NULL;
     LPWSTR lpImagePath = NULL;
+    LPWSTR lpClearTextPassword = NULL;
     HKEY hServiceKey = NULL;
     LPWSTR lpObjectName;
 
@@ -2576,11 +2604,16 @@ RCreateServiceW(
 
         if (lpPassword != NULL && *(LPWSTR)lpPassword != 0)
         {
-            /* FIXME: Decrypt the password */
+            /* Decrypt the password */
+            dwError = ScmDecryptPassword(lpPassword,
+                                         dwPwSize,
+                                         &lpClearTextPassword);
+            if (dwError != ERROR_SUCCESS)
+                goto done;
 
             /* Write the password */
             dwError = ScmSetServicePassword(lpServiceName,
-                                            (LPCWSTR)lpPassword);
+                                            lpClearTextPassword);
             if (dwError != ERROR_SUCCESS)
                 goto done;
         }
@@ -2612,6 +2645,14 @@ done:
     if (hServiceKey != NULL)
         RegCloseKey(hServiceKey);
 
+    if (lpClearTextPassword != NULL)
+    {
+        /* Wipe and release the password buffer */
+        ZeroMemory(lpClearTextPassword,
+                   (wcslen(lpClearTextPassword) + 1) * sizeof(WCHAR));
+        HeapFree(GetProcessHeap(), 0, lpClearTextPassword);
+    }
+
     if (dwError == ERROR_SUCCESS)
     {
         DPRINT("hService %p\n", hServiceHandle);
index b455bea..ce1b46e 100644 (file)
@@ -150,6 +150,13 @@ ScmDeleteRegKey(
     _In_ HKEY hKey,
     _In_ PCWSTR pszSubKey);
 
+DWORD
+ScmDecryptPassword(
+    _In_ PBYTE pPassword,
+    _In_ DWORD dwPasswordSize,
+    _Out_ PWSTR *pDecryptedPassword);
+
+
 /* controlset.c */
 
 BOOL ScmGetControlSetValues(VOID);
index 92661c9..022864b 100644 (file)
@@ -155,6 +155,33 @@ ScmRpcStatusToWinError(RPC_STATUS Status)
 }
 
 
+static
+DWORD
+ScmEncryptPassword(
+    _In_ PCWSTR pClearTextPassword,
+    _Out_ PBYTE *pEncryptedPassword,
+    _Out_ PDWORD pEncryptedPasswordSize)
+{
+    DWORD dwSize;
+    PBYTE pBuffer;
+
+    dwSize = (wcslen(pClearTextPassword) + 1) * sizeof(WCHAR);
+
+    pBuffer = HeapAlloc(GetProcessHeap(), 0, dwSize);
+    if (pBuffer == NULL)
+        return ERROR_OUTOFMEMORY;
+
+    CopyMemory(pBuffer,
+               pClearTextPassword,
+               dwSize);
+
+    *pEncryptedPassword = pBuffer;
+    *pEncryptedPasswordSize = dwSize;
+
+    return ERROR_SUCCESS;
+}
+
+
 /**********************************************************************
  *  ChangeServiceConfig2A
  *
@@ -293,12 +320,12 @@ ChangeServiceConfigA(SC_HANDLE hService,
     DWORD dwDependenciesLength = 0;
     SIZE_T cchLength;
     LPCSTR lpStr;
-    DWORD dwPasswordLength = 0;
+    DWORD dwPasswordSize = 0;
     LPWSTR lpPasswordW = NULL;
     LPBYTE lpEncryptedPassword = NULL;
 
     TRACE("ChangeServiceConfigA(%p %lu %lu %lu %s %s %p %s %s %s %s)\n",
-          dwServiceType, dwStartType, dwErrorControl, debugstr_a(lpBinaryPathName),
+          hService, dwServiceType, dwStartType, dwErrorControl, debugstr_a(lpBinaryPathName),
           debugstr_a(lpLoadOrderGroup), lpdwTagId, debugstr_a(lpDependencies),
           debugstr_a(lpServiceStartName), debugstr_a(lpPassword), debugstr_a(lpDisplayName));
 
@@ -334,9 +361,12 @@ ChangeServiceConfigA(SC_HANDLE hService,
                             lpPasswordW,
                             (int)(strlen(lpPassword) + 1));
 
-        /* FIXME: Encrypt the password */
-        lpEncryptedPassword = (LPBYTE)lpPasswordW;
-        dwPasswordLength = (wcslen(lpPasswordW) + 1) * sizeof(WCHAR);
+        /* Encrypt the unicode password */
+        dwError = ScmEncryptPassword(lpPasswordW,
+                                     &lpEncryptedPassword,
+                                     &dwPasswordSize);
+        if (dwError != ERROR_SUCCESS)
+            goto done;
     }
 
     RpcTryExcept
@@ -352,7 +382,7 @@ ChangeServiceConfigA(SC_HANDLE hService,
                                         dwDependenciesLength,
                                         (LPSTR)lpServiceStartName,
                                         lpEncryptedPassword,
-                                        dwPasswordLength,
+                                        dwPasswordSize,
                                         (LPSTR)lpDisplayName);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -361,9 +391,20 @@ ChangeServiceConfigA(SC_HANDLE hService,
     }
     RpcEndExcept;
 
+done:
     if (lpPasswordW != NULL)
+    {
+        /* Wipe and release the password buffers */
+        ZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * sizeof(WCHAR));
         HeapFree(GetProcessHeap(), 0, lpPasswordW);
 
+        if (lpEncryptedPassword != NULL)
+        {
+            ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+            HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
+        }
+    }
+
     if (dwError != ERROR_SUCCESS)
     {
         TRACE("RChangeServiceConfigA() failed (Error %lu)\n", dwError);
@@ -397,11 +438,11 @@ ChangeServiceConfigW(SC_HANDLE hService,
     DWORD dwDependenciesLength = 0;
     SIZE_T cchLength;
     LPCWSTR lpStr;
-    DWORD dwPasswordLength = 0;
+    DWORD dwPasswordSize = 0;
     LPBYTE lpEncryptedPassword = NULL;
 
     TRACE("ChangeServiceConfigW(%p %lu %lu %lu %s %s %p %s %s %s %s)\n",
-          dwServiceType, dwStartType, dwErrorControl, debugstr_w(lpBinaryPathName),
+          hService, dwServiceType, dwStartType, dwErrorControl, debugstr_w(lpBinaryPathName),
           debugstr_w(lpLoadOrderGroup), lpdwTagId, debugstr_w(lpDependencies),
           debugstr_w(lpServiceStartName), debugstr_w(lpPassword), debugstr_w(lpDisplayName));
 
@@ -421,9 +462,14 @@ ChangeServiceConfigW(SC_HANDLE hService,
 
     if (lpPassword != NULL)
     {
-        /* FIXME: Encrypt the password */
-        lpEncryptedPassword = (LPBYTE)lpPassword;
-        dwPasswordLength = (wcslen(lpPassword) + 1) * sizeof(WCHAR);
+        dwError = ScmEncryptPassword(lpPassword,
+                                     &lpEncryptedPassword,
+                                     &dwPasswordSize);
+        if (dwError != ERROR_SUCCESS)
+        {
+            ERR("ScmEncryptPassword failed (Error %lu)\n", dwError);
+            goto done;
+        }
     }
 
     RpcTryExcept
@@ -439,7 +485,7 @@ ChangeServiceConfigW(SC_HANDLE hService,
                                         dwDependenciesLength,
                                         (LPWSTR)lpServiceStartName,
                                         lpEncryptedPassword,
-                                        dwPasswordLength,
+                                        dwPasswordSize,
                                         (LPWSTR)lpDisplayName);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -448,6 +494,14 @@ ChangeServiceConfigW(SC_HANDLE hService,
     }
     RpcEndExcept;
 
+done:
+    if (lpEncryptedPassword != NULL)
+    {
+        /* Wipe and release the password buffer */
+        ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+        HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
+    }
+
     if (dwError != ERROR_SUCCESS)
     {
         TRACE("RChangeServiceConfigW() failed (Error %lu)\n", dwError);
@@ -584,7 +638,7 @@ CreateServiceA(SC_HANDLE hSCManager,
     DWORD dwError;
     SIZE_T cchLength;
     LPCSTR lpStr;
-    DWORD dwPasswordLength = 0;
+    DWORD dwPasswordSize = 0;
     LPWSTR lpPasswordW = NULL;
     LPBYTE lpEncryptedPassword = NULL;
 
@@ -632,9 +686,12 @@ CreateServiceA(SC_HANDLE hSCManager,
                             lpPasswordW,
                             (int)(strlen(lpPassword) + 1));
 
-        /* FIXME: Encrypt the password */
-        lpEncryptedPassword = (LPBYTE)lpPasswordW;
-        dwPasswordLength = (wcslen(lpPasswordW) + 1) * sizeof(WCHAR);
+        /* Encrypt the password */
+        dwError = ScmEncryptPassword(lpPasswordW,
+                                     &lpEncryptedPassword,
+                                     &dwPasswordSize);
+        if (dwError != ERROR_SUCCESS)
+            goto done;
     }
 
     RpcTryExcept
@@ -653,7 +710,7 @@ CreateServiceA(SC_HANDLE hSCManager,
                                   dwDependenciesLength,
                                   (LPSTR)lpServiceStartName,
                                   lpEncryptedPassword,
-                                  dwPasswordLength,
+                                  dwPasswordSize,
                                   (SC_RPC_HANDLE *)&hService);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -662,9 +719,20 @@ CreateServiceA(SC_HANDLE hSCManager,
     }
     RpcEndExcept;
 
+done:
     if (lpPasswordW != NULL)
+    {
+        /* Wipe and release the password buffers */
+        ZeroMemory(lpPasswordW, (wcslen(lpPasswordW) + 1) * sizeof(WCHAR));
         HeapFree(GetProcessHeap(), 0, lpPasswordW);
 
+        if (lpEncryptedPassword != NULL)
+        {
+            ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+            HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
+        }
+    }
+
     SetLastError(dwError);
     if (dwError != ERROR_SUCCESS)
     {
@@ -701,7 +769,7 @@ CreateServiceW(SC_HANDLE hSCManager,
     DWORD dwError;
     SIZE_T cchLength;
     LPCWSTR lpStr;
-    DWORD dwPasswordLength = 0;
+    DWORD dwPasswordSize = 0;
     LPBYTE lpEncryptedPassword = NULL;
 
     TRACE("CreateServiceW(%p %s %s %lx %lu %lu %lu %s %s %p %s %s %s)\n",
@@ -732,9 +800,12 @@ CreateServiceW(SC_HANDLE hSCManager,
 
     if (lpPassword != NULL)
     {
-        /* FIXME: Encrypt the password */
-        lpEncryptedPassword = (LPBYTE)lpPassword;
-        dwPasswordLength = (wcslen(lpPassword) + 1) * sizeof(WCHAR);
+        /* Encrypt the password */
+        dwError = ScmEncryptPassword(lpPassword,
+                                     &lpEncryptedPassword,
+                                     &dwPasswordSize);
+        if (dwError != ERROR_SUCCESS)
+            goto done;
     }
 
     RpcTryExcept
@@ -753,7 +824,7 @@ CreateServiceW(SC_HANDLE hSCManager,
                                   dwDependenciesLength,
                                   lpServiceStartName,
                                   lpEncryptedPassword,
-                                  dwPasswordLength,
+                                  dwPasswordSize,
                                   (SC_RPC_HANDLE *)&hService);
     }
     RpcExcept(EXCEPTION_EXECUTE_HANDLER)
@@ -762,6 +833,14 @@ CreateServiceW(SC_HANDLE hSCManager,
     }
     RpcEndExcept;
 
+done:
+    if (lpEncryptedPassword != NULL)
+    {
+        /* Wipe and release the password buffers */
+        ZeroMemory(lpEncryptedPassword, dwPasswordSize);
+        HeapFree(GetProcessHeap(), 0, lpEncryptedPassword);
+    }
+
     SetLastError(dwError);
     if (dwError != ERROR_SUCCESS)
     {