https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5e2c4657ca10dea1154cb…
commit 5e2c4657ca10dea1154cb43f16ee6962999ac7a4
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Mon Sep 17 16:34:48 2018 +0200
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Mon Sep 17 16:34:48 2018 +0200
[ADVAPI32][SERVICES] Add (dummy) password encryption/decryption functions to
CreateServiceA/W and ChangeServiceConfigA/W in order to prepare to pass encrypted
passwords to the service manager
---
base/system/services/config.c | 24 ++++++++
base/system/services/rpcserver.c | 49 ++++++++++++++--
base/system/services/services.h | 7 +++
dll/win32/advapi32/service/scm.c | 123 ++++++++++++++++++++++++++++++++-------
4 files changed, 177 insertions(+), 26 deletions(-)
diff --git a/base/system/services/config.c b/base/system/services/config.c
index 2099d64214..14af8e5b0f 100644
--- a/base/system/services/config.c
+++ b/base/system/services/config.c
@@ -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 */
diff --git a/base/system/services/rpcserver.c b/base/system/services/rpcserver.c
index aa64233350..454181bb66 100644
--- a/base/system/services/rpcserver.c
+++ b/base/system/services/rpcserver.c
@@ -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);
diff --git a/base/system/services/services.h b/base/system/services/services.h
index b455bead0f..ce1b46eafa 100644
--- a/base/system/services/services.h
+++ b/base/system/services/services.h
@@ -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);
diff --git a/dll/win32/advapi32/service/scm.c b/dll/win32/advapi32/service/scm.c
index 92661c9581..022864bba9 100644
--- a/dll/win32/advapi32/service/scm.c
+++ b/dll/win32/advapi32/service/scm.c
@@ -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)
{