https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e5fcda922b0ad049f22815...
commit e5fcda922b0ad049f22815a6ea1258205fa17927 Author: Eric Kohl eric.kohl@reactos.org AuthorDate: Tue Sep 18 21:33:29 2018 +0200 Commit: Eric Kohl eric.kohl@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); }