summaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/Config.cpp16
-rw-r--r--client/Config.h34
-rw-r--r--client/Dialog.cpp40
-rw-r--r--client/Dialog.h3
-rw-r--r--client/Proxifier.cpp521
-rw-r--r--client/Proxifier.h140
-rw-r--r--client/UpdatedConfig.cpp2
7 files changed, 631 insertions, 125 deletions
diff --git a/client/Config.cpp b/client/Config.cpp
index 38ff50f..489818e 100644
--- a/client/Config.cpp
+++ b/client/Config.cpp
@@ -201,6 +201,18 @@ vector<string> Config::GetProxies(string &country, string &state, string &city)
return proxies;
}
+ProxyEntryStatic* Config::GetStaticProxy(string& name)
+{
+ for (unsigned i = 0; i < staticProxy.size(); i++)
+ {
+ if (name.compare(staticProxy[i].name) == 0)
+ {
+ return &staticProxy[i];
+ }
+ }
+ return NULL;
+}
+
vector<ProxyEntryStatic> Config::GetStaticProxyGuiLine(unsigned line)
{
vector<ProxyEntryStatic> staticProxyLine;
@@ -349,7 +361,7 @@ void Config::ParseGenericProxies(string data)
}
}
-void Config::ParseStaticPorxies(string data)
+void Config::ParseStaticProxies(string data)
{
/* clear previous proxies */
staticProxy.clear();
@@ -491,6 +503,6 @@ void Config::ReadStaticProxy()
proxyFile.read (buffer, length);
proxyFile.close();
string proxies = buffer;
- ParseStaticPorxies(proxies);
+ ParseStaticProxies(proxies);
delete[] buffer;
}
diff --git a/client/Config.h b/client/Config.h
index 5254361..f7653e0 100644
--- a/client/Config.h
+++ b/client/Config.h
@@ -140,7 +140,7 @@ public:
* @return Alphabetically sorted vector<string> with unique state names.<br/>
* Resultant vector<string> may be empty in case if there are no states in specified country
*/
- vector<string> GetStates(std::string &country);
+ vector<string> GetStates(string &country);
/**
* @brief Get list of cities in particular country without states<br/>
@@ -179,12 +179,19 @@ public:
vector<string> GetProxies(string &country, string &state, string &city);
/**
+ * @brief Get static proxy entry by name
+ * @param name static proxy name
+ * @return ProxyEntryStatic object on success or false otherwise
+ */
+ ProxyEntryStatic* GetStaticProxy(string& name);
+
+ /**
* @brief Get list of static proxy entries
* @param line number of GUI line proxy list associated with
* @return List of static proxy entries sorted by speed in descending order
*/
vector<ProxyEntryStatic> GetStaticProxyGuiLine(unsigned line);
-
+
/**
* @brief Get number of static proxy GUI lines
* @return number of static proxy GUI lines or 0 if none
@@ -245,53 +252,50 @@ protected:
*/
unsigned retryTimeout;
};
-
+
+ /**
+ * @brief array of config server entries
+ */
+ vector<ServerEntry> servers;
+ /**
+ * @brief time between subsequent config updates
+ */
+ unsigned updateInterval;
/**
* @brief create new instance (not allowed for use by other classes and functions)
*/
Config();
-
/**
* @brief parse client configuration
* @param data string containing configuration parameters
*/
void ParseConfig(string data);
-
/**
* @brief parse list of generic proxies
* @param data string containing list of ProxyEntryGeneric records
*/
void ParseGenericProxies(string data);
-
/**
* @brief parse list of static proxies
* @param data string containing list of ProxyEntryStatic records
*/
- void ParseStaticPorxies(string data);
-
+ void ParseStaticProxies(string data);
/**
* @brief parse firewall configuration
* @param data string containing list of FirewallEntry records
*/
void ParseFirewalls(string data);
-
/**
* @brief parse list of file to be deleted
* @param data string containing path to aforementioned file
*/
void ParseDeleteList(string data);
-
/**
* @brief parse list of files to be downloaded
* @param data string containing path to new file and it's md5 hash
*/
void ParseDownloadList(string data);
- /**
- * @brief time between subsequent config updates
- */
- unsigned updateInterval;
- vector<ServerEntry> servers;
private:
vector<ProxyEntryGeneric> genericProxy;
vector<ProxyEntryStatic> staticProxy;
diff --git a/client/Dialog.cpp b/client/Dialog.cpp
index 4c92a79..279bfc8 100644
--- a/client/Dialog.cpp
+++ b/client/Dialog.cpp
@@ -52,7 +52,7 @@ ProxyDialog::ProxyDialog(QWidget *parent): QDialog(parent)
genericProxyGroup = new QButtonGroup;
staticProxyGroup = new QButtonGroup;
- /* static proxy panel */
+ // static proxy panel
bottomLabel = new QLabel(QString::fromLocal8Bit(cfg->BottomPanelText.c_str()));
bottomLabel->setObjectName("bottomLabel");
bottomLabel->setAlignment(Qt::AlignHCenter);
@@ -91,7 +91,10 @@ ProxyDialog::ProxyDialog(QWidget *parent): QDialog(parent)
QPushButton *btn = new QPushButton();
btn->setObjectName("bottomBtn");
btn->setCheckable(true);
+ btn->setChecked(proxifier->IsOn(staticProxyLine[j].host, staticProxyLine[j].port));
+ btn->setProperty("proxyName", QString::fromLocal8Bit(staticProxyLine[j].name.c_str()));
btn->setLayout(btnLayout);
+ connect(btn, SIGNAL(toggled(bool)), this, SLOT(StaticToggled(bool)));
staticProxyGroup->addButton(btn);
bottomPanelLayout->addWidget(btn, i, j);
}
@@ -106,14 +109,35 @@ ProxyDialog::ProxyDialog(QWidget *parent): QDialog(parent)
setLayout(mainLayout);
}
-void ProxyDialog::StaticToggle(bool val)
+void ProxyDialog::StaticToggled(bool on)
{
- Logger::Debug("toggle: %s\n", val ? "true" : "false");
-}
-
-void ProxyDialog::StaticClick()
-{
- Logger::Debug("click\n");
+ QPushButton* btn = (QPushButton*) sender();
+ QVariant propVal = btn->property("proxyName");
+ QString proxyName = propVal.toString();
+ Logger::Debug("Static Proxy button toggled\n");
+ Logger::Debug("State '%s', associated proxy name: %s\n", on ? "down" : "up", proxyName.toStdString().c_str());
+
+ UpdatedConfig *cfg = UpdatedConfig::CurrentConfig();
+ string name = proxyName.toStdString();
+ ProxyEntryStatic* proxy = cfg->GetStaticProxy(name);
+ if (proxy == NULL)
+ {
+ Logger::Error("Static proxy with name '%s' was not found\n", proxyName.toStdString().c_str());
+ return;
+ }
+ Proxifier *proxifier = Proxifier::GetInstance();
+ if (!proxifier->IsValid())
+ {
+ Logger::Fatal("No valid proxifier configuration file found!\n");
+ }
+ if (on)
+ {
+ proxifier->TurnProxyOn(*proxy);
+ }
+ else
+ {
+ proxifier->TurnProxyOff(*proxy);
+ }
}
void ProxyDialog::CountryActivated(int index)
diff --git a/client/Dialog.h b/client/Dialog.h
index e3be343..8fd5aff 100644
--- a/client/Dialog.h
+++ b/client/Dialog.h
@@ -30,8 +30,7 @@ private slots:
void StateActivated(int index);
void CityActivated(int index);
- void StaticToggle(bool toggle);
- void StaticClick();
+ void StaticToggled(bool toggle);
private:
QButtonGroup *genericProxyGroup;
QButtonGroup *staticProxyGroup;
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;
+}
diff --git a/client/Proxifier.h b/client/Proxifier.h
index 320ba44..af27b80 100644
--- a/client/Proxifier.h
+++ b/client/Proxifier.h
@@ -7,33 +7,71 @@
#include <string>
#include <QDomElement>
#include <QString>
+#include "Proxy.h"
+
using namespace std;
class QDomDocument;
+class Proxy;
+/**
+ * @brief Special class that represents proxifier's configuration file
+ * @note All operation that turn on/off and add/remove proxies and chain will apply to "Default" rule
+ * All proxies are put into "Client" chain event if it's only one proxy
+ */
class Proxifier
{
public:
/**
+ * @brief Get application-wide singleton instance of Proxifier class
+ * @return pointer to Proxifier singleton
+ */
+ static Proxifier* GetInstance();
+
+ /**
+ * @brief Chack if the current config is valid
+ * @return true if the config is valid or false otherwise
+ * @note you may wish to try ReadConfig() before but if it doesn't help
+ */
+ bool IsValid();
+ /**
+ * @brief Check if certain server is turned on in Proxifier's tules and list
+ */
+ bool IsOn(string& addr, short port);
+ /**
+ * @brief turn proxy on, all traffic will go throught this proxy
+ * @param proxy Proxy class that represents particular proxy
+ * @return true on success or false otherwise
+ * @note adds specified proxy to Proxifier's Proxy list and in "Client" chain<br/>
+ * Also adds "Client" chain to "Default" rule if its not there
+ */
+ bool TurnProxyOn(Proxy& proxy);
+ /**
+ * @brief turn proxy off
+ * @param proxy Proxy class that represents particular proxy
+ * @return true on success or false otherwise<br/>
+ * alse true will be returned even if proxy is not exist in config
+ * @note removes specified proxy from "Client" chain and from Proxy list<br/>
+ * If its the last proxy in client chain then "Default" rule will be resetted to<br/>
+ * send all traffic directly to servers
+ */
+ bool TurnProxyOff(Proxy& proxy);
+
+private:
+ /**
* @brief class representing Proxifier's proxy setting
*/
- class Proxy
+ class ProxifierProxy: public Proxy
{
public:
- string login;
- string password;
- string host;
- string type;
- short port;
- // proxifier-specific fields
int id;
short option;
bool useAuth; // whether to authenticate on server
bool emptyAuth; // self-closing auth (for Proxifier it means to use current login+pass)
- Proxy();
+ ProxifierProxy();
};
/**
@@ -92,26 +130,18 @@ public:
Rule();
};
-
- static Proxifier* GetInstance();
-
/**
- * @brief Chack if the current config is valid
- * @return true if the config is valid or false otherwise
- * @note you may wish to try ReadConfig() before but if it doesn't help
+ * @brief XML indentation level
*/
- bool IsValid();
+ static const int indent = 4;
/**
- * @brief read Proxifier config from file and parse it
- * @note you should check IsValid() method to get to know if the config is valid
+ * @brief default chain name to add proxies to
*/
- void ReadConfig();
-
-private:
+ static string defaultChain;
/**
- * @brief XML indentation level
+ * @brief default rule name to add proxies to
*/
- static const int indent = 4;
+ static string defaultRule;
/**
* @brief pointer to sigleton instance
*/
@@ -120,14 +150,37 @@ private:
* @brief XML file name to read data from
*/
QString filename;
+ /**
+ * @brief indicates whether config valid or not
+ */
bool valid;
- vector<Proxy> proxyList;
+ vector<ProxifierProxy> proxyList;
vector<Chain> chainList;
vector<Rule> ruleList;
Proxifier();
+ /**
+ * @brief read Proxifier config from file and parse it
+ * @note you should check IsValid() method to get to know if the config is valid
+ */
+ void ReadConfig();
+ /**
+ * @brief read ProxyList section in Proxifier's config
+ * @param root root DOM element
+ * @return true on success or false otherwise
+ */
bool ReadProxyList(QDomElement& root);
+ /**
+ * @brief read ChainList section in Proxifier's config
+ * @param root root DOM element
+ * @return true on success or false otherwise
+ */
bool ReadChainList(QDomElement& root);
+ /**
+ * @brief read RuleList section in Proxifier's config
+ * @param root root DOM element
+ * @return true on success or false otherwise
+ */
bool ReadRuleList(QDomElement& root);
/**
* @brief gets the next valid ID fo proxy/chain
@@ -141,28 +194,28 @@ private:
* id new proxy id will be set there
* @return true on success or false otherwise
*/
- bool AddProxy(Proxy& proxy, int* id);
+ bool AddProxy(ProxifierProxy& proxy, int* id);
/**
* @brief add new chain to proxifier config
* @param name the name of the chain
* id new chain id
* @return true on success or false otherwise
*/
- bool AddChain(string& name, int *id);
+ bool AddChain(string& name, int* id);
/**
* @brief add proxy to proxy chain
* @param proxyId proxy ID to add to proxy chain
* chainId chain ID to add proxy to
* @return true on success or false otherwise
*/
- bool AddChainProxy(int proxyId, int chainId);
+ bool AddProxyToChain(int proxyId, int chainId);
/**
* @brief remove proxy from proxy chain
* @param proxyId proxy ID to remove to proxy chain
* chainId chain ID to remove proxy from
* @return true on success or false otherwise
*/
- bool RemoveChainProxy(int proxyId, int chainId);
+ bool RemoveProxyFromChain(int proxyId, int chainId);
/**
* @brief add new rule to Proxifier config
* @param rule rule class representing Proxifier's rule entry
@@ -170,11 +223,42 @@ private:
*/
bool AddRule(Rule& rule);
/**
+ * @brief modify action on existing rule
+ * @param name name of the rule to modify
+ * action action name to set to
+ * actId id of action target (if applicable)
+ * @return true on success or false otherwise
+ */
+ bool SetRuleAction(string& name, string& action, int actId = -1);
+ /**
* @brief remove rule to Proxifier config
* @param name name of the rule to remove from Rule list
* @return true on success or false otherwise
*/
- bool RemoveRule(string name);
+ bool RemoveRule(string& name);
+ /**
+ * @brief Check if certain proxy address exists in Proxifier's Proxy list
+ * @param addr proxy address to check for
+ * port proxy port to check for
+ * id if proxy exist then there'll be it's id number otherwise this value is undetermined
+ * @return true if proxy exist or false otherwise
+ * @note DNS names are not resolved and not compared to IPs<br/>
+ * proxies are compared only by checking address and port values
+ */
+ bool isProxyExists(string& addr, short port, int* id = NULL);
+ /**
+ * @brief Check if certain chain exisis in Proxifier's Chain list
+ * @param name chain name to check for
+ * id if chain exist then there'll be it's id number otherwise this value is undetermined
+ * @return true if chain exist or false otherwise
+ */
+ bool isChainExists(string& name, int* id = NULL);
+ /**
+ * @brief Check if certain rule exists
+ * @param name rule name to check for
+ * @return true if rule exist or false otherwise
+ */
+ bool isRuleExists(string& name);
};
#endif
diff --git a/client/UpdatedConfig.cpp b/client/UpdatedConfig.cpp
index 6873d30..0d7703a 100644
--- a/client/UpdatedConfig.cpp
+++ b/client/UpdatedConfig.cpp
@@ -145,7 +145,7 @@ void UpdatedConfig::gotServerReply(SslClient::RequestType &type, QByteArray &con
ParseGenericProxies(confdata.constData());
break;
case SslClient::StaticProxyList:
- ParseStaticPorxies(confdata.constData());
+ ParseStaticProxies(confdata.constData());
break;
case SslClient::FirewallList:
ParseFirewalls(confdata.constData());