diff --git a/src/controller/controller.cpp b/src/controller/controller.cpp index 2a606cb0..7fdf3a8a 100644 --- a/src/controller/controller.cpp +++ b/src/controller/controller.cpp @@ -301,6 +301,7 @@ int main_loop(int argc, char **argv){ Controller::maxConnsPerIP = Controller::conf.getInteger("maxconnsperip"); Controller::Storage["config"]["prometheus"] = Controller::conf.getString("prometheus"); Controller::Storage["config"]["accesslog"] = Controller::conf.getString("accesslog"); + Controller::normalizeTrustedProxies(Controller::Storage["config"]["trustedproxy"]); Controller::prometheus = Controller::Storage["config"]["prometheus"].asStringRef(); Controller::accesslog = Controller::Storage["config"]["accesslog"].asStringRef(); Controller::writeConfig(); diff --git a/src/controller/controller_api.cpp b/src/controller/controller_api.cpp index e6e027da..8347a0f4 100644 --- a/src/controller/controller_api.cpp +++ b/src/controller/controller_api.cpp @@ -528,6 +528,10 @@ void Controller::handleAPICommands(JSON::Value & Request, JSON::Value & Response out["protocols"] = in["protocols"]; removeDuplicateProtocols(); } + if (in.isMember("trustedproxy")){ + out["trustedproxy"] = in["trustedproxy"]; + Controller::normalizeTrustedProxies(out["trustedproxy"]); + } if (in.isMember("controller")){ out["controller"] = in["controller"]; } diff --git a/src/controller/controller_storage.cpp b/src/controller/controller_storage.cpp index 328eed0e..3665a34b 100644 --- a/src/controller/controller_storage.cpp +++ b/src/controller/controller_storage.cpp @@ -101,6 +101,33 @@ namespace Controller{ } } + void normalizeTrustedProxies(JSON::Value & tp){ + //First normalize to arrays + if (!tp.isArray()){tp.append(tp.asString());} + //Now, wipe any empty entries, and convert spaces to array entries + std::set n; + jsonForEach(tp, jit){ + if (!jit->isString()){*jit = jit->asString();} + if (jit->asStringRef().find(' ') == std::string::npos){ + n.insert(jit->asStringRef()); + continue; + } + std::string tmp = jit->asStringRef(); + while (tmp.find(' ') != std::string::npos){ + size_t p = tmp.find(' '); + n.insert(tmp.substr(0, p)); + tmp.erase(0, p+1); + } + if (tmp.size()){n.insert(tmp);} + } + n.erase(""); + //Re-write the entire array, which is now normalized + tp.shrink(0); + for (std::set::iterator it = n.begin(); it != n.end(); ++it){ + tp.append(*it); + } + } + ///\brief Write contents to Filename ///\param Filename The full path of the file to write to. ///\param contents The data to be written to the file. @@ -239,8 +266,20 @@ namespace Controller{ void writeProtocols(){ static std::string proxy_written; - if (proxy_written != Storage["config"]["trustedproxy"].asStringRef()){ - proxy_written = Storage["config"]["trustedproxy"].asStringRef(); + std::string tmpProxy; + if (Storage["config"]["trustedproxy"].isArray()){ + jsonForEachConst(Storage["config"]["trustedproxy"], jit){ + if (tmpProxy.size()){ + tmpProxy += " "+jit->asString(); + }else{ + tmpProxy = jit->asString(); + } + } + }else{ + tmpProxy = Storage["config"]["trustedproxy"].asString(); + } + if (proxy_written != tmpProxy){ + proxy_written = tmpProxy; static IPC::sharedPage mistProxOut(SHM_PROXY, proxy_written.size()+100, true, false); mistProxOut.close(); mistProxOut.init(SHM_PROXY, proxy_written.size()+100, true, false); diff --git a/src/controller/controller_storage.h b/src/controller/controller_storage.h index 15cefec0..14e29f52 100644 --- a/src/controller/controller_storage.h +++ b/src/controller/controller_storage.h @@ -25,6 +25,10 @@ namespace Controller { void Log(const std::string & kind, const std::string & message, const std::string & stream = "", bool noWriteToLog = false); void logAccess(const std::string & sessId, const std::string & strm, const std::string & conn, const std::string & host, uint64_t duration, uint64_t up, uint64_t down, const std::string & tags); + + void normalizeTrustedProxies(JSON::Value & tp); + + /// Write contents to Filename. bool WriteFile(std::string Filename, std::string contents); void writeConfigToDisk(); diff --git a/src/output/output_http.cpp b/src/output/output_http.cpp index 24321d8e..b118be84 100644 --- a/src/output/output_http.cpp +++ b/src/output/output_http.cpp @@ -448,8 +448,7 @@ namespace Mist { bool HTTPOutput::isTrustedProxy(const std::string & ip){ static std::set trustedProxies; if (!trustedProxies.size()){ - trustedProxies.insert("::1"); - trustedProxies.insert("127.0.0.1"); + trustedProxies.insert("localhost"); IPC::sharedPage rPage(SHM_PROXY, 0, false, false); if (rPage){ @@ -467,11 +466,11 @@ namespace Mist { } } } - //Make sure to also check for IPv6 addresses - if (ip.substr(0, 7) == "::ffff:" && trustedProxies.count(ip.substr(7))){ - return true; + std::string binIp = Socket::getBinForms(ip); + for (std::set::iterator it = trustedProxies.begin(); it != trustedProxies.end(); ++it){ + if (Socket::isBinAddress(binIp, *it)){return true;} } - return trustedProxies.count(ip) > 0; + return false; } /*LTS-END*/