#include #include #include #include #include #include "Config.h" #include "SslClient.h" using namespace std; /* * Firewall Entry class */ void Config::FirewallEntry::Parse(string entry) { Logger::Trace("Parsing firewall string: %s\n", entry.c_str()); size_t lp1 = 0, lp2 = 0; //extract action part lp2 = entry.find(" ", lp1); string action = entry.substr(lp1, lp2-lp1); if (action.compare("block") == 0) { block = true; } else if (action.compare("allow") == 0) { block = false; } else { Logger::Error("Unknown firewall action! Skipping.\n"); return; } //extract host part lp1 = lp2 + 1; host.clear(); host = entry.substr(lp1); } /* * Config class */ Config::Config(): StaticProxySpeedLow(50) { Logger::Info("Parsing config.cfg to determine initial configuration\n"); QString configPath = this_app->applicationDirPath()+ "/config.cfg"; ifstream configFile(configPath.toLocal8Bit().data(), std::ios::in); if (!configFile) { Logger::Fatal("Can't open file: config.cfg\n"); return; } configFile.seekg (0, ios::end); int length = configFile.tellg(); configFile.seekg (0, ios::beg); char *buffer = new char [length]; configFile.read (buffer, length); configFile.close(); string config = buffer; ParseConfig(config); delete[] buffer; } void Config::AcquireConfig() { /* reset existing values */ genericProxy.clear(); staticProxy.clear(); /* read new values */ ReadGenericProxy(); ReadStaticProxy(); } vector Config::GetCountries() { vector countries; for (unsigned i = 0; i < genericProxy.size(); i++) { countries.push_back(genericProxy[i].country); } sort(countries.begin(), countries.end()); vector::iterator end = unique(countries.begin(), countries.end()); countries.resize(end - countries.begin()); return countries; } vector Config::GetStates(string &country) { vector states; for (unsigned i = 0; i < genericProxy.size(); i++) { if ((genericProxy[i].state != "-") && (genericProxy[i].country == country)) { states.push_back(genericProxy[i].state); } } if (!states.empty()) { sort(states.begin(), states.end()); vector::iterator end = unique(states.begin(), states.end()); states.resize(end - states.begin()); } return states; } vector Config::GetCities(string &country) { string defState = "-"; return GetCities(country, defState); } vector Config::GetCities(string &country, string &state) { vector cities; for (unsigned i = 0; i < genericProxy.size(); i++) { if ((genericProxy[i].state == state) && (genericProxy[i].country == country)) { cities.push_back(genericProxy[i].city); } } sort(cities.begin(), cities.end()); vector::iterator end = unique(cities.begin(), cities.end()); cities.resize(end - cities.begin()); return cities; } vector Config::GetProxies(string &country, string &city) { string defState = "-"; return GetProxies(country, defState, city); } vector Config::GetProxies(string &country, string &state, string &city) { vector proxies; for (unsigned i = 0; i < genericProxy.size(); i++) { if ((genericProxy[i].state == state) && (genericProxy[i].country == country) && (genericProxy[i].city == city)) { proxies.push_back(genericProxy[i].host); } } sort(proxies.begin(), proxies.end()); return proxies; } vector Config::GetStaticProxyGuiLine(unsigned line) { vector staticProxyLine; for (unsigned i = 0; i < staticProxy.size(); i++) { if (staticProxy[i].position != line) staticProxyLine.push_back(staticProxy[i]); } /* sort manually using bubble sort - not too efficient, * but I suppose we're not going too sort millions of records */ for (unsigned i = 0; i < staticProxyLine.size(); i++) { for (unsigned j = 1; j < staticProxyLine.size(); j++) { if (staticProxyLine[j].speed > staticProxyLine[j-1].speed) swap(staticProxyLine[j], staticProxyLine[j-1]); } } return staticProxyLine; } unsigned Config::GetStaticProxyGuiLines() { unsigned maxLine = 0; for (unsigned i = 0; i < staticProxy.size(); i++) { if (staticProxy[i].position > maxLine) maxLine = staticProxy[i].position; } return maxLine; } void Config::ParseConfig(string data) { stringstream config(data, ios_base::in); const int str_size = 512; char str[str_size] = {0}; while (! config.eof()) { config.getline(str, str_size, ';'); config.ignore(2, '\n'); if (config.eof()) break; string entry = str; size_t eqpos = entry.find('='); if (eqpos == string::npos) { Logger::Warn("No '=' at the config line: %s\n", entry.c_str()); continue; } string key = entry.substr(0, eqpos); string value = entry.substr(eqpos+1); Logger::Trace("Found option: %s = %s\n", key.c_str(), value.c_str()); if (key.compare("config_update_interval") == 0) { updateInterval = atoi(value.c_str()); } else if (key.compare("client_update_interval") == 0) { ClientUpdateInterval = atoi(value.c_str()); } else if (key.compare("server") == 0) { /** * @todo clear list of previous servers on config update
* when server will be able to sent valid config.cfg data */ ServerEntry server(value); servers.push_back(server); } else if (key.compare("welcome_msg") == 0) { WelcomeMsg = value; } else if (key.compare("config_downloaded_msg") == 0) { ConfigLoadedMsg = value; } else if (key.compare("top_panel_text") == 0) { TopPanelText = value; } else if (key.compare("bottom_panel_text") == 0) { BottomPanelText = value; } else if (key.compare("speed_visibility") == 0) { IsSpeedVisible = false; if (value.compare("1") == 0) { IsSpeedVisible = true; } } else { Logger::Warn("Unrecognized config option: %s\n", key.c_str()); } } } void Config::ParseGenericProxies(string data) { /* clear previous proxies */ genericProxy.clear(); stringstream proxies(data, ios_base::in); const int str_size = 512; char str[str_size] = {0}; while (! proxies.eof()) { proxies.getline(str, str_size, ';'); proxies.ignore(2, '\n'); if (proxies.eof()) break; string entry = str; ProxyEntryGeneric proxy; proxy.Parse(entry); genericProxy.push_back(proxy); } } void Config::ParseStaticPorxies(string data) { /* clear previous proxies */ staticProxy.clear(); stringstream proxies(data, ios_base::in); const int str_size = 512; char str[str_size] = {0}; while (! proxies.eof()) { proxies.getline(str, str_size, ';'); proxies.ignore(2, '\n'); if (proxies.eof()) break; string entry = str; ProxyEntryStatic proxy; proxy.Parse(entry); staticProxy.push_back(proxy); } } void Config::ParseFirewalls(string data) { firewalls.clear(); stringstream rules(data, ios_base::in); const int str_size = 512; char str[str_size] = {0}; while (! rules.eof()) { rules.getline(str, str_size, ';'); rules.ignore(2, '\n'); if (rules.eof()) break; string entry = str; FirewallEntry rule; rule.Parse(entry); firewalls.push_back(rule); } } /** * @deprecated left for testing purposes, will be removed */ void Config::ReadGenericProxy() { Logger::Info("Parsing generic proxy list\n"); string filname = QCoreApplication::applicationDirPath().toStdString() + "/config/proxy_list.cfg"; ifstream proxyFile(filname.c_str(), std::ios::binary | std::ios::in); if (! proxyFile) { Logger::Error("Can't open file %s\n", filname.c_str()); return; } proxyFile.seekg (0, ios::end); int length = proxyFile.tellg(); proxyFile.seekg (0, ios::beg); char *buffer = new char [length]; proxyFile.read (buffer, length); proxyFile.close(); string proxies = buffer; ParseGenericProxies(proxies); delete[] buffer; } /** * @deprecated left for testing purposes, will be removed */ void Config::ReadStaticProxy() { Logger::Info("Parsing static proxy list\n"); string filename = QCoreApplication::applicationDirPath().toStdString() + "/config/static_proxy_list.cfg"; ifstream proxyFile(filename.c_str(), std::ios::in); if (! proxyFile) { Logger::Error("Can't open file %s\n", filename.c_str()); return; } proxyFile.seekg (0, ios::end); int length = proxyFile.tellg(); proxyFile.seekg (0, ios::beg); char *buffer = new char [length]; proxyFile.read (buffer, length); proxyFile.close(); string proxies = buffer; ParseStaticPorxies(proxies); delete[] buffer; } /*** * Nested class section */ Config::ServerEntry::ServerEntry(): host("127.0.0.1"), timeout(120), retryTimeout(60) { } Config::ServerEntry::ServerEntry(string entry) { ServerEntry(); /* processing server entry e.g.: "8.8.8.8 600 60" */ size_t start = 0, end = 0; end = entry.find(' '); host = entry.substr(start, end); start = end+1; end = entry.find(' '); timeout = atoi(entry.substr(start, end).c_str()); start = end+1; end = entry.find(' '); retryTimeout = atoi(entry.substr(start, end).c_str()); }