summaryrefslogtreecommitdiff
path: root/client/Proxifier.cpp
diff options
context:
space:
mode:
authorAlex Borisov <borisov.alexandr@rambler.ru>2011-12-19 04:04:57 +0200
committerAlex Borisov <borisov.alexandr@rambler.ru>2011-12-19 04:04:57 +0200
commit816941559161cbc54d5373713cf07fb3fe40e311 (patch)
treeb0b697f4ed0a3a1b82b4478cbd93e6f3d6da5f02 /client/Proxifier.cpp
parent5e33822db1ecbcd49ac85e46a95061dd7522f28c (diff)
XML config public API. read/write static proxies to/from XML. few bug fixes
Diffstat (limited to 'client/Proxifier.cpp')
-rw-r--r--client/Proxifier.cpp521
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;
+}