diff options
Diffstat (limited to 'client/Proxifier.cpp')
-rw-r--r-- | client/Proxifier.cpp | 521 |
1 files changed, 452 insertions, 69 deletions
diff --git a/client/Proxifier.cpp b/client/Proxifier.cpp index 84553f7..c8e7cf8 100644 --- a/client/Proxifier.cpp +++ b/client/Proxifier.cpp @@ -4,11 +4,13 @@ #include "Logger.h" #include "Proxifier.h" +// static field initialization +string Proxifier::defaultChain = "Client"; +string Proxifier::defaultRule = "Default"; +Proxifier* Proxifier::instance = NULL; -Proxifier* Proxifier::instance = NULL; - -Proxifier::Proxy::Proxy(): port(0), id(0), option(0), emptyAuth(true) +Proxifier::ProxifierProxy::ProxifierProxy(): id(0), option(0), emptyAuth(true) { } @@ -46,6 +48,172 @@ bool Proxifier::IsValid() return valid; } +bool Proxifier::IsOn(string& addr, short port) +{ + // at first proxy should be in proxy list + int proxyId = 0; + if (!isProxyExists(addr, port, &proxyId)) + { + return false; + } + // next - check for "Client" chain + int chainId; + if (!isChainExists(defaultChain, &chainId)) + { + return false; + } + // and next - find chain by id + for (unsigned i = 0; chainList.size(); i++) + { + if (chainList[i].id == chainId) + { + map<int, bool>::iterator it = chainList[i].proxies.find(proxyId); + if (it == chainList[i].proxies.end()) + { + return false; + } + return it->second; + } + } + return false; +} + +bool Proxifier::TurnProxyOn(Proxy& proxy) +{ + if (!valid) + { + return false; + } + // if proxy do not exist - add it + int proxyId = 0; + if (!isProxyExists(proxy.host, proxy.port, &proxyId)) + { + ProxifierProxy _proxy; + _proxy.login = proxy.login; + _proxy.password = proxy.password; + _proxy.host = proxy.host; + _proxy.port = proxy.port; + _proxy.type = proxy.type; + // default values for Proxifier Proxy record + _proxy.option = 0; + _proxy.useAuth = !proxy.login.empty(); + _proxy.emptyAuth = false; + if (!AddProxy(_proxy, &proxyId)) + { + return false; + } + } + // if "Client" chain do not exist - add it + int chainId = 0; + if (!isChainExists(defaultChain, &chainId)) + { + if (!AddChain(defaultChain, &chainId)) + { + return false; + } + } + + // try to find proxy in chain + for (unsigned i = 0; i < chainList.size(); i++) + { + if (chainList[i].name.compare(defaultChain) != 0) + { + continue; + } + + map<int, bool>::iterator it = chainList[i].proxies.find(proxyId); + if (it != chainList[i].proxies.end()) + { + if (!it->second) + { + // proxy is not enabled - remove it and add again + RemoveProxyFromChain(proxyId, chainId); + AddProxyToChain(proxyId, chainId); + } + } + else + { + // proxy not found in the target chain - add it + AddProxyToChain(proxyId, chainId); + } + } + + if (isRuleExists(defaultRule)) + { + // the "Default" rule can't be disabled from Proxifier's UI + // so we can skip this check here + string action = "Chain"; + if (!SetRuleAction(defaultRule, action, chainId)) + { + return false; + } + } + else + { + Rule rule; + rule.isEnabled = true; + rule.name = defaultRule; + rule.action = "Chain"; + rule.actId = chainId; + if (!AddRule(rule)) + { + return false; + } + } + return true; +} + +bool Proxifier::TurnProxyOff(Proxy& proxy) +{ + if (!valid) + { + return false; + } + // check if proxy do not exist + int proxyId = 0; + if (!isProxyExists(proxy.host, proxy.port, &proxyId)) + { + return true; + } + int chainId = 0; + if (!isChainExists(defaultChain, &chainId)) + { + return true; + } + // try to find proxy in chain + bool isFound = false; + for (unsigned i = 0; i < chainList.size(); i++) + { + if (chainList[i].name.compare(defaultChain) != 0) + { + continue; + } + + map<int, bool>::iterator it = chainList[i].proxies.find(proxyId); + if (it != chainList[i].proxies.end()) + { + isFound = true; + // if it was the last proxy in chain - change default rule + if (chainList[i].proxies.size() == 1) + { + string action = "Direct"; + SetRuleAction(defaultRule, action); + } + RemoveProxyFromChain(proxyId, chainId); + // update config to reflect last changes + ReadConfig(); + break; + } + } + if (!isFound) + { + return true; + } + + return true; +} + + void Proxifier::ReadConfig() { valid = false; @@ -53,19 +221,19 @@ void Proxifier::ReadConfig() QFile config(filename); if (!config.open(QIODevice::ReadOnly)) { - Logger::Error("Can't open Proxifier configuration file\n"); + Logger::Error("Can't open Proxifier config file\n"); return; } if (!configDom.setContent(&config)) { - Logger::Fatal("Invalid Proxifier configuration file!"); + Logger::Fatal("Invalid Proxifier config file!\n"); return; } QDomElement root = configDom.documentElement(); if (root.tagName() != "ProxifierProfile") { - Logger::Fatal("Invalid Proxifier configuration file!"); + Logger::Fatal("Invalid Proxifier config file!\n"); return; } QDomElement options = root.firstChildElement("Options"); @@ -76,19 +244,19 @@ void Proxifier::ReadConfig() // parse proxy list if (!ReadProxyList(root)) { - Logger::Fatal("Invalid Proxifier configuration file!"); + Logger::Fatal("Invalid Proxifier config file!\n"); return; } // parse chain list if (!ReadChainList(root)) { - Logger::Fatal("Invalid Proxifier configuration file!"); + Logger::Fatal("Invalid Proxifier configfile!\n"); return; } // parse rule list if (!ReadRuleList(root)) { - Logger::Fatal("Invalid Proxifier configuration file!"); + Logger::Fatal("Invalid Proxifier config file!\n"); return; } config.close(); @@ -109,7 +277,7 @@ bool Proxifier::ReadProxyList(QDomElement& root) while (!proxy.isNull()) { bool ok = true; // used when converting values to int - Proxy proxyRecord; + ProxifierProxy proxyRecord; // check whether attributes are present if (! (proxy.hasAttribute("id") && proxy.hasAttribute("type"))) @@ -155,7 +323,7 @@ bool Proxifier::ReadProxyList(QDomElement& root) QDomElement authElem = proxy.firstChildElement("Authentication"); if (!authElem.isNull()) { - if (! authElem.hasChildNodes()) + if (!authElem.hasChildNodes()) { // in case if "NTLM + userLogin" = selfclosing auth tag Logger::Trace("Auth section is empty\n"); @@ -312,6 +480,7 @@ bool Proxifier::ReadRuleList(QDomElement& root) return true; } + int Proxifier::GetNextId() { if (!valid) @@ -333,33 +502,32 @@ int Proxifier::GetNextId() max = chainList[i].id; } } - return max; + return max + 1; } -bool Proxifier::AddProxy(Proxy& proxy, int* id) +bool Proxifier::AddProxy(ProxifierProxy& proxy, int* id) { - Logger::Trace("Adding new proxy to Proxifier configuration\n"); - if (!valid) - { - Logger::Error("Current Proxifier configuration is not valid. Update first!\n"); - return false; - } + Logger::Trace("Adding new proxy to Proxifier config\n"); + // read XML DOM structure QDomDocument configDom("config"); - QFile config(filename); - if (!config.open(QIODevice::WriteOnly)) + QFile* config = new QFile(filename); + if (!config->open(QIODevice::ReadOnly)) { - Logger::Error("Can't open Proxifier configuration file\n"); + Logger::Error("Can't open Proxifier config file for reading\n"); return false; } - if (!configDom.setContent(&config)) + if (!configDom.setContent(config)) { - Logger::Fatal("Invalid Proxifier configuration file!"); + Logger::Fatal("Invalid Proxifier config file!\n"); return false; } + config->close(); + delete config; + QDomElement root = configDom.documentElement(); if (root.tagName() != "ProxifierProfile") { - Logger::Error("Invalid Proxifier configuration file!"); + Logger::Error("Invalid Proxifier config file!\n"); return false; } QDomElement proxyListElem = root.firstChildElement("ProxyList"); @@ -367,7 +535,6 @@ bool Proxifier::AddProxy(Proxy& proxy, int* id) { return false; } - // create proxy record // root element QDomElement proxyElem = configDom.createElement("Proxy"); @@ -417,29 +584,45 @@ bool Proxifier::AddProxy(Proxy& proxy, int* id) proxyElem.appendChild(authElem); } proxyListElem.appendChild(proxyElem); - QTextStream(&config) << configDom.toString(indent); - config.close(); + // update state to reflect all the changes + ReadProxyList(root); + + // save new DOM to file + config = new QFile(filename); + if (!config->open(QIODevice::WriteOnly)) + { + Logger::Error("Can't open Proxifier config file for writing\n"); + return false; + } + QTextStream(config) << configDom.toString(indent); + config->close(); + delete config; return true; } bool Proxifier::AddChain(string& name, int *id) { + Logger::Trace("Adding new chain to Proxifier config\n"); + // read XML DOM structure QDomDocument configDom("config"); - QFile config(filename); - if (!config.open(QIODevice::WriteOnly)) + QFile* config = new QFile(filename); + if (!config->open(QIODevice::ReadOnly)) { - Logger::Error("Can't open Proxifier configuration file\n"); + Logger::Error("Can't open Proxifier config file\n"); return false; } - if (!configDom.setContent(&config)) + if (!configDom.setContent(config)) { - Logger::Fatal("Invalid Proxifier configuration file!"); + Logger::Fatal("Invalid Proxifier config file!\n"); return false; } + config->close(); + delete config; + QDomElement root = configDom.documentElement(); if (root.tagName() != "ProxifierProfile") { - Logger::Error("Invalid Proxifier configuration file!"); + Logger::Error("Invalid Proxifier config file!\n"); return false; } QDomElement chainListElem = root.firstChildElement("ChainList"); @@ -461,30 +644,45 @@ bool Proxifier::AddChain(string& name, int *id) nameElem.appendChild(nameTxt); chainElem.appendChild(nameElem); chainListElem.appendChild(chainElem); + // update state to reflect all the changes + ReadChainList(root); - QTextStream(&config) << configDom.toString(indent); - config.close(); + // save new DOM to file + config = new QFile(filename); + if (!config->open(QIODevice::WriteOnly)) + { + Logger::Error("Can't open Proxifier config file for writing\n"); + return false; + } + QTextStream(config) << configDom.toString(indent); + config->close(); + delete config; return true; } -bool Proxifier::AddChainProxy(int proxyId, int chainId) +bool Proxifier::AddProxyToChain(int proxyId, int chainId) { + Logger::Trace("Adding proxy to chain in Proxifier config\n"); + // read XML DOM structure QDomDocument configDom("config"); - QFile config(filename); - if (!config.open(QIODevice::WriteOnly)) + QFile* config = new QFile(filename); + if (!config->open(QIODevice::ReadOnly)) { - Logger::Error("Can't open Proxifier configuration file\n"); + Logger::Error("Can't open Proxifier config file\n"); return false; } - if (!configDom.setContent(&config)) + if (!configDom.setContent(config)) { - Logger::Fatal("Invalid Proxifier configuration file!"); + Logger::Fatal("Invalid Proxifier config file!\n"); return false; } + config->close(); + delete config; + QDomElement root = configDom.documentElement(); if (root.tagName() != "ProxifierProfile") { - Logger::Error("Invalid Proxifier configuration file!"); + Logger::Error("Invalid Proxifier config file!\n"); return false; } QDomElement chainListElem = root.firstChildElement("ChainList"); @@ -524,30 +722,45 @@ bool Proxifier::AddChainProxy(int proxyId, int chainId) break; } } + // update state to reflect all the changes + ReadChainList(root); - QTextStream(&config) << configDom.toString(indent); - config.close(); + // save new DOM to file + config = new QFile(filename); + if (!config->open(QIODevice::WriteOnly)) + { + Logger::Error("Can't open Proxifier config file for writing\n"); + return false; + } + QTextStream(config) << configDom.toString(indent); + config->close(); + delete config; return true; } -bool Proxifier::RemoveChainProxy(int proxyId, int chainId) +bool Proxifier::RemoveProxyFromChain(int proxyId, int chainId) { + Logger::Trace("Removing proxy from chain in Proxifier config\n"); + // read XML DOM structure QDomDocument configDom("config"); - QFile config(filename); - if (!config.open(QIODevice::WriteOnly)) + QFile* config = new QFile(filename); + if (!config->open(QIODevice::ReadOnly)) { Logger::Error("Can't open Proxifier configuration file\n"); return false; } - if (!configDom.setContent(&config)) + if (!configDom.setContent(config)) { - Logger::Fatal("Invalid Proxifier configuration file!"); + Logger::Fatal("Invalid Proxifier configuration file!\n"); return false; } + config->close(); + delete config; + QDomElement root = configDom.documentElement(); if (root.tagName() != "ProxifierProfile") { - Logger::Error("Invalid Proxifier configuration file!"); + Logger::Error("Invalid Proxifier configuration file!\n"); return false; } QDomElement chainListElem = root.firstChildElement("ChainList"); @@ -591,31 +804,46 @@ bool Proxifier::RemoveChainProxy(int proxyId, int chainId) break; } } + // update state to reflect all the changes + ReadChainList(root); - QTextStream(&config) << configDom.toString(indent); - config.close(); + // save new DOM to file + config = new QFile(filename); + if (!config->open(QIODevice::WriteOnly)) + { + Logger::Error("Can't open Proxifier config file for writing\n"); + return false; + } + QTextStream(config) << configDom.toString(indent); + config->close(); + delete config; return true; } bool Proxifier::AddRule(Rule& rule) { + Logger::Trace("Adding rules to Proxifier config\n"); + // read XML DOM structure QDomDocument configDom("config"); - QFile config(filename); - if (!config.open(QIODevice::WriteOnly)) + QFile* config = new QFile(filename); + if (!config->open(QIODevice::ReadOnly)) { - Logger::Error("Can't open Proxifier configuration file\n"); + Logger::Error("Can't open Proxifier config file\n"); return false; } - if (!configDom.setContent(&config)) + if (!configDom.setContent(config)) { - Logger::Fatal("Invalid Proxifier configuration file!"); + Logger::Fatal("Invalid Proxifier config file!\n"); return false; } + config->close(); + delete config; + QDomElement root = configDom.documentElement(); if (root.tagName() != "ProxifierProfile") { - Logger::Error("Invalid Proxifier configuration file!"); + Logger::Error("Invalid Proxifier config file!\n"); return false; } QDomElement ruleListElem = root.firstChildElement("RuleList"); @@ -678,31 +906,118 @@ bool Proxifier::AddRule(Rule& rule) QDomText portsTxt = configDom.createTextNode(actionId); } ruleElem.appendChild(actionElem); + // update state to reflect all the changes + ReadRuleList(root); - QTextStream(&config) << configDom.toString(indent); - config.close(); + // save new DOM to file + config = new QFile(filename); + if (!config->open(QIODevice::WriteOnly)) + { + Logger::Error("Can't open Proxifier config file for writing\n"); + return false; + } + QTextStream(config) << configDom.toString(indent); + config->close(); + delete config; return true; } -bool Proxifier::RemoveRule(string name) +bool Proxifier::SetRuleAction(string& name, string& action, int actId) { // !names only compared! + Logger::Trace("Setting rule action in Proxifier config\n"); + // read XML DOM structure QDomDocument configDom("config"); - QFile config(filename); - if (!config.open(QIODevice::WriteOnly)) + QFile* config = new QFile(filename); + if (!config->open(QIODevice::ReadWrite)) { Logger::Error("Can't open Proxifier configuration file\n"); return false; } - if (!configDom.setContent(&config)) + if (!configDom.setContent(config)) + { + Logger::Fatal("Invalid Proxifier configuration file!\n"); + return false; + } + config->close(); + delete config; + + QDomElement root = configDom.documentElement(); + if (root.tagName() != "ProxifierProfile") + { + Logger::Error("Invalid Proxifier configuration file!\n"); + return false; + } + QDomElement ruleListElem = root.firstChildElement("ChainList"); + if (ruleListElem.isNull()) + { + return false; + } + + QDomElement ruleElem = ruleListElem.firstChildElement("Rule"); + while (!ruleElem.isNull()) + { + QDomElement nameElem = ruleElem.firstChildElement("Name"); + QString nameStr = nameElem.text(); + if (nameStr == QString::fromLocal8Bit(name.c_str())) + { + // remove old + QDomElement oldActionElem = ruleElem.firstChildElement("Action"); + ruleElem.removeChild(oldActionElem); + // add new + QDomElement newActionElem = configDom.createElement("Action"); + QString actionType = QString::fromLocal8Bit(action.c_str()); + newActionElem.setAttribute("type", actionType); + if ((actionType == "Chain") || (actionType == "Proxy")) + { + QString actionId; + actionId.setNum(actId); + QDomText portsTxt = configDom.createTextNode(actionId); + } + ruleElem.appendChild(newActionElem); + break; + } + } + // update state to reflect all the changes + ReadRuleList(root); + + // save new DOM to file + config = new QFile(filename); + if (!config->open(QIODevice::WriteOnly)) + { + Logger::Error("Can't open Proxifier config file for writing\n"); + return false; + } + QTextStream(config) << configDom.toString(indent); + config->close(); + delete config; + return true; +} + +bool Proxifier::RemoveRule(string& name) +{ + // !names only compared! + Logger::Trace("Removing rule from Proxifier config\n"); + // read XML DOM structure + QDomDocument configDom("config"); + QFile* config = new QFile(filename); + if (!config->open(QIODevice::ReadWrite)) { - Logger::Fatal("Invalid Proxifier configuration file!"); + Logger::Error("Can't open Proxifier configuration file\n"); return false; } + if (!configDom.setContent(config)) + { + Logger::Fatal("Invalid Proxifier configuration file!\n"); + return false; + } + config->close(); + delete config; + QDomElement root = configDom.documentElement(); if (root.tagName() != "ProxifierProfile") { - Logger::Error("Invalid Proxifier configuration file!"); + Logger::Error("Invalid Proxifier configuration file!\n"); return false; } QDomElement ruleListElem = root.firstChildElement("ChainList"); @@ -722,9 +1037,77 @@ bool Proxifier::RemoveRule(string name) break; } } + // update state to reflect all the changes + ReadRuleList(root); - QTextStream(&config) << configDom.toString(indent); - config.close(); + // save new DOM to file + config = new QFile(filename); + if (!config->open(QIODevice::WriteOnly)) + { + Logger::Error("Can't open Proxifier config file for writing\n"); + return false; + } + QTextStream(config) << configDom.toString(indent); + config->close(); + delete config; return true; } +bool Proxifier::isProxyExists(string& addr, short port, int *id) +{ + if (!valid) + { + return false; + } + for (unsigned i = 0; i < proxyList.size(); i++) + { + ProxifierProxy proxy = proxyList[i]; + if ((addr.compare(proxy.host) == 0) && (port == proxy.port)) + { + if (id != NULL) + { + *id = proxy.id; + } + return true; + } + } + return false; +} + +bool Proxifier::isChainExists(string& name, int* id) +{ + if (!valid) + { + return false; + } + for (unsigned i = 0; i < chainList.size(); i++) + { + Chain chain = chainList[i]; + if (name.compare(chain.name) == 0) + { + if (id != NULL) + { + *id = chain.id; + } + return true; + } + } + return false; +} + +bool Proxifier::isRuleExists(string& name) +{ + if (!valid) + { + return false; + } + for (unsigned i = 0; i < ruleList.size(); i++) + { + Rule rule = ruleList[i]; + if (name.compare(rule.name) == 0) + { + return true; + } + } + return false; +} |