summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Borisov <borisov.alexandr@rambler.ru>2011-12-12 03:57:23 +0200
committerAlex Borisov <borisov.alexandr@rambler.ru>2011-12-12 03:57:23 +0200
commitf77a7f9a1e282dba6e39f6b7f0685971cfac7747 (patch)
tree4053e95d95c3a34f6b0cdaa11c61b50de9bbf05f
parent1ecb59ec27137a039a73289a3ded1f8dedcdab88 (diff)
Proxifier config parsing
-rw-r--r--client/Dialog.cpp34
-rw-r--r--client/Dialog.h4
-rw-r--r--client/Proxifier.cpp310
-rw-r--r--client/Proxifier.h114
-rw-r--r--client/Proxy.h1
-rw-r--r--client/UpdatedConfig.cpp2
-rw-r--r--client/client.pro8
7 files changed, 453 insertions, 20 deletions
diff --git a/client/Dialog.cpp b/client/Dialog.cpp
index 4ce48be..dfb280d 100644
--- a/client/Dialog.cpp
+++ b/client/Dialog.cpp
@@ -5,6 +5,7 @@
#include "client.h"
#include "UpdatedConfig.h"
#include "Dialog.h"
+#include "Proxifier.h"
#include "Proxy.h"
using namespace std;
@@ -12,7 +13,12 @@ using namespace std;
ProxyDialog::ProxyDialog(QWidget *parent): QDialog(parent)
{
UpdatedConfig *cfg = UpdatedConfig::CurrentConfig();
-
+ Proxifier *proxifier = Proxifier::GetInstance();
+ if (!proxifier->IsValid())
+ {
+ Logger::Fatal("No valid proxifier configuration file found!\n");
+ }
+
/* generic proxy panel */
topLabel = new QLabel(QString::fromLocal8Bit(cfg->TopPanelText.c_str()));
topLabel->setObjectName("topLabel");
@@ -29,14 +35,14 @@ ProxyDialog::ProxyDialog(QWidget *parent): QDialog(parent)
countryBox->addItem(country);
}
countryBox->setCurrentIndex(-1);
-
+
connect(countryBox, SIGNAL(activated(int)),
this, SLOT(CountryActivated(int)));
connect(stateBox, SIGNAL(activated(int)),
this, SLOT(StateActivated(int)));
connect(cityBox, SIGNAL(activated(int)),
this, SLOT(CityActivated(int)));
-
+
topPanelLayout = new QGridLayout;
topPanelLayout->setSpacing(5);
topPanelLayout->addWidget(countryBox, 0, 0);
@@ -44,7 +50,7 @@ ProxyDialog::ProxyDialog(QWidget *parent): QDialog(parent)
topPanelLayout->addWidget(cityBox, 2, 0);
genericProxyGroup = new QButtonGroup;
staticProxyGroup = new QButtonGroup;
-
+
/* static proxy panel */
bottomLabel = new QLabel(QString::fromLocal8Bit(cfg->BottomPanelText.c_str()));
bottomLabel->setObjectName("bottomLabel");
@@ -89,7 +95,7 @@ ProxyDialog::ProxyDialog(QWidget *parent): QDialog(parent)
bottomPanelLayout->addWidget(btn, i, j);
}
}
-
+
/* setup layouting */
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(topLabel);
@@ -106,7 +112,7 @@ void ProxyDialog::StaticToggle(bool val)
void ProxyDialog::StaticClick()
{
- Logger::Debug("click\n");
+ Logger::Debug("click\n");
}
void ProxyDialog::CountryActivated(int index)
@@ -118,10 +124,10 @@ void ProxyDialog::CountryActivated(int index)
{
return;
}
-
+
string country(countryBox->currentText().toLocal8Bit().constData());
Logger::Info("Country %s was selected\n", country.c_str());
-
+
UpdatedConfig *cfg = UpdatedConfig::CurrentConfig();
vector<string> states = cfg->GetStates(country);
if (states.empty())
@@ -160,11 +166,11 @@ void ProxyDialog::StateActivated(int index)
{
return;
}
-
+
string country(countryBox->currentText().toLocal8Bit().constData());
string state(stateBox->currentText().toLocal8Bit().constData());
Logger::Info("State %s was selected\n", state.c_str());
-
+
UpdatedConfig *cfg = UpdatedConfig::CurrentConfig();
vector<string> cities = cfg->GetCities(country, state);
cityBox->clear();
@@ -185,9 +191,9 @@ void ProxyDialog::CityActivated(int index)
{
return;
}
-
+
vector<string> proxies;
- UpdatedConfig *cfg = UpdatedConfig::CurrentConfig();
+ UpdatedConfig *cfg = UpdatedConfig::CurrentConfig();
string country(countryBox->currentText().toLocal8Bit().constData());
string city(cityBox->currentText().toLocal8Bit().constData());
if (stateBox->isVisible())
@@ -199,7 +205,7 @@ void ProxyDialog::CityActivated(int index)
{
proxies = cfg->GetProxies(country, city);
}
-
+
/* delete existing buttons */
if (topPanelLayout->count() != 0)
{
@@ -210,7 +216,7 @@ void ProxyDialog::CityActivated(int index)
delete child->widget();
}
}
-
+
Logger::Trace("Adding new buttons\n");
for (unsigned i = 0; i < proxies.size(); i++)
{
diff --git a/client/Dialog.h b/client/Dialog.h
index b2d21d3..e3be343 100644
--- a/client/Dialog.h
+++ b/client/Dialog.h
@@ -29,7 +29,7 @@ private slots:
void CountryActivated(int index);
void StateActivated(int index);
void CityActivated(int index);
-
+
void StaticToggle(bool toggle);
void StaticClick();
private:
@@ -43,4 +43,4 @@ private:
QLabel *bottomLabel;
};
-#endif \ No newline at end of file
+#endif
diff --git a/client/Proxifier.cpp b/client/Proxifier.cpp
new file mode 100644
index 0000000..5ef213d
--- /dev/null
+++ b/client/Proxifier.cpp
@@ -0,0 +1,310 @@
+
+#include <QtCore>
+#include <QtXml>
+#include "Logger.h"
+#include "Proxifier.h"
+
+
+Proxifier* Proxifier::instance = NULL;
+
+
+Proxifier::Proxy::Proxy(): port(0), id(0), option(0), emptyAuth(true)
+{
+}
+
+
+Proxifier::Chain::Chain(): id(0)
+{
+}
+
+
+Proxifier::Rule::Rule(): isEnabled(false), id(0)
+{
+}
+
+
+/**
+ * Proxifier class
+ */
+Proxifier* Proxifier::GetInstance()
+{
+ if (instance == NULL)
+ {
+ instance = new Proxifier;
+ }
+ return instance;
+}
+
+Proxifier::Proxifier(): valid(false)
+{
+ Update();
+}
+
+bool Proxifier::IsValid()
+{
+ return valid;
+}
+
+void Proxifier::Update()
+{
+ valid = false;
+ configDom = new QDomDocument("config");
+ QFile config("Default.ppx");
+ if (!config.open(QIODevice::ReadOnly))
+ {
+ Logger::Error("Can't open Proxifier configuration file\n");
+ return;
+ }
+ if (!configDom->setContent(&config))
+ {
+ Logger::Fatal("Invalid Proxifier configuration file!");
+ return;
+ }
+
+ QDomElement root = configDom->documentElement();
+ if (root.tagName() != "ProxifierProfile")
+ {
+ Logger::Fatal("Invalid Proxifier configuration file!");
+ return;
+ }
+ QDomElement options = root.firstChildElement("Options");
+ /**
+ * @todo process Options if needed
+ */
+
+ // parse proxy list
+ if (!UpdateProxyList(root))
+ {
+ Logger::Fatal("Invalid Proxifier configuration file!");
+ return;
+ }
+ // parse chain list
+ if (!UpdateChainList(root))
+ {
+ Logger::Fatal("Invalid Proxifier configuration file!");
+ return;
+ }
+ // parse rule list
+ if (!UpdateRuleList(root))
+ {
+ Logger::Fatal("Invalid Proxifier configuration file!");
+ return;
+ }
+
+ valid = true;
+}
+
+bool Proxifier::UpdateProxyList(QDomElement& root)
+{
+ Logger::Trace("Processing Proxifier proxy list\n");
+ QDomElement proxyListElem = root.firstChildElement("ProxyList");
+ if (proxyListElem.isNull())
+ {
+ return false;
+ }
+
+ proxyList.clear();
+ QDomElement proxy = proxyListElem.firstChildElement("Proxy");
+ while (!proxy.isNull())
+ {
+ bool ok = true; // used when converting values to int
+ Proxy proxyRecord;
+
+ // check whether attributes are present
+ if (! (proxy.hasAttribute("id") && proxy.hasAttribute("type")))
+ {
+ Logger::Error("Invalid Proxy entry\n");
+ proxy = proxy.nextSiblingElement("Proxy");
+ continue;
+ }
+ // proxy id
+ QString id = proxy.attribute("id");
+ proxyRecord.id = id.toInt(&ok);
+ if (!ok)
+ {
+ Logger::Error("Invalid Proxy id\n");
+ proxy = proxy.nextSiblingElement("Proxy");
+ continue;
+ }
+ //proxy type
+ proxyRecord.type = proxy.attribute("type").toStdString();
+ // proxy address
+ QDomElement addrElem = proxy.firstChildElement("Address");
+ proxyRecord.host = addrElem.text().toStdString();
+ // proxy port
+ QDomElement portElem = proxy.firstChildElement("Port");
+ QString port = portElem.text();
+ proxyRecord.port = port.toShort(&ok);
+ if (!ok)
+ {
+ Logger::Error("Invalid Proxy port\n");
+ proxy = proxy.nextSiblingElement("Proxy");
+ continue;
+ }
+ // proxy options
+ QDomElement optElem = proxy.firstChildElement("Options");
+ QString opt = optElem.text();
+ proxyRecord.option = opt.toInt(&ok);
+ if (!ok)
+ {
+ Logger::Error("Invalid Proxy option\n");
+ continue;
+ }
+ // auth section
+ QDomElement authElem = proxy.firstChildElement("Authentication");
+ if (!authElem.isNull())
+ {
+ if (! authElem.hasChildNodes())
+ {
+ // in case if "NTLM + userLogin" = selfclosing auth tag
+ proxyRecord.emptyAuth = true;
+ }
+ else
+ {
+ // username
+ QDomElement userElem = authElem.firstChildElement("Username");
+ proxyRecord.login = userElem.text().toStdString();
+ // pass
+ QDomElement passElem = authElem.firstChildElement("Password");
+ proxyRecord.password = passElem.text().toStdString();
+ }
+ }
+ else
+ {
+ Logger::Trace("Auth section is empty\n");
+ }
+ Logger::Trace("Found proxy in proxifier config: id=%d\n", proxyRecord.id);
+ proxyList.push_back(proxyRecord);
+
+ // process next proxy element
+ proxy = proxy.nextSiblingElement("Proxy");
+ }
+ return true;
+}
+
+bool Proxifier::UpdateChainList(QDomElement& root)
+{
+ Logger::Trace("Processing Proxifier chain list\n");
+ QDomElement chainListElem = root.firstChildElement("ChainList");
+ if (chainListElem.isNull())
+ {
+ return false;
+ }
+
+ chainList.clear();
+ QDomElement chain = chainListElem.firstChildElement("Chain");
+ while (!chain.isNull())
+ {
+ bool ok;
+ Chain chainRecord;
+
+ // chain id
+ if (!chain.hasAttribute("id"))
+ {
+ Logger::Error("Invalid Chain entry\n");
+ chain = chain.nextSiblingElement("Chain");
+ continue;
+ }
+ QString id = chain.attribute("id");
+ chainRecord.id = id.toInt(&ok);
+ if (!ok)
+ {
+ Logger::Error("Invalid Chain id\n");
+ chain = chain.nextSiblingElement("Chain");
+ continue;
+ }
+ // chain name
+ QDomElement nameElem = chain.firstChildElement("Name");
+ chainRecord.name = nameElem.text().toStdString();
+ //chain proxies
+ QDomElement proxyElem = chain.firstChildElement("Proxy");
+ while (!proxyElem.isNull())
+ {
+ Logger::Trace("Processing Chain proxy\n");
+ bool isEnabled = false;
+ QString enAttr = proxyElem.attribute("enabled");
+ if (enAttr == "true")
+ {
+ isEnabled = true;
+ }
+ QString idTxt = proxyElem.text();
+ int id = idTxt.toInt();
+ chainRecord.proxies[id] = isEnabled;
+ // proceed to the next chain proxy
+ proxyElem = proxyElem.nextSiblingElement("Proxy");
+ }
+ Logger::Trace("Found chain in proxifier config: id=%d\n", chainRecord.id);
+ chainList.push_back(chainRecord);
+
+ // proceed to the next chain
+ chain = chain.nextSiblingElement("Chain");
+ }
+ return true;
+}
+
+bool Proxifier::UpdateRuleList(QDomElement& root)
+{
+ Logger::Trace("Processing Proxifier rule list\n");
+ QDomElement ruleListElem = root.firstChildElement("RuleList");
+ if (ruleListElem.isNull())
+ {
+ return false;
+ }
+
+ ruleList.clear();
+ QDomElement rule = ruleListElem.firstChildElement("Rule");
+ while (!rule.isNull())
+ {
+ Rule ruleRecord;
+
+ // rule enabled attr
+ if (!rule.hasAttribute("enabled"))
+ {
+ Logger::Error("Invalid Rule entry\n");
+ rule = rule.nextSiblingElement("Rule");
+ continue;
+ }
+ QString enAttr = rule.attribute("enabled");
+ if (enAttr == "true")
+ {
+ ruleRecord.isEnabled = true;
+ }
+ // rule name
+ QDomElement nameElem = rule.firstChildElement("Name");
+ ruleRecord.name = nameElem.text().toStdString();
+ // rule applications
+ QDomElement appsElem = rule.firstChildElement("Applications");
+ if (!appsElem.isNull())
+ {
+ ruleRecord.apps = appsElem.text().toStdString();
+ }
+ // rule targets
+ QDomElement targetsElem = rule.firstChildElement("Targets");
+ if (!targetsElem.isNull())
+ {
+ ruleRecord.targets = targetsElem.text().toStdString();
+ }
+ // rule ports
+ QDomElement portsElem = rule.firstChildElement("Ports");
+ if (!portsElem.isNull())
+ {
+ ruleRecord.ports = targetsElem.text().toStdString();
+ }
+ // rule action
+ QDomElement actionElem = rule.firstChildElement("Action");
+ QString actionTxt = actionElem.attribute("type");
+ if ((actionTxt == "Chain") || (actionTxt == "Proxy"))
+ {
+ QString idTxt = actionElem.text();
+ ruleRecord.id = idTxt.toInt();
+ }
+ ruleRecord.action = actionTxt.toStdString();
+ Logger::Trace("Found rule in proxifier config: name=%s\n", ruleRecord.name.c_str());
+ ruleList.push_back(ruleRecord);
+
+ // proceed to the next rule
+ rule = rule.nextSiblingElement("Rule");
+ }
+
+ return true;
+}
diff --git a/client/Proxifier.h b/client/Proxifier.h
new file mode 100644
index 0000000..37ea3fd
--- /dev/null
+++ b/client/Proxifier.h
@@ -0,0 +1,114 @@
+
+
+#ifndef PROXIFIER_CONFIG
+#define PROXIFIER_CONFIG
+
+#include <vector>
+#include <string>
+#include <QDomElement>
+
+using namespace std;
+
+
+class QDomDocument;
+
+class Proxifier
+{
+public:
+ /**
+ * @brief class representing Proxifier's proxy setting
+ */
+ class Proxy
+ {
+ public:
+ string login;
+ string password;
+ string host;
+ string type;
+ short port;
+ // proxifier-specific fields
+ int id;
+ short option;
+ bool emptyAuth;
+
+ Proxy();
+ };
+
+ /**
+ * @brief class representing Proxifier's proxy chain
+ */
+ class Chain
+ {
+ public:
+ /**
+ * @brief chain id
+ */
+ int id;
+ /**
+ * @brief chain name
+ */
+ string name;
+ /**
+ * @brief associative array of proxies in the chain - [id: isEnabled]
+ */
+ map<int, bool> proxies;
+
+ Chain();
+ };
+
+ class Rule
+ {
+ public:
+ /**
+ * @brief indicates if the rule is enabled
+ */
+ bool isEnabled;
+ /**
+ * @brief rule name
+ */
+ string name;
+ /**
+ * @brief list of applications the rule affects
+ */
+ string apps;
+ /**
+ * @brief rule targets (list of hosts separeted w ';')
+ */
+ string targets;
+ /**
+ * @brief rule ports (e.g.: 80; 8000-9000; 8080)
+ */
+ string ports;
+ /**
+ * @brief rule action (one of: 'Direct', 'Block', 'Chain', 'Proxy')
+ */
+ string action;
+ /**
+ * @brief action parameter (applicable only to 'Chain' and 'Proxy' actions)
+ */
+ int id;
+
+ Rule();
+ };
+
+
+ static Proxifier* GetInstance();
+ bool IsValid();
+ void Update();
+
+private:
+ static Proxifier *instance;
+
+ bool valid;
+ QDomDocument *configDom;
+ vector<Proxy> proxyList;
+ vector<Chain> chainList;
+ vector<Rule> ruleList;
+
+ Proxifier();
+ bool UpdateProxyList(QDomElement& root);
+ bool UpdateChainList(QDomElement& root);
+ bool UpdateRuleList(QDomElement& root);
+};
+
+#endif
diff --git a/client/Proxy.h b/client/Proxy.h
index 368f2b8..a718353 100644
--- a/client/Proxy.h
+++ b/client/Proxy.h
@@ -10,6 +10,7 @@ public:
std::string login;
std::string password;
std::string host;
+ std::string type;
short port;
Proxy(): port(0) {}
diff --git a/client/UpdatedConfig.cpp b/client/UpdatedConfig.cpp
index d5b4177..6873d30 100644
--- a/client/UpdatedConfig.cpp
+++ b/client/UpdatedConfig.cpp
@@ -5,7 +5,7 @@
UpdatedConfig* UpdatedConfig::self = NULL;
-UpdatedConfig *UpdatedConfig::CurrentConfig()
+UpdatedConfig* UpdatedConfig::CurrentConfig()
{
if (self == NULL)
self = new UpdatedConfig();
diff --git a/client/client.pro b/client/client.pro
index ca6abf8..cfdc184 100644
--- a/client/client.pro
+++ b/client/client.pro
@@ -5,7 +5,7 @@
QMAKE_CXXFLAGS_DEBUG += -DDEBUG -g3 -ggdb -O0
CONFIG += qt debug console warn_on
-QT = core gui network
+QT = core gui network xml
TEMPLATE = app
TARGET = client
@@ -23,7 +23,8 @@ HEADERS += client.h \
SslClient.h \
FileOpThread.h \
DownloadClient.h \
- Utility.h
+ Utility.h \
+ Proxifier.h
SOURCES += Dialog.cpp \
main.cpp \
@@ -35,7 +36,8 @@ SOURCES += Dialog.cpp \
SslClient.cpp \
FileOpThread.cpp \
DownloadClient.cpp \
- Utility.cpp
+ Utility.cpp \
+ Proxifier.cpp
OTHER_FILES +=