Password case insensitive and encoded. Proper uninstall

This commit is contained in:
luiscuenca 2019-06-06 13:37:22 -07:00
parent 9835f16821
commit e572057d7c
6 changed files with 219 additions and 60 deletions

View file

@ -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);
}
}

View file

@ -38,6 +38,7 @@ public:
};
CLauncherDlg(CWnd* pParent = nullptr);
~CLauncherDlg();
virtual BOOL PreTranslateMessage(MSG* pMsg);
void setDrawDialog(DrawStep step, BOOL isUpdate = FALSE);

View file

@ -9,6 +9,7 @@
//
#include "stdafx.h"
#include <time.h>
#include <fstream>
#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(&ltm, &now);
strftime(buff, 100, "%Y-%m-%d %H:%M:%S", &ltm);
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);
}

View file

@ -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;
};

View file

@ -17,6 +17,24 @@
#include "LauncherUtils.h"
CString LauncherUtils::urlEncodeString(const CString& url) {
std::map<CString, CString> 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<void(int, int)> 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;
}
}
BOOL LauncherUtils::deleteDirectoriesOnThread(const CString& dir1, const CString& dir2, std::function<void(int)> 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;
}

View file

@ -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<void(int)> callback;
void setCallback(std::function<void(int)> 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<void(int, int)> callback);
static BOOL downloadFileOnThread(int type, const CString& url, const CString& file, std::function<void(int)> callback);
static BOOL deleteDirectoriesOnThread(const CString& dir1, const CString& dir2, std::function<void(int)> 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);
};