From e572057d7cc6192049017a97294d03884fd13af4 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 6 Jun 2019 13:37:22 -0700 Subject: [PATCH] Password case insensitive and encoded. Proper uninstall --- launchers/win32/LauncherDlg.cpp | 137 ++++++++++++++++++---------- launchers/win32/LauncherDlg.h | 1 + launchers/win32/LauncherManager.cpp | 71 +++++++++++--- launchers/win32/LauncherManager.h | 4 + launchers/win32/LauncherUtils.cpp | 47 +++++++++- launchers/win32/LauncherUtils.h | 19 +++- 6 files changed, 219 insertions(+), 60 deletions(-) diff --git a/launchers/win32/LauncherDlg.cpp b/launchers/win32/LauncherDlg.cpp index 07fb57ddcd..7751c9cd6b 100644 --- a/launchers/win32/LauncherDlg.cpp +++ b/launchers/win32/LauncherDlg.cpp @@ -46,6 +46,10 @@ CLauncherDlg::CLauncherDlg(CWnd* pParent) EnableD2DSupport(); } +CLauncherDlg::~CLauncherDlg() { + theApp._manager.closeLog(); +} + void CLauncherDlg::DoDataExchange(CDataExchange* pDX) { DDX_Control(pDX, IDC_BUTTON_NEXT, m_btnNext); @@ -154,25 +158,50 @@ HCURSOR CLauncherDlg::OnQueryDragIcon() } void CLauncherDlg::startProcess() { - if (theApp._manager.needsUpdate()) { - setDrawDialog(DrawStep::DrawProcessUpdate); - } else { - setDrawDialog(DrawStep::DrawProcessSetup); - } - - CString installDir; - theApp._manager.getAndCreatePaths(LauncherManager::PathType::Interface_Directory, installDir); - CString interfaceExe = installDir += "\\interface.exe"; - if (!theApp._manager.isLoggedIn()) { - theApp._manager.downloadContent(); - } else { - theApp._manager.downloadApplication(); - } + if (theApp._manager.needsUpdate()) { + theApp._manager.addToLog(_T("Starting Process Update")); + setDrawDialog(DrawStep::DrawProcessUpdate); + } else { + theApp._manager.addToLog(_T("Starting Process Setup")); + setDrawDialog(DrawStep::DrawProcessSetup); + } + theApp._manager.addToLog(_T("Deleting directories before install")); + + CString installDir; + theApp._manager.getAndCreatePaths(LauncherManager::PathType::Interface_Directory, installDir); + CString downloadDir; + theApp._manager.getAndCreatePaths(LauncherManager::PathType::Download_Directory, downloadDir); + + LauncherUtils::deleteDirectoriesOnThread(installDir, downloadDir, [&](int error) { + LauncherUtils::DeleteDirError deleteError = (LauncherUtils::DeleteDirError)error; + if (error == LauncherUtils::DeleteDirError::NoErrorDeleting) { + theApp._manager.addToLog(_T("Install directory deleted.")); + theApp._manager.addToLog(_T("Downloads directory deleted.")); + // CString interfaceExe = installPath += "\\interface.exe"; + if (!theApp._manager.isLoggedIn()) { + theApp._manager.addToLog(_T("Downloading Content")); + theApp._manager.downloadContent(); + } else { + theApp._manager.addToLog(_T("Downloading App")); + theApp._manager.downloadApplication(); + } + } + if (error == LauncherUtils::DeleteDirError::ErrorDeletingPath1 || + error == LauncherUtils::DeleteDirError::ErrorDeletingPaths) { + theApp._manager.addToLog(_T("Error deleting install directory.")); + } + if (error == LauncherUtils::DeleteDirError::ErrorDeletingPath2 || + error == LauncherUtils::DeleteDirError::ErrorDeletingPaths) { + theApp._manager.addToLog(_T("Error deleting downloads directory.")); + } + }); } BOOL CLauncherDlg::getHQInfo(const CString& orgname) { CString hash; - LauncherUtils::hMac256(orgname, LAUNCHER_HMAC_SECRET, hash); + CString lowerOrgName = orgname; + lowerOrgName.MakeLower(); + LauncherUtils::hMac256(lowerOrgName, LAUNCHER_HMAC_SECRET, hash); return theApp._manager.readOrganizationJSON(hash) == LauncherUtils::ResponseError::NoError; } @@ -181,33 +210,44 @@ afx_msg void CLauncherDlg::OnTroubleClicked() { } afx_msg void CLauncherDlg::OnNextClicked() { - if (_drawStep != DrawStep::DrawChoose) { - CString token; - CString username, password, orgname; - m_orgname.GetWindowTextW(orgname); - m_username.GetWindowTextW(username); - m_password.GetWindowTextW(password); - LauncherUtils::ResponseError error; - if (orgname.GetLength() > 0 && username.GetLength() > 0 && password.GetLength() > 0) { - if (getHQInfo(orgname)) { - error = theApp._manager.getAccessTokenForCredentials(username, password); - if (error == LauncherUtils::ResponseError::NoError) { - setDrawDialog(DrawStep::DrawChoose); - } else if (error == LauncherUtils::ResponseError::BadCredentials) { - setDrawDialog(DrawStep::DrawLoginErrorCred); - } else { - MessageBox(L"Error Reading or retreaving response.", L"Network Error", MB_OK | MB_ICONERROR); - } - } else { - setDrawDialog(DrawStep::DrawLoginErrorOrg); - } - } - } else { - CString displayName; - m_username.GetWindowTextW(displayName); - theApp._manager.setDisplayName(displayName); - startProcess(); - } + if (_drawStep != DrawStep::DrawChoose) { + CString token; + CString username, password, orgname; + m_orgname.GetWindowTextW(orgname); + m_username.GetWindowTextW(username); + m_password.GetWindowTextW(password); + + username = LauncherUtils::urlEncodeString(username); + password = LauncherUtils::urlEncodeString(password); + LauncherUtils::ResponseError error; + if (orgname.GetLength() > 0 && username.GetLength() > 0 && password.GetLength() > 0) { + theApp._manager.addToLog(_T("Trying to get organization data")); + if (getHQInfo(orgname)) { + theApp._manager.addToLog(_T("Organization data received.")); + theApp._manager.addToLog(_T("Trying to log in with credentials")); + error = theApp._manager.getAccessTokenForCredentials(username, password); + if (error == LauncherUtils::ResponseError::NoError) { + theApp._manager.addToLog(_T("Logged in correctly.")); + setDrawDialog(DrawStep::DrawChoose); + } else if (error == LauncherUtils::ResponseError::BadCredentials) { + theApp._manager.addToLog(_T("Bad credentials. Try again")); + setDrawDialog(DrawStep::DrawLoginErrorCred); + } else { + theApp._manager.addToLog(_T("Error Reading or retreaving response.")); + MessageBox(L"Error Reading or retreaving response.", L"Network Error", MB_OK | MB_ICONERROR); + } + } else { + theApp._manager.addToLog(_T("Organization name does not exist.")); + setDrawDialog(DrawStep::DrawLoginErrorOrg); + } + } + } else { + CString displayName; + m_username.GetWindowTextW(displayName); + theApp._manager.setDisplayName(displayName); + theApp._manager.addToLog(_T("Setting display name: " + displayName)); + startProcess(); + } } void CLauncherDlg::drawBackground(CHwndRenderTarget* pRenderTarget) { @@ -534,11 +574,13 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) { } if (_showSplash) { if (_splashStep == 0){ - if (theApp._manager.needsUninstall()) { - setDrawDialog(DrawStep::DrawProcessUninstall); - } else { - setDrawDialog(DrawStep::DrawLogo); - } + if (theApp._manager.needsUninstall()) { + theApp._manager.addToLog(_T("Waiting to unistall")); + setDrawDialog(DrawStep::DrawProcessUninstall); + } else { + theApp._manager.addToLog(_T("Start splash screen")); + setDrawDialog(DrawStep::DrawLogo); + } } else if (_splashStep > 100) { _showSplash = false; if (theApp._manager.shouldShutDown()) { @@ -551,6 +593,7 @@ void CLauncherDlg::OnTimer(UINT_PTR nIDEvent) { theApp._manager.uninstallApplication(); exit(0); } else { + theApp._manager.addToLog(_T("Starting login")); setDrawDialog(DrawStep::DrawLoginLogin); } } diff --git a/launchers/win32/LauncherDlg.h b/launchers/win32/LauncherDlg.h index 55bc97f205..d743dd31d2 100644 --- a/launchers/win32/LauncherDlg.h +++ b/launchers/win32/LauncherDlg.h @@ -38,6 +38,7 @@ public: }; CLauncherDlg(CWnd* pParent = nullptr); + ~CLauncherDlg(); virtual BOOL PreTranslateMessage(MSG* pMsg); void setDrawDialog(DrawStep step, BOOL isUpdate = FALSE); diff --git a/launchers/win32/LauncherManager.cpp b/launchers/win32/LauncherManager.cpp index 94a659a4d7..3dc7ddedcc 100644 --- a/launchers/win32/LauncherManager.cpp +++ b/launchers/win32/LauncherManager.cpp @@ -9,6 +9,7 @@ // #include "stdafx.h" +#include #include #include "LauncherManager.h" @@ -24,19 +25,57 @@ LauncherManager::~LauncherManager() } void LauncherManager::init() { - getMostRecentBuild(_latestApplicationURL, _latestVersion); - CString currentVersion; - if (isApplicationInstalled(currentVersion, _domainURL, _contentURL, _loggedIn) && _loggedIn) { - if (_latestVersion.Compare(currentVersion) == 0) { - launchApplication(); - _shouldShutdown = TRUE; - } else { - _shouldUpdate = TRUE; - } - } + initLog(); + addToLog(_T("Getting most recent build")); + getMostRecentBuild(_latestApplicationURL, _latestVersion); + addToLog(_T("Latest version: ") + _latestVersion); + CString currentVersion; + if (isApplicationInstalled(currentVersion, _domainURL, _contentURL, _loggedIn) && _loggedIn) { + addToLog(_T("Installed version: ") + currentVersion); + if (_latestVersion.Compare(currentVersion) == 0) { + addToLog(_T("Already running most recent build. Launching interface.exe")); + launchApplication(); + _shouldShutdown = TRUE; + } else { + addToLog(_T("New build found. Updating")); + _shouldUpdate = TRUE; + } + } +} + +BOOL LauncherManager::initLog() { + CString logPath; + auto result = getAndCreatePaths(PathType::Launcher_Directory, logPath); + if (result) { + logPath += _T("log.txt"); + return result = _logFile.Open(logPath, CFile::modeCreate | CFile::modeReadWrite); + } + return FALSE; +} + +BOOL LauncherManager::addToLog(const CString& line) { + if (_logFile.m_hFile != CStdioFile::hFileNull) { + char buff[100]; + time_t now = time(0); + tm ltm; + localtime_s(<m, &now); + + strftime(buff, 100, "%Y-%m-%d %H:%M:%S", <m); + CString timeStr = CString(buff); + _logFile.WriteString(timeStr + _T(" ") + line + _T("\n")); + return TRUE; + } + return FALSE; +} + +void LauncherManager::closeLog() { + if (_logFile.m_hFile != CStdioFile::hFileNull) { + _logFile.Close(); + } } BOOL LauncherManager::installLauncher() { + addToLog(_T("Installing Launcher.")); CString appPath; BOOL result = getAndCreatePaths(PathType::Running_Path, appPath); if (!result) { @@ -60,6 +99,7 @@ BOOL LauncherManager::installLauncher() { CopyFile(appPath, instalationPath, FALSE); } } else if (_shouldUninstall) { + addToLog(_T("Launching uninstall mode.")); CString tempPath; if (getAndCreatePaths(PathType::Temp_Directory, tempPath)) { tempPath += _T("\\HQ_uninstaller_tmp.exe"); @@ -73,6 +113,7 @@ BOOL LauncherManager::installLauncher() { BOOL LauncherManager::createShortcuts() { CString desktopLnkPath; + addToLog(_T("Creating shortcuts.")); getAndCreatePaths(PathType::Desktop_Directory, desktopLnkPath); desktopLnkPath += _T("\\HQ Launcher.lnk"); CString installDir; @@ -100,6 +141,7 @@ BOOL LauncherManager::createShortcuts() { BOOL LauncherManager::deleteShortcuts() { CString desktopLnkPath; + addToLog(_T("Deleting shortcuts.")); getAndCreatePaths(PathType::Desktop_Directory, desktopLnkPath); desktopLnkPath += _T("\\HQ Launcher.lnk"); BOOL success = LauncherUtils::deleteFileOrDirectory(desktopLnkPath); @@ -353,13 +395,17 @@ BOOL LauncherManager::uninstallApplication() { void LauncherManager::onZipExtracted(ZipType type, int size) { if (type == ZipType::ZipContent) { + addToLog(_T("Downloading application.")); downloadApplication(); } else if (type == ZipType::ZipApplication) { createShortcuts(); CString versionPath; getAndCreatePaths(LauncherManager::PathType::Launcher_Directory, versionPath); - createConfigJSON(); + addToLog(_T("Creating config.json")); + createConfigJSON(); + addToLog(_T("Launching application.")); launchApplication(_tokensJSON); + addToLog(_T("Creating registry keys.")); createApplicationRegistryKeys(size); _shouldShutdown = TRUE; } @@ -377,8 +423,10 @@ BOOL LauncherManager::extractApplication() { void LauncherManager::onFileDownloaded(DownloadType type) { if (type == DownloadType::DownloadContent) { + addToLog(_T("Installing content.")); installContent(); } else if (type == DownloadType::DownloadApplication) { + addToLog(_T("Installing application.")); extractApplication(); } } @@ -412,6 +460,7 @@ BOOL LauncherManager::downloadFile(DownloadType type, const CString& url, CStrin } BOOL LauncherManager::downloadContent() { + addToLog(_T("Downloading content.")); CString contentURL = getContentURL(); return downloadFile(DownloadType::DownloadContent, contentURL, _contentZipPath); } diff --git a/launchers/win32/LauncherManager.h b/launchers/win32/LauncherManager.h index 3ad21694f6..4bc09b49ca 100644 --- a/launchers/win32/LauncherManager.h +++ b/launchers/win32/LauncherManager.h @@ -53,6 +53,9 @@ public: LauncherManager(); ~LauncherManager(); void init(); + BOOL initLog(); + BOOL addToLog(const CString& line); + void closeLog(); BOOL getAndCreatePaths(PathType type, CString& outPath); BOOL getInstalledVersion(const CString& path, CString& version); BOOL isApplicationInstalled(CString& version, CString& domain, @@ -105,5 +108,6 @@ private: BOOL _shouldUpdate{ FALSE }; BOOL _shouldUninstall{ FALSE }; BOOL _shouldShutdown{ FALSE }; + CStdioFile _logFile; }; diff --git a/launchers/win32/LauncherUtils.cpp b/launchers/win32/LauncherUtils.cpp index 8a75747e9b..8cf1d78ebf 100644 --- a/launchers/win32/LauncherUtils.cpp +++ b/launchers/win32/LauncherUtils.cpp @@ -17,6 +17,24 @@ #include "LauncherUtils.h" +CString LauncherUtils::urlEncodeString(const CString& url) { + std::map specialCharsMap = { { _T("$"), _T("%24") }, { _T(" "), _T("%20") }, { _T("#"), _T("%23") }, + { _T("@"), _T("%40") }, { _T("`"), _T("%60") }, { _T("&"), _T("%26") }, + { _T("/"), _T("%2F") }, { _T(":"), _T("%3A") }, { _T(";"), _T("%3B") }, + { _T("<"), _T("%3C") }, { _T(">"), _T("%3E") }, { _T("="), _T("%3D") }, + { _T("?"), _T("%3F") }, { _T("["), _T("%5B") }, { _T("\\"), _T("%5C") }, + { _T("]"), _T("%5D") }, { _T("^"), _T("%5E") }, { _T("{"), _T("%7B") }, + { _T("|"), _T("%7C") }, { _T("}"), _T("%7D") }, { _T("~"), _T("%7E") }, + { _T("“"), _T("%22") }, { _T("‘"), _T("%27") }, { _T("+"), _T("%2B") }, + { _T(","), _T("%2C") } }; + CString stringOut = url; + stringOut.Replace(_T("%"), _T("%25")); + for (auto& itr = specialCharsMap.begin(); itr != specialCharsMap.end(); itr++) { + stringOut.Replace(itr->first, itr->second); + } + return stringOut; +} + BOOL LauncherUtils::IsProcessRunning(const wchar_t *processName) { bool exists = false; PROCESSENTRY32 entry; @@ -374,6 +392,19 @@ DWORD WINAPI LauncherUtils::downloadThread(LPVOID lpParameter) return 0; } +DWORD WINAPI LauncherUtils::deleteDirectoriesThread(LPVOID lpParameter) { + DeleteThreadData& data = *((DeleteThreadData*)lpParameter); + DeleteDirError error = DeleteDirError::NoErrorDeleting; + if (!LauncherUtils::deleteFileOrDirectory(data._path1)) { + error = DeleteDirError::ErrorDeletingPath1; + } + if (!LauncherUtils::deleteFileOrDirectory(data._path2)) { + error = error == NoError ? DeleteDirError::ErrorDeletingPath2 : DeleteDirError::ErrorDeletingPaths; + } + data.callback(error); + return 0; +} + BOOL LauncherUtils::unzipFileOnThread(int type, const std::string& zipFile, const std::string& path, std::function callback) { DWORD myThreadID; UnzipThreadData* unzipThreadData = new UnzipThreadData(); @@ -402,4 +433,18 @@ BOOL LauncherUtils::downloadFileOnThread(int type, const CString& url, const CSt return TRUE; } return FALSE; -} \ No newline at end of file +} + +BOOL LauncherUtils::deleteDirectoriesOnThread(const CString& dir1, const CString& dir2, std::function callback) { + DWORD myThreadID; + DeleteThreadData* deleteThreadData = new DeleteThreadData(); + deleteThreadData->_path1 = dir1; + deleteThreadData->_path2 = dir2; + deleteThreadData->setCallback(callback); + HANDLE myHandle = CreateThread(0, 0, deleteDirectoriesThread, deleteThreadData, 0, &myThreadID); + if (myHandle) { + CloseHandle(myHandle); + return TRUE; + } + return FALSE; +} diff --git a/launchers/win32/LauncherUtils.h b/launchers/win32/LauncherUtils.h index 3e9f18d892..4add0fb931 100644 --- a/launchers/win32/LauncherUtils.h +++ b/launchers/win32/LauncherUtils.h @@ -30,6 +30,13 @@ public: NoError }; + enum DeleteDirError { + NoErrorDeleting = 0, + ErrorDeletingPath1, + ErrorDeletingPath2, + ErrorDeletingPaths + }; + struct DownloadThreadData { int _type; CString _url; @@ -52,6 +59,13 @@ public: } }; + struct DeleteThreadData { + CString _path1; + CString _path2; + std::function callback; + void setCallback(std::function fn) { callback = std::bind(fn, std::placeholders::_1); } + }; + static BOOL parseJSON(const CString& jsonTxt, Json::Value& jsonObject); static ResponseError makeHTTPCall(const CString& callerName, const CString& mainUrl, const CString& dirUrl, const CString& contentType, @@ -69,9 +83,12 @@ public: static BOOL deleteRegistryKey(const CString& registryPath); static BOOL unzipFileOnThread(int type, const std::string& zipFile, const std::string& path, std::function callback); static BOOL downloadFileOnThread(int type, const CString& url, const CString& file, std::function callback); + static BOOL deleteDirectoriesOnThread(const CString& dir1, const CString& dir2, std::function callback); + static CString urlEncodeString(const CString& url); -private: + private: // Threads static DWORD WINAPI unzipThread(LPVOID lpParameter); static DWORD WINAPI downloadThread(LPVOID lpParameter); + static DWORD WINAPI deleteDirectoriesThread(LPVOID lpParameter); }; \ No newline at end of file