From b662bcf5ae24f1437369271826b1aee7f3a49e83 Mon Sep 17 00:00:00 2001 From: Don HO Date: Thu, 27 Sep 2018 09:56:58 +0200 Subject: [PATCH] Add checking MD5 ability in Plugin Admin Check MD5 after installing to prevent from MITMA --- PowerEditor/src/MISC/Common/Common.cpp | 42 +++++++++++++++ PowerEditor/src/MISC/Common/Common.h | 5 ++ PowerEditor/src/MISC/md5/md5Dlgs.cpp | 8 +-- PowerEditor/src/NppNotification.cpp | 1 - .../WinControls/PluginsAdmin/pluginsAdmin.cpp | 52 ++++++++++++++----- .../WinControls/Preference/preferenceDlg.cpp | 3 +- 6 files changed, 91 insertions(+), 20 deletions(-) diff --git a/PowerEditor/src/MISC/Common/Common.cpp b/PowerEditor/src/MISC/Common/Common.cpp index 8d3f031d0..df3dd308a 100644 --- a/PowerEditor/src/MISC/Common/Common.cpp +++ b/PowerEditor/src/MISC/Common/Common.cpp @@ -30,6 +30,8 @@ #include #include #include +#include + #include "StaticDialog.h" #include "Common.h" @@ -1194,3 +1196,43 @@ bool isAssoCommandExisting(LPCTSTR FullPathName) } return isAssoCommandExisting; } + +std::wstring s2ws(const std::string& str) +{ + using convert_typeX = std::codecvt_utf8; + std::wstring_convert converterX; + + return converterX.from_bytes(str); +} + +std::string ws2s(const std::wstring& wstr) +{ + using convert_typeX = std::codecvt_utf8; + std::wstring_convert converterX; + + return converterX.to_bytes(wstr); +} + +bool deleteFileOrFolder(const generic_string& f2delete) +{ + auto len = f2delete.length(); + TCHAR* actionFolder = new TCHAR[len + 2]; + lstrcpy(actionFolder, f2delete.c_str()); + actionFolder[len] = 0; + actionFolder[len + 1] = 0; + + SHFILEOPSTRUCT fileOpStruct = { 0 }; + fileOpStruct.hwnd = NULL; + fileOpStruct.pFrom = actionFolder; + fileOpStruct.pTo = NULL; + fileOpStruct.wFunc = FO_DELETE; + fileOpStruct.fFlags = FOF_NOCONFIRMATION | FOF_SILENT | FOF_ALLOWUNDO; + fileOpStruct.fAnyOperationsAborted = false; + fileOpStruct.hNameMappings = NULL; + fileOpStruct.lpszProgressTitle = NULL; + + int res = SHFileOperation(&fileOpStruct); + + delete[] actionFolder; + return (res == 0); +} diff --git a/PowerEditor/src/MISC/Common/Common.h b/PowerEditor/src/MISC/Common/Common.h index 383050879..be1e62352 100644 --- a/PowerEditor/src/MISC/Common/Common.h +++ b/PowerEditor/src/MISC/Common/Common.h @@ -191,3 +191,8 @@ HWND CreateToolTip(int toolID, HWND hDlg, HINSTANCE hInst, const PTSTR pszText); bool isCertificateValidated(const generic_string & fullFilePath, const generic_string & subjectName2check); bool isAssoCommandExisting(LPCTSTR FullPathName); + +std::wstring s2ws(const std::string& str); +std::string ws2s(const std::wstring& wstr); + +bool deleteFileOrFolder(const generic_string& f2delete); \ No newline at end of file diff --git a/PowerEditor/src/MISC/md5/md5Dlgs.cpp b/PowerEditor/src/MISC/md5/md5Dlgs.cpp index a6b572c9b..1bdee98b2 100644 --- a/PowerEditor/src/MISC/md5/md5Dlgs.cpp +++ b/PowerEditor/src/MISC/md5/md5Dlgs.cpp @@ -58,20 +58,20 @@ INT_PTR CALLBACK MD5FromFilesDlg::run_dlgProc(UINT message, WPARAM wParam, LPARA if (stringVector *pfns = fDlg.doOpenMultiFilesDlg()) { std::wstring files2check, md5resultStr; - for (auto it = pfns->begin(); it != pfns->end(); ++it) + for (const auto& it : *pfns) { WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); - const char *path = wmc->wchar2char(it->c_str(), CP_ACP); + const char *path = wmc->wchar2char(it.c_str(), CP_ACP); MD5 md5; char *md5Result = md5.digestFile(path); if (md5Result) { - files2check += *it; + files2check += it; files2check += TEXT("\r\n"); - wchar_t* fileName = ::PathFindFileName(it->c_str()); + wchar_t* fileName = ::PathFindFileName(it.c_str()); md5resultStr += wmc->char2wchar(md5Result, CP_ACP); md5resultStr += TEXT(" "); md5resultStr += fileName; diff --git a/PowerEditor/src/NppNotification.cpp b/PowerEditor/src/NppNotification.cpp index 4ee7ac811..6bfc96e1c 100644 --- a/PowerEditor/src/NppNotification.cpp +++ b/PowerEditor/src/NppNotification.cpp @@ -1067,4 +1067,3 @@ BOOL Notepad_plus::notify(SCNotification *notification) } return FALSE; } - diff --git a/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp b/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp index b20e9e639..b79c73327 100644 --- a/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp +++ b/PowerEditor/src/WinControls/PluginsAdmin/pluginsAdmin.cpp @@ -511,22 +511,45 @@ bool PluginsAdminDlg::installPlugins() int result = updater.runSync(); if (result == 0) // wingup return 0 -> OK { - // Remove (Hide) installed plugin from available list - _availableList.hideFromPluginInfoPtr(i); + generic_string installedPluginFolder = nppPluginsDir; + PathAppend(installedPluginFolder, i->_folderName); - // Add installed plugin into insttalled list - PluginUpdateInfo* installedPui = new PluginUpdateInfo(*i); - installedPui->_isVisible = true; - _installedList.pushBack(installedPui); - - // Load installed plugin - generic_string installedPluginPath = nppPluginsDir; - PathAppend(installedPluginPath, i->_folderName); + generic_string installedPluginPath = installedPluginFolder; PathAppend(installedPluginPath, i->_folderName + TEXT(".dll")); - vector dll2Remove; - int index = _pPluginsManager->loadPlugin(installedPluginPath.c_str(), dll2Remove); - _pPluginsManager->addInMenuFromPMIndex(index); + // check installed id to prevent from MITMA + MD5 md5; + char *md5Result = md5.digestFile(ws2s(installedPluginPath).c_str()); + if (ws2s(i->_id) == md5Result) + { + // Remove (Hide) installed plugin from available list + _availableList.hideFromPluginInfoPtr(i); + + // Add installed plugin into insttalled list + PluginUpdateInfo* installedPui = new PluginUpdateInfo(*i); + installedPui->_isVisible = true; + _installedList.pushBack(installedPui); + + // Load installed plugin + vector dll2Remove; + int index = _pPluginsManager->loadPlugin(installedPluginPath.c_str(), dll2Remove); + _pPluginsManager->addInMenuFromPMIndex(index); + } + else + { + // Remove installed plugin + NativeLangSpeaker *pNativeSpeaker = (NppParameters::getInstance())->getNativeLangSpeaker(); + pNativeSpeaker->messageBox("PluginIdNotMatchedWillBeRemoved", + NULL, + TEXT("The plugin \"$STR_REPLACE$\" ID is not correct. This plugin will be uninstalled."), + TEXT("Plugin ID missmathed"), + MB_OK | MB_APPLMODAL, + 0, + i->_displayName.c_str()); + + deleteFileOrFolder(installedPluginFolder); + } + } else // wingup return non-zero (-1) -> Not OK { @@ -689,6 +712,9 @@ bool loadFromJson(PluginViewList & pl, const json& j) valStr = i.at("description").get(); pi->_description = wmc->char2wchar(valStr.c_str(), CP_ACP); + valStr = i.at("id").get(); + pi->_id = wmc->char2wchar(valStr.c_str(), CP_ACP); + valStr = i.at("version").get(); generic_string newValStr(valStr.begin(), valStr.end()); pi->_version = Version(newValStr); diff --git a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp index 152cb9a82..66bb9f64e 100644 --- a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp +++ b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp @@ -399,8 +399,7 @@ INT_PTR CALLBACK BarsDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM) if (pNppParam->getNativeLangA()) // if nativeLangA is not NULL, then we can be sure the default language (English) is not used { string fn = localizationSwitcher.getFileName(); - wstring fnW(fn.begin(), fn.end()); - fnW.assign(fn.begin(), fn.end()); + wstring fnW = s2ws(fn); lang = localizationSwitcher.getLangFromXmlFileName(fnW.c_str()); } auto index = ::SendDlgItemMessage(_hSelf, IDC_COMBO_LOCALIZATION, CB_FINDSTRINGEXACT, static_cast(-1), reinterpret_cast(lang.c_str()));