summaryrefslogtreecommitdiff
diff options
authordaniel <daniel@daniel-1-2>2024-03-30 15:32:56 +0100
committerdaniel <daniel@daniel-1-2>2024-03-30 15:32:56 +0100
commit2f4430c42f160acd4045fac1009d253dcfc5c38a (patch)
tree9ee2c640cbe966822ea69aa9782acb9706aa916e
parent42c59e1c7373c19765b5412e52ce2a7854d7ce7b (diff)
preventing execution of outdated scripts
-rwxr-xr-xsrc/Controller/MainController.hpp1
-rwxr-xr-xsrc/Model/ListCfg.hpp85
-rwxr-xr-xsrc/Model/Script.hpp39
-rwxr-xr-xsrc/Model/ScriptSourceMap.hpp12
4 files changed, 99 insertions, 38 deletions
diff --git a/src/Controller/MainController.hpp b/src/Controller/MainController.hpp
index 6b374a3..b240656 100755
--- a/src/Controller/MainController.hpp
+++ b/src/Controller/MainController.hpp
@@ -850,7 +850,6 @@ class MainController :
}
if (progress == 1 && this->grublistCfg->hasScriptUpdates()) {
- this->grublistCfg->applyScriptUpdates();
this->env->modificationsUnsaved = true;
this->view->showScriptUpdateInfo();
}
diff --git a/src/Model/ListCfg.hpp b/src/Model/ListCfg.hpp
index 46cbf3a..27f5f48 100755
--- a/src/Model/ListCfg.hpp
+++ b/src/Model/ListCfg.hpp
@@ -250,6 +250,19 @@ class Model_ListCfg :
repository.deleteAllEntries();
this->unlock();
}
+
+ // init script source map
+ if (!preserveConfig){
+ //load script map
+ this->scriptSourceMap.load();
+ if (!this->scriptSourceMap.fileExists() && this->getProxifiedScripts().size() > 0) {
+ this->generateScriptSourceMap();
+ }
+ this->populateScriptSourceMap();
+
+ this->applyScriptUpdates();
+ }
+ this->disableOutdatedScripts();
//create proxifiedScript links & chmod other files
this->log("creating proxifiedScript links & chmodding other files…", Logger::EVENT);
@@ -258,7 +271,9 @@ class Model_ListCfg :
for (auto script : this->repository) {
if (script->isInScriptDir(env->cfg_dir)){
//createScriptForwarder & disable proxies
- createScriptForwarder(script->fileName);
+ if (! this->scriptSourceMap.hasUpdateFor(script->fileName)) {
+ this->createScriptForwarder(script->fileName);
+ }
auto relatedProxies = proxies.getProxiesByScript(script);
for (auto proxy : relatedProxies) {
int res = chmod(proxy->fileName.c_str(), 0644);
@@ -271,16 +286,6 @@ class Model_ListCfg :
this->unlock();
send_new_load_progress(0.1);
-
- if (!preserveConfig){
- //load script map
- this->scriptSourceMap.load();
- if (!this->scriptSourceMap.fileExists() && this->getProxifiedScripts().size() > 0) {
- this->generateScriptSourceMap();
- }
- this->populateScriptSourceMap();
- }
-
//run mkconfig
this->log("running " + this->env->mkconfig_cmd, Logger::EVENT);
FILE* mkconfigProc = popen((this->env->mkconfig_cmd + " 2> " + this->errorLogFile).c_str(), "r");
@@ -309,7 +314,7 @@ class Model_ListCfg :
//restore old configuration
this->log("restoring grub configuration", Logger::EVENT);
this->lock();
- for (auto script : this->repository){
+ for (auto script : this->repository) {
if (script->isInScriptDir(env->cfg_dir)){
//removeScriptForwarder & reset proxy permissions
bool result = removeScriptForwarder(script->fileName);
@@ -322,6 +327,9 @@ class Model_ListCfg :
chmod(proxy->fileName.c_str(), proxy->permissions);
}
}
+ for (auto script : this->repository.trash) {
+ script->restorePermissions();
+ }
this->unlock();
//remove invalid proxies from list (no file system action here)
@@ -430,6 +438,7 @@ class Model_ListCfg :
send_new_save_progress(0.2);
// register in script source map
+ this->scriptSourceMap.deleteUpdates();
for (auto scriptFilenameMapItem : scriptFilenameMap) {
this->scriptSourceMap.registerMove(scriptFilenameMapItem.second, scriptFilenameMapItem.first->fileName);
}
@@ -1175,8 +1184,9 @@ class Model_ListCfg :
int pos = -1;
if (script->isCustomScript) {
- defaultPath = this->env->cfg_dir + "/40_custom";
- } else if (defaultScripts.find(script->name) != defaultScripts.end()) {
+ continue;
+ }
+ if (defaultScripts.find(script->name) != defaultScripts.end()) {
pos = defaultScripts[script->name];
std::ostringstream str;
str << this->env->cfg_dir << "/" << std::setw(2) << std::setfill('0') << pos << "_" << script->name;
@@ -1193,6 +1203,9 @@ class Model_ListCfg :
{
std::string proxyfiedScriptPath = this->env->cfg_dir + "/proxifiedScripts";
for (auto script : this->repository) {
+ if (script->isCustomScript) {
+ continue;
+ }
if (script->fileName.substr(0, proxyfiedScriptPath.length()) != proxyfiedScriptPath
&& this->scriptSourceMap.getSourceName(script->fileName) == "") {
this->scriptSourceMap.addScript(script->fileName);
@@ -1205,6 +1218,27 @@ class Model_ListCfg :
return this->scriptSourceMap.getUpdates().size() > 0;
}
+ public: void disableOutdatedScripts()
+ {
+ std::list<std::string> newScriptPathes = this->scriptSourceMap.getUpdates();
+ for (auto newScriptPath : newScriptPathes) {
+ std::string oldScriptPath = this->scriptSourceMap[newScriptPath];
+
+ std::shared_ptr<Model_Script> oldScript = nullptr;
+ for (auto script : this->repository.trash) {
+ if (script->fileName == oldScriptPath) {
+ oldScript = script;
+ break;
+ }
+ }
+
+ // disable old scripts on top level to avoid problems on execution
+ if (oldScript && ! oldScript->isInScriptDir(env->cfg_dir)) {
+ oldScript->revokeExecutePermissions();
+ }
+ }
+ }
+
public: void applyScriptUpdates()
{
std::list<std::string> newScriptPathes = this->scriptSourceMap.getUpdates();
@@ -1217,31 +1251,16 @@ class Model_ListCfg :
continue;
}
- // unsync proxies of newScript
+ // remove auto generated proxies of newScript
auto newProxies = this->proxies.getProxiesByScript(newScript);
for (auto newProxy : newProxies) {
- newProxy->unsync();
this->proxies.deleteProxy(newProxy);
}
- // copy entries of custom scripts
- if (oldScript->isCustomScript && newScript->isCustomScript && oldScript->entries().size()) {
- for (auto entry : oldScript->entries()) {
- if (entry->type == Model_Entry::PLAINTEXT && newScript->getPlaintextEntry()) {
- newScript->getPlaintextEntry()->content = entry->content; // copy plaintext instead of adding another entry
- newScript->getPlaintextEntry()->isModified = true;
- } else {
- newScript->entries().push_back(entry);
- newScript->entries().back()->isModified = true;
- }
- }
- }
-
- // connect proxies of oldScript with newScript, resync
+ // connect proxies of oldScript with newScript
auto oldProxies = this->proxies.getProxiesByScript(oldScript);
for (auto oldProxy : oldProxies) {
// connect old proxy to new script
- oldProxy->unsync();
oldProxy->dataSource = newScript;
if (oldProxy->fileName == oldScript->fileName) {
oldProxy->fileName = newScript->fileName; // set the new fileName
@@ -1258,10 +1277,6 @@ class Model_ListCfg :
this->repository.removeScript(oldScript);
}
- this->scriptSourceMap.deleteUpdates();
-
- this->proxies.unsync_all();
- this->proxies.sync_all(true, true, nullptr, this->repository.getScriptPathMap());
}
diff --git a/src/Model/Script.hpp b/src/Model/Script.hpp
index f87c883..14cfc20 100755
--- a/src/Model/Script.hpp
+++ b/src/Model/Script.hpp
@@ -44,6 +44,7 @@ class Model_Script : public Model_EntryPathFollower, public Trait_LoggerAware, p
public: std::string name, fileName;
public: bool isCustomScript;
public: std::shared_ptr<Model_Entry> root;
+ private: int originalPermissions = -1;
public: Model_Script(std::string const& name, std::string const& fileName) :
name(name),
@@ -284,6 +285,44 @@ class Model_Script : public Model_EntryPathFollower, public Trait_LoggerAware, p
return false;
}
+ /**
+ * temporary removes the execute permissions on file system to ensure the script is not executed when running grub-mkconfig
+ */
+ public: void revokeExecutePermissions()
+ {
+ if (this->fileName == "") {
+ return;
+ }
+
+ struct stat fileProperties;
+ auto res = stat(this->fileName.c_str(), &fileProperties);
+
+ if (res != 0) {
+ return;
+ }
+
+ this->originalPermissions = fileProperties.st_mode & ~S_IFMT;
+
+ chmod(this->fileName.c_str(), this->originalPermissions & ~0111);
+ }
+
+ /**
+ * restore the execute permissions on file system after running revokeExecutePermissions
+ */
+ public: void restorePermissions()
+ {
+ if (this->fileName == "") {
+ return;
+ }
+
+ if (this->originalPermissions == -1) {
+ return;
+ }
+ chmod(this->fileName.c_str(), this->originalPermissions);
+
+ this->originalPermissions = -1;
+ }
+
public: operator ArrayStructure() const
{
ArrayStructure result;
diff --git a/src/Model/ScriptSourceMap.hpp b/src/Model/ScriptSourceMap.hpp
index 1c4d619..b1d23e6 100755
--- a/src/Model/ScriptSourceMap.hpp
+++ b/src/Model/ScriptSourceMap.hpp
@@ -112,8 +112,8 @@ public:
return this->find(sourceName) != this->end();
}
- std::string getSourceName(std::string const& destinationName) {
- for (std::map<std::string, std::string>::iterator iter = this->begin(); iter != this->end(); iter++) {
+ std::string getSourceName(std::string const& destinationName) const {
+ for (std::map<std::string, std::string>::const_iterator iter = this->begin(); iter != this->end(); iter++) {
if (iter->second == destinationName) {
return iter->first;
}
@@ -129,6 +129,14 @@ public:
return this->_newSources;
}
+ bool hasUpdateFor(std::string const& scriptName) const {
+ auto sourceName = this->getSourceName(scriptName);
+ if (sourceName == "") {
+ return false;
+ }
+ return std::find(this->_newSources.begin(), this->_newSources.end(), sourceName) != this->_newSources.end();
+ }
+
void deleteUpdates() {
this->_newSources.clear();
}