void CWE319_Cleartext_Tx_Sensitive_Info__w32_wchar_t_connect_socket_09_bad() { wchar_t * password; wchar_t passwordBuffer[100] = L""; password = passwordBuffer; if(GLOBAL_CONST_TRUE) { { WSADATA wsaData; int wsaDataInit = 0; int recvResult; struct sockaddr_in service; wchar_t *replace; SOCKET connectSocket = INVALID_SOCKET; size_t passwordLen = wcslen(password); do { if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { break; } wsaDataInit = 1; connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (connectSocket == INVALID_SOCKET) { break; } memset(&service, 0, sizeof(service)); service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr(IP_ADDRESS); service.sin_port = htons(TCP_PORT); if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) { break; } /* Abort on error or the connection was closed, make sure to recv one * less char than is in the recv_buf in order to append a terminator */ /* POTENTIAL FLAW: Reading sensitive data from the network */ recvResult = recv(connectSocket, (char*)(password + passwordLen), (100 - passwordLen - 1) * sizeof(wchar_t), 0); if (recvResult == SOCKET_ERROR || recvResult == 0) { break; } /* Append null terminator */ password[passwordLen + recvResult / sizeof(wchar_t)] = L'\0'; /* Eliminate CRLF */ replace = wcschr(password, L'\r'); if (replace) { *replace = L'\0'; } replace = wcschr(password, L'\n'); if (replace) { *replace = L'\0'; } } while (0); if (connectSocket != INVALID_SOCKET) { closesocket(connectSocket); } if (wsaDataInit) { WSACleanup(); } } } if(GLOBAL_CONST_TRUE) { { HANDLE pHandle; wchar_t * username = L"User"; wchar_t * domain = L"Domain"; /* Use the password in LogonUser() to establish that it is "sensitive" */ /* POTENTIAL FLAW: Using sensitive information that was possibly sent in plaintext over the network */ if (LogonUserW( username, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } } }
/* goodB2G2() - use badsource and goodsink by reversing the blocks in the if in the sink function */ static void goodB2G2Sink(wchar_t * password) { if(goodB2G2Static) { { HCRYPTPROV hCryptProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; char hashData[100] = HASH_INPUT; HANDLE pHandle; wchar_t * username = L"User"; wchar_t * domain = L"Domain"; do { BYTE payload[(100 - 1) * sizeof(wchar_t)]; /* same size as password except for NUL terminator */ DWORD payloadBytes; /* Hex-decode the input string into raw bytes */ payloadBytes = decodeHexWChars(payload, sizeof(payload), password); /* Wipe the hex string, to prevent it from being given to LogonUserW if * any of the crypto calls fail. */ SecureZeroMemory(password, 100 * sizeof(wchar_t)); /* Aquire a Context */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) { break; } /* Create hash handle */ if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) { break; } /* Hash the input string */ if(!CryptHashData(hHash, (BYTE*)hashData, strlen(hashData), 0)) { break; } /* Derive an AES key from the hash */ if(!CryptDeriveKey(hCryptProv, CALG_AES_256, hHash, 0, &hKey)) { break; } /* FIX: Decrypt the password */ if(!CryptDecrypt(hKey, 0, 1, 0, payload, &payloadBytes)) { break; } /* Copy back into password and NUL-terminate */ memcpy(password, payload, payloadBytes); password[payloadBytes / sizeof(wchar_t)] = L'\0'; } while (0); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } /* Use the password in LogonUser() to establish that it is "sensitive" */ if (LogonUserW( username, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } } }
DWORD WINAPI InstallReactOS(HINSTANCE hInstance) { TCHAR szBuffer[MAX_PATH]; HANDLE token; TOKEN_PRIVILEGES privs; HKEY hKey; HINF hShortcutsInf; InitializeSetupActionLog(FALSE); LogItem(SYSSETUP_SEVERITY_INFORMATION, L"Installing ReactOS"); if (!InitializeProfiles()) { FatalError("InitializeProfiles() failed"); return 0; } CreateTempDir(L"TEMP"); CreateTempDir(L"TMP"); if (GetWindowsDirectory(szBuffer, sizeof(szBuffer) / sizeof(TCHAR))) { if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_WRITE, &hKey) == ERROR_SUCCESS) { RegSetValueExW(hKey, L"PathName", 0, REG_SZ, (LPBYTE)szBuffer, (wcslen(szBuffer) + 1) * sizeof(WCHAR)); RegSetValueExW(hKey, L"SystemRoot", 0, REG_SZ, (LPBYTE)szBuffer, (wcslen(szBuffer) + 1) * sizeof(WCHAR)); RegCloseKey(hKey); } PathAddBackslash(szBuffer); _tcscat(szBuffer, _T("system")); CreateDirectory(szBuffer, NULL); } if (!CommonInstall()) return 0; InstallWizard(); InstallSecurity(); SetAutoAdminLogon(); hShortcutsInf = SetupOpenInfFileW(L"shortcuts.inf", NULL, INF_STYLE_WIN4, NULL); if (hShortcutsInf == INVALID_HANDLE_VALUE) { FatalError("Failed to open shortcuts.inf"); return 0; } if (!CreateShortcuts(hShortcutsInf, L"ShortcutFolders")) { FatalError("CreateShortcuts() failed"); return 0; } SetupCloseInfFile(hShortcutsInf); /* ROS HACK, as long as NtUnloadKey is not implemented */ { NTSTATUS Status = NtUnloadKey(NULL); if (Status == STATUS_NOT_IMPLEMENTED) { /* Create the Administrator profile */ PROFILEINFOW ProfileInfo; HANDLE hToken; BOOL ret; ret = LogonUserW(AdminInfo.Name, AdminInfo.Domain, AdminInfo.Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken); if (!ret) { FatalError("LogonUserW() failed!"); return 0; } ZeroMemory(&ProfileInfo, sizeof(PROFILEINFOW)); ProfileInfo.dwSize = sizeof(PROFILEINFOW); ProfileInfo.lpUserName = L"Administrator"; ProfileInfo.dwFlags = PI_NOUI; LoadUserProfileW(hToken, &ProfileInfo); CloseHandle(hToken); } else { DPRINT1("ROS HACK not needed anymore. Please remove it\n"); } } /* END OF ROS HACK */ SetupCloseInfFile(hSysSetupInf); SetSetupType(0); LogItem(SYSSETUP_SEVERITY_INFORMATION, L"Installing ReactOS done"); TerminateSetupActionLog(); if (AdminInfo.Name != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo.Name); if (AdminInfo.Domain != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo.Domain); if (AdminInfo.Password != NULL) RtlFreeHeap(RtlGetProcessHeap(), 0, AdminInfo.Password); /* Get shutdown privilege */ if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &token)) { FatalError("OpenProcessToken() failed!"); return 0; } if (!LookupPrivilegeValue( NULL, SE_SHUTDOWN_NAME, &privs.Privileges[0].Luid)) { FatalError("LookupPrivilegeValue() failed!"); return 0; } privs.PrivilegeCount = 1; privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if (AdjustTokenPrivileges( token, FALSE, &privs, 0, (PTOKEN_PRIVILEGES)NULL, NULL) == 0) { FatalError("AdjustTokenPrivileges() failed!"); return 0; } ExitWindowsEx(EWX_REBOOT, 0); return 0; }
/* goodB2G2() - use badsource and goodsink by reversing the blocks in the second if */ static void goodB2G2() { wchar_t * password; wchar_t passwordBuffer[100] = L""; password = passwordBuffer; if(GLOBAL_CONST_TRUE) { { WSADATA wsaData; int wsaDataInit = 0; int recvResult; struct sockaddr_in service; wchar_t *replace; SOCKET connectSocket = INVALID_SOCKET; size_t passwordLen = wcslen(password); do { if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { break; } wsaDataInit = 1; connectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (connectSocket == INVALID_SOCKET) { break; } memset(&service, 0, sizeof(service)); service.sin_family = AF_INET; service.sin_addr.s_addr = inet_addr(IP_ADDRESS); service.sin_port = htons(TCP_PORT); if (connect(connectSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) { break; } /* Abort on error or the connection was closed, make sure to recv one * less char than is in the recv_buf in order to append a terminator */ /* POTENTIAL FLAW: Reading sensitive data from the network */ recvResult = recv(connectSocket, (char*)(password + passwordLen), (100 - passwordLen - 1) * sizeof(wchar_t), 0); if (recvResult == SOCKET_ERROR || recvResult == 0) { break; } /* Append null terminator */ password[passwordLen + recvResult / sizeof(wchar_t)] = L'\0'; /* Eliminate CRLF */ replace = wcschr(password, L'\r'); if (replace) { *replace = L'\0'; } replace = wcschr(password, L'\n'); if (replace) { *replace = L'\0'; } } while (0); if (connectSocket != INVALID_SOCKET) { closesocket(connectSocket); } if (wsaDataInit) { WSACleanup(); } } } if(GLOBAL_CONST_TRUE) { { HCRYPTPROV hCryptProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; char hashData[100] = HASH_INPUT; HANDLE pHandle; wchar_t * username = L"User"; wchar_t * domain = L"Domain"; do { BYTE payload[(100 - 1) * sizeof(wchar_t)]; /* same size as password except for NUL terminator */ DWORD payloadBytes; /* Hex-decode the input string into raw bytes */ payloadBytes = decodeHexWChars(payload, sizeof(payload), password); /* Wipe the hex string, to prevent it from being given to LogonUserW if * any of the crypto calls fail. */ SecureZeroMemory(password, 100 * sizeof(wchar_t)); /* Aquire a Context */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) { break; } /* Create hash handle */ if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) { break; } /* Hash the input string */ if(!CryptHashData(hHash, (BYTE*)hashData, strlen(hashData), 0)) { break; } /* Derive an AES key from the hash */ if(!CryptDeriveKey(hCryptProv, CALG_AES_256, hHash, 0, &hKey)) { break; } /* FIX: Decrypt the password */ if(!CryptDecrypt(hKey, 0, 1, 0, payload, &payloadBytes)) { break; } /* Copy back into password and NUL-terminate */ memcpy(password, payload, payloadBytes); password[payloadBytes / sizeof(wchar_t)] = L'\0'; } while (0); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } /* Use the password in LogonUser() to establish that it is "sensitive" */ if (LogonUserW( username, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } } }
/* goodB2G() - use badsource and goodsink by reversing the blocks on the second goto statement */ static void goodB2G() { wchar_t * data; wchar_t dataBuffer[100] = L""; data = dataBuffer; goto source; source: { FILE *pFile; pFile = fopen("passwords.txt", "r"); if (pFile != NULL) { /* POTENTIAL FLAW: Read the password from a file */ if (fgetws(data, 100, pFile) == NULL) { data[0] = L'\0'; } fclose(pFile); } else { data[0] = L'\0'; } } goto sink; sink: { HANDLE pHandle; wchar_t * username = L"User"; wchar_t * domain = L"Domain"; char hashData[100] = HASH_INPUT; HCRYPTPROV hCryptProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; do { BYTE payload[(100 - 1) * sizeof(wchar_t)]; /* same size as data except for NUL terminator */ DWORD payloadBytes; /* Hex-decode the input string into raw bytes */ payloadBytes = decodeHexWChars(payload, sizeof(payload), data); /* Wipe the hex string, to prevent it from being given to LogonUserW if * any of the crypto calls fail. */ SecureZeroMemory(data, 100 * sizeof(wchar_t)); /* Aquire a Context */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) { break; } /* Create hash handle */ if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) { break; } /* Hash the input string */ if(!CryptHashData(hHash, (BYTE*)hashData, strlen(hashData), 0)) { break; } /* Derive an AES key from the hash */ if(!CryptDeriveKey(hCryptProv, CALG_AES_256, hHash, 0, &hKey)) { break; } if(!CryptDecrypt(hKey, 0, 1, 0, payload, &payloadBytes)) { break; } /* Copy back into data and NUL-terminate */ memcpy(data, payload, payloadBytes); data[payloadBytes / sizeof(wchar_t)] = L'\0'; } while (0); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } /* FIX: Decrypt the password before using it for authentication */ if (LogonUserW( username, domain, data, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } }
/* goodG2B() - use goodsource and badsink by changing the first "if" so that both branches use the GoodSource and the second "if" so that both branches use the BadSink */ static void goodG2B() { wchar_t * password; wchar_t passwordBuffer[100] = L""; password = passwordBuffer; if(globalReturnsTrueOrFalse()) { /* FIX: Use a hardcoded password (it was not sent over the network) * INCIDENTAL FLAW: CWE-259 Hard Coded Password */ wcscpy(password, L"Password1234!"); } else { /* FIX: Use a hardcoded password (it was not sent over the network) * INCIDENTAL FLAW: CWE-259 Hard Coded Password */ wcscpy(password, L"Password1234!"); } if(globalReturnsTrueOrFalse()) { { HANDLE pHandle; wchar_t * username = L"User"; wchar_t * domain = L"Domain"; /* Use the password in LogonUser() to establish that it is "sensitive" */ /* POTENTIAL FLAW: Using sensitive information that was possibly sent in plaintext over the network */ if (LogonUserW( username, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } } else { { HANDLE pHandle; wchar_t * username = L"User"; wchar_t * domain = L"Domain"; /* Use the password in LogonUser() to establish that it is "sensitive" */ /* POTENTIAL FLAW: Using sensitive information that was possibly sent in plaintext over the network */ if (LogonUserW( username, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } } }
void CWE319_Cleartext_Tx_Sensitive_Info__w32_wchar_t_listen_socket_12_bad() { wchar_t * password; wchar_t passwordBuffer[100] = L""; password = passwordBuffer; if(globalReturnsTrueOrFalse()) { { WSADATA wsaData; int wsaDataInit = 0; int recvResult; struct sockaddr_in service; wchar_t *replace; SOCKET listenSocket = INVALID_SOCKET; SOCKET acceptSocket = INVALID_SOCKET; size_t passwordLen = wcslen(password); do { if (WSAStartup(MAKEWORD(2,2), &wsaData) != NO_ERROR) { break; } wsaDataInit = 1; listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (listenSocket == INVALID_SOCKET) { break; } memset(&service, 0, sizeof(service)); service.sin_family = AF_INET; service.sin_addr.s_addr = INADDR_ANY; service.sin_port = htons(TCP_PORT); if (bind(listenSocket, (struct sockaddr*)&service, sizeof(service)) == SOCKET_ERROR) { break; } if (listen(listenSocket, LISTEN_BACKLOG) == SOCKET_ERROR) { break; } acceptSocket = accept(listenSocket, NULL, NULL); if (acceptSocket == SOCKET_ERROR) { break; } /* Abort on error or the connection was closed */ /* POTENTIAL FLAW: Reading sensitive data from the network */ recvResult = recv(acceptSocket, (char*)(password + passwordLen), (100 - passwordLen - 1) * sizeof(wchar_t), 0); if (recvResult == SOCKET_ERROR || recvResult == 0) { break; } /* Append null terminator */ password[passwordLen + recvResult / sizeof(wchar_t)] = L'\0'; /* Eliminate CRLF */ replace = wcschr(password, L'\r'); if (replace) { *replace = L'\0'; } replace = wcschr(password, L'\n'); if (replace) { *replace = L'\0'; } } while (0); if (listenSocket != INVALID_SOCKET) { closesocket(listenSocket); } if (acceptSocket != INVALID_SOCKET) { closesocket(acceptSocket); } if (wsaDataInit) { WSACleanup(); } } } else { /* FIX: Use a hardcoded password (it was not sent over the network) * INCIDENTAL FLAW: CWE-259 Hard Coded Password */ wcscpy(password, L"Password1234!"); } if(globalReturnsTrueOrFalse()) { { HANDLE pHandle; wchar_t * username = L"User"; wchar_t * domain = L"Domain"; /* Use the password in LogonUser() to establish that it is "sensitive" */ /* POTENTIAL FLAW: Using sensitive information that was possibly sent in plaintext over the network */ if (LogonUserW( username, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } } else { { HCRYPTPROV hCryptProv = 0; HCRYPTHASH hHash = 0; HCRYPTKEY hKey = 0; char hashData[100] = HASH_INPUT; HANDLE pHandle; wchar_t * username = L"User"; wchar_t * domain = L"Domain"; do { BYTE payload[(100 - 1) * sizeof(wchar_t)]; /* same size as password except for NUL terminator */ DWORD payloadBytes; /* Hex-decode the input string into raw bytes */ payloadBytes = decodeHexWChars(payload, sizeof(payload), password); /* Wipe the hex string, to prevent it from being given to LogonUserW if * any of the crypto calls fail. */ SecureZeroMemory(password, 100 * sizeof(wchar_t)); /* Aquire a Context */ if(!CryptAcquireContext(&hCryptProv, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, 0)) { break; } /* Create hash handle */ if(!CryptCreateHash(hCryptProv, CALG_SHA_256, 0, 0, &hHash)) { break; } /* Hash the input string */ if(!CryptHashData(hHash, (BYTE*)hashData, strlen(hashData), 0)) { break; } /* Derive an AES key from the hash */ if(!CryptDeriveKey(hCryptProv, CALG_AES_256, hHash, 0, &hKey)) { break; } /* FIX: Decrypt the password */ if(!CryptDecrypt(hKey, 0, 1, 0, payload, &payloadBytes)) { break; } /* Copy back into password and NUL-terminate */ memcpy(password, payload, payloadBytes); password[payloadBytes / sizeof(wchar_t)] = L'\0'; } while (0); if (hKey) { CryptDestroyKey(hKey); } if (hHash) { CryptDestroyHash(hHash); } if (hCryptProv) { CryptReleaseContext(hCryptProv, 0); } /* Use the password in LogonUser() to establish that it is "sensitive" */ if (LogonUserW( username, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &pHandle) != 0) { printLine("User logged in successfully."); CloseHandle(pHandle); } else { printLine("Unable to login."); } } } }
BOOL DoLoginTasks( IN OUT PGINA_CONTEXT pgContext, IN PWSTR UserName, IN PWSTR Domain, IN PWSTR Password) { EndDialog(pgContext->hSasNotice, WLX_SAS_ACTION_NONE); pgContext->hSasNotice = 0; LPWSTR ProfilePath = NULL; LPWSTR lpEnvironment = NULL; TOKEN_STATISTICS Stats; PWLX_PROFILE_V2_0 pProfile = NULL; DWORD cbStats, cbSize; BOOL bResult; if (!LogonUserW(UserName, Domain, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &pgContext->UserToken)) { WARN("LogonUserW() failed\n"); goto cleanup; } /* Get profile path */ cbSize = 0; bResult = GetProfilesDirectoryW(NULL, &cbSize); if (!bResult && GetLastError() == ERROR_INSUFFICIENT_BUFFER) { ProfilePath = HeapAlloc(GetProcessHeap(), 0, cbSize * sizeof(WCHAR)); if (!ProfilePath) { WARN("HeapAlloc() failed\n"); goto cleanup; } bResult = GetProfilesDirectoryW(ProfilePath, &cbSize); } if (!bResult) { WARN("GetUserProfileDirectoryW() failed\n"); goto cleanup; } /* Allocate memory for profile */ pProfile = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WLX_PROFILE_V2_0)); if (!pProfile) { WARN("HeapAlloc() failed\n"); goto cleanup; } pProfile->dwType = WLX_PROFILE_TYPE_V2_0; pProfile->pszProfile = ProfilePath; lpEnvironment = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 32 * sizeof(WCHAR)); if (!lpEnvironment) { WARN("HeapAlloc() failed\n"); goto cleanup; } wcscpy(lpEnvironment, L"LOGONSERVER=\\\\Test"); pProfile->pszEnvironment = lpEnvironment; if (!GetTokenInformation(pgContext->UserToken, TokenStatistics, (PVOID)&Stats, sizeof(TOKEN_STATISTICS), &cbStats)) { WARN("Couldn't get Authentication id from user token!\n"); goto cleanup; } *pgContext->pAuthenticationId = Stats.AuthenticationId; pgContext->pMprNotifyInfo->pszUserName = DuplicationString(UserName); pgContext->pMprNotifyInfo->pszDomain = DuplicationString(Domain); pgContext->pMprNotifyInfo->pszPassword = DuplicationString(Password); pgContext->pMprNotifyInfo->pszOldPassword = NULL; *pgContext->pdwOptions = 0; *pgContext->pProfile = pProfile; return TRUE; cleanup: if (pProfile) { HeapFree(GetProcessHeap(), 0, pProfile->pszEnvironment); } HeapFree(GetProcessHeap(), 0, pProfile); HeapFree(GetProcessHeap(), 0, ProfilePath); return FALSE; }
/* Execute a command as a "user". The command is run as cmd.exe /c <command> The command is executed from the user's HOME (as determined by the user profile) Input, Output & Err streams are redirected. */ void *win_execute_command(wchar_t *shell, wchar_t *command, wchar_t *user, wchar_t *password, wchar_t *domain, wchar_t *root, int pty_mode) { SECURITY_ATTRIBUTES sa; STARTUPINFOW si; HANDLE out_rd_tmp, in_wr_tmp, out_wr, in_rd, in_wr, err_wr; exec_ctx *ctx; HANDLE ttok, ntok; int ret; ZeroMemory(&sa, sizeof(sa)); sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; ctx = malloc(sizeof(*ctx)); ZeroMemory(ctx, sizeof(*ctx)); ctx->pty_mode = pty_mode; /* setup the parent child plumbing */ if (!CreatePipe(&in_rd, &in_wr_tmp, &sa, 0)) { printf("Couldn't set up in pipe to child %s", get_error_msg(GetLastError())); free(ctx); return NULL; } if (!CreatePipe(&out_rd_tmp, &out_wr, &sa, 0)) { printf("Couldn't set up stdout pipe to child %s", get_error_msg(GetLastError())); free(ctx); return NULL; } if (!DuplicateHandle(GetCurrentProcess(), out_wr, GetCurrentProcess(), &err_wr, 0, TRUE, DUPLICATE_SAME_ACCESS)) { printf("Couldn't set up stderr pipe to child %s", get_error_msg(GetLastError())); free(ctx); return NULL; } if (!DuplicateHandle(GetCurrentProcess(), out_rd_tmp, GetCurrentProcess(), &ctx->out_rd, 0, FALSE, DUPLICATE_SAME_ACCESS)) { return NULL; } if (!DuplicateHandle(GetCurrentProcess(), in_wr_tmp, GetCurrentProcess(), &in_wr, 0, FALSE, DUPLICATE_SAME_ACCESS)) { return NULL; } CloseHandle(out_rd_tmp); CloseHandle(in_wr_tmp); ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; si.wShowWindow = SW_HIDE; si.hStdInput = in_rd; si.hStdOutput = out_wr; si.hStdError = err_wr; /* if (!CreateProcessWithLogonW(user, domain, password, LOGON_WITH_PROFILE, shell, command, 0, NULL, root, &si, &ctx->pi)) { */ ret = LogonUserW(user, domain, password, LOGON32_LOGON_NETWORK, LOGON32_PROVIDER_DEFAULT, &ttok); if (!ret) { CloseHandle(ttok); INFO(GetLastError(), "Login failed for user"); return NULL; } ret = DuplicateTokenEx(ttok, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &ntok); if (!ret) { CloseHandle(ttok); INFO(GetLastError(), "Can't impersonate user"); return NULL; } CloseHandle(ttok); if (!CreateProcessAsUserW(ntok, shell, command, NULL, NULL, TRUE, 0, NULL, root, &si, &ctx->pi)) { int ecode = GetLastError(); INFO(GetLastError(), "CreateProcess failed"); free(ctx); CloseHandle(ntok); return NULL; } CloseHandle(ntok); CloseHandle(out_wr); CloseHandle(err_wr); CloseHandle(in_rd); return ctx; }