diff --git a/builder b/builder index ce64ed80..c66dee9b 160000 --- a/builder +++ b/builder @@ -1 +1 @@ -Subproject commit ce64ed8015eb5962f87567e41f1b9aaca540c05a +Subproject commit c66dee9bfa5a676ebd8543c7c111a93242043db6 diff --git a/builder-support/specs/wforce.spec b/builder-support/specs/wforce.spec index 4af4b58a..e7636fe3 100644 --- a/builder-support/specs/wforce.spec +++ b/builder-support/specs/wforce.spec @@ -23,7 +23,7 @@ Summary: Weakforce daemon for detecting brute force attacts Name: wforce Version: %{getenv:BUILDER_RPM_VERSION} -Release: %{getenv:BUILDER_RPM_RELEASE} +Release: %{getenv:BUILDER_RPM_RELEASE}%{?dist} License: GPLv3 Group: System Environment/Daemons URL: http://www.open-xchange.com/ diff --git a/common/common-lua.cc b/common/common-lua.cc index 2b1e7a6d..fe024c42 100644 --- a/common/common-lua.cc +++ b/common/common-lua.cc @@ -340,56 +340,11 @@ void setupCommonLua(bool client, if (!multi_lua) { c_lua.writeFunction("makeKey", []() { - g_outputBuffer="setKey("+newKey()+")\n"; - }); - } - else { - c_lua.writeFunction("makeKey", []() { }); - } - - if (!multi_lua) { - c_lua.writeFunction("setKey", [](const std::string& key) { - string newkey; - if(B64Decode(key, newkey) < 0) { - g_outputBuffer=string("Unable to decode ")+key+" as Base64"; - errlog("%s", g_outputBuffer); - } - else - g_key = newkey; - }); - } - else { - c_lua.writeFunction("setKey", [](const std::string& key) { }); - } - - if (!multi_lua) { - c_lua.writeFunction("testCrypto", [](const std::string& testmsg) - { - try { - SodiumNonce sn, sn2; - sn.init(); - sn2=sn; - string encrypted = sodEncryptSym(testmsg, g_key, sn); - string decrypted = sodDecryptSym(encrypted, g_key, sn2); - - sn.increment(); - sn2.increment(); - - encrypted = sodEncryptSym(testmsg, g_key, sn); - decrypted = sodDecryptSym(encrypted, g_key, sn2); - - if(testmsg == decrypted) - g_outputBuffer="Everything is ok!\n"; - else - g_outputBuffer="Crypto failed..\n"; - - } - catch(...) { - g_outputBuffer="Crypto failed..\n"; - }}); + g_outputBuffer="setKey("+newKey()+")\n"; + }); } else { - c_lua.writeFunction("testCrypto", [](const string& testmsg) {}); + c_lua.writeFunction("makeKey", []() { }); } #ifdef HAVE_GEOIP diff --git a/common/common-lua.hh b/common/common-lua.hh index f2f9a1d4..64a5d7da 100644 --- a/common/common-lua.hh +++ b/common/common-lua.hh @@ -52,8 +52,6 @@ extern WebHookDB g_custom_webhook_db; extern int g_num_luastates; -extern std::string g_key; // in theory needs locking - void setupCommonLua(bool client, bool multi_lua, LuaContext& c_lua, diff --git a/docs/manpages/trackalert.conf.5.md b/docs/manpages/trackalert.conf.5.md index c1130581..5b572884 100644 --- a/docs/manpages/trackalert.conf.5.md +++ b/docs/manpages/trackalert.conf.5.md @@ -64,9 +64,13 @@ cannot be called inside the report or background functions: * setKey(\) - Use the specified key for authenticating connections from siblings. The key must be generated with makeKey() from the console. See *trackalert(1)* for instructions on - running a console client. For example: - - setKey("Ay9KXgU3g4ygK+qWT0Ut4gH8PPz02gbtPeXWPdjD0HE=") + running a console client. + Returns false if the key could not be set (e.g. invalid base64). + For example: + + if not setKey("Ay9KXgU3g4ygK+qWT0Ut4gH8PPz02gbtPeXWPdjD0HE=") + then + ... * setNumLuaStates(\) - Set the number of Lua Contexts that will be created to run report commands. Defaults to 10 diff --git a/docs/manpages/wforce.conf.5.md b/docs/manpages/wforce.conf.5.md index dfe43c84..f3075c3b 100644 --- a/docs/manpages/wforce.conf.5.md +++ b/docs/manpages/wforce.conf.5.md @@ -159,11 +159,15 @@ cannot be called inside the allow/report/reset functions: controlSocket("0.0.0.0:4004") * setKey(\) - Use the specified key for authenticating - connections from siblings. The key must be generated with makeKey() + connections from siblings. The key can be generated with makeKey() from the console. See *wforce(1)* for instructions on - running a console client. For example: - - setKey("Ay9KXgU3g4ygK+qWT0Ut4gH8PPz02gbtPeXWPdjD0HE=") + running a console client. + Returns false if the key could not be set (e.g. invalid base64). + For example: + + if not setKey("Ay9KXgU3g4ygK+qWT0Ut4gH8PPz02gbtPeXWPdjD0HE=") + then + ... * setNumLuaStates(\) - Set the number of Lua Contexts that will be created to run allow/report/reset commands. Defaults to 10 @@ -1083,4 +1087,4 @@ a Netmask. For example: # SEE ALSO wforce(1) wforce_webhook(5) - \ No newline at end of file + diff --git a/trackalert/trackalert-lua.cc b/trackalert/trackalert-lua.cc index 2c0f1167..7510b3e9 100644 --- a/trackalert/trackalert-lua.cc +++ b/trackalert/trackalert-lua.cc @@ -297,6 +297,24 @@ vector> setupLua(bool client, bool multi_lua, c_lua.writeFunction("showVersion", []() { }); } + if (!multi_lua) { + c_lua.writeFunction("setKey", [](const std::string& key) -> bool { + string newkey; + if(B64Decode(key, newkey) < 0) { + g_outputBuffer=string("Unable to decode ")+key+" as Base64"; + errlog("%s", g_outputBuffer); + return false; + } + else { + g_key = newkey; + return true; + } + }); + } + else { + c_lua.writeFunction("setKey", [](const std::string& key) { }); + } + if (!multi_lua) { c_lua.writeFunction("testCrypto", [](string testmsg) { diff --git a/wforce/wforce-lua.cc b/wforce/wforce-lua.cc index 85d22143..33c92ffe 100644 --- a/wforce/wforce-lua.cc +++ b/wforce/wforce-lua.cc @@ -1002,6 +1002,24 @@ vector> setupLua(bool client, bool multi_lua, LuaConte c_lua.writeFunction("showVersion", []() { }); } + if (!multi_lua) { + c_lua.writeFunction("setKey", [](const std::string& key) -> bool { + string newkey; + if(B64Decode(key, newkey) < 0) { + g_outputBuffer=string("Unable to decode ")+key+" as Base64"; + errlog("%s", g_outputBuffer); + return false; + } + else { + g_replication.setEncryptionKey(newkey); + return true; + } + }); + } + else { + c_lua.writeFunction("setKey", [](const std::string& key) { }); + } + if (!multi_lua) { c_lua.writeFunction("testCrypto", [](string testmsg) { @@ -1009,14 +1027,15 @@ vector> setupLua(bool client, bool multi_lua, LuaConte SodiumNonce sn, sn2; sn.init(); sn2=sn; - string encrypted = sodEncryptSym(testmsg, g_key, sn); - string decrypted = sodDecryptSym(encrypted, g_key, sn2); + std::string key = g_replication.getEncryptionKey(); + string encrypted = sodEncryptSym(testmsg, key, sn); + string decrypted = sodDecryptSym(encrypted, key, sn2); sn.increment(); sn2.increment(); - encrypted = sodEncryptSym(testmsg, g_key, sn); - decrypted = sodDecryptSym(encrypted, g_key, sn2); + encrypted = sodEncryptSym(testmsg, key, sn); + decrypted = sodDecryptSym(encrypted, key, sn2); if(testmsg == decrypted) g_outputBuffer="Everything is ok!\n"; diff --git a/wforce/wforce-replication.cc b/wforce/wforce-replication.cc index c0c7a9bb..7a100fe6 100644 --- a/wforce/wforce-replication.cc +++ b/wforce/wforce-replication.cc @@ -22,7 +22,6 @@ #include "config.h" #include -#include "wforce.hh" #include "wforce_ns.hh" #include "sstuff.hh" #include "misc.hh" @@ -49,7 +48,7 @@ void WforceReplication::encryptMsg(const std::string& msg, std::string& packet) { std::lock_guard lock(d_sod_mutx); packet=d_sodnonce.toString(); - packet+=sodEncryptSym(msg, g_key, d_sodnonce); + packet+=sodEncryptSym(msg, d_key, d_sodnonce); } void WforceReplication::encryptMsgWithKey(const std::string& msg, std::string& packet, const std::string& key, SodiumNonce& nonce, std::mutex& mutex) @@ -70,7 +69,7 @@ bool WforceReplication::decryptMsg(const char* buf, size_t len, std::string& msg memcpy((char*)&nonce, buf, crypto_secretbox_NONCEBYTES); string packet(buf + crypto_secretbox_NONCEBYTES, buf+len); try { - msg=sodDecryptSym(packet, g_key, nonce); + msg=sodDecryptSym(packet, d_key, nonce); } catch (std::runtime_error& e) { errlog("Could not decrypt replication operation: %s", e.what()); @@ -90,7 +89,7 @@ void WforceReplication::replicateOperation(const ReplicationOperation& rep_op) for(auto& s : *siblings) { bool use_sibling_packet = false; if (s->d_has_key) { - if (s->d_key != g_key) { + if (s->d_key != d_key) { encryptMsgWithKey(msg, sibling_packet, s->d_key, s->d_nonce, s->mutx); use_sibling_packet = true; } diff --git a/wforce/wforce-replication.hh b/wforce/wforce-replication.hh index e7f11b62..167015a3 100644 --- a/wforce/wforce-replication.hh +++ b/wforce/wforce-replication.hh @@ -22,7 +22,6 @@ #pragma once -#include "luastate.hh" #include "sholder.hh" #include "iputils.hh" #include "sodcrypto.hh" @@ -35,22 +34,24 @@ public: } virtual ~WforceReplication() = default; - void receiveReplicationOperationsTCP(const ComboAddress& local); - void receiveReplicationOperations(const ComboAddress& local); - void startReplicationWorkerThreads(); - void encryptMsg(const std::string& msg, std::string& packet); - void encryptMsgWithKey(const std::string& msg, std::string& packet, const std::string& key, SodiumNonce& nonce, + virtual void receiveReplicationOperationsTCP(const ComboAddress& local); + virtual void receiveReplicationOperations(const ComboAddress& local); + + virtual void startReplicationWorkerThreads(); + virtual void encryptMsg(const std::string& msg, std::string& packet); + virtual void encryptMsgWithKey(const std::string& msg, std::string& packet, const std::string& key, SodiumNonce& nonce, std::mutex& mutex); - bool decryptMsg(const char* buf, size_t len, std::string& msg); + virtual bool decryptMsg(const char* buf, size_t len, std::string& msg); void setMaxSiblingRecvQueueSize(size_t size); void setNumSiblingThreads(unsigned int num_threads) { d_num_sibling_threads = num_threads; } GlobalStateHolder>>& getSiblings() { return d_siblings; } - void replicateOperation(const ReplicationOperation& rep_op); + virtual void replicateOperation(const ReplicationOperation& rep_op); + void setEncryptionKey(const std::string& key) { d_key = key; } + std::string getEncryptionKey() const { return d_key; } protected: - bool checkConnFromSibling(const ComboAddress& remote, shared_ptr& recv_sibling); - void parseTCPReplication(std::shared_ptr sockp, const ComboAddress& remote, std::shared_ptr recv_sibling); - void parseReceivedReplicationMsg(const std::string& msg, const ComboAddress& remote, std::shared_ptr recv_sibling); -private: + virtual bool checkConnFromSibling(const ComboAddress& remote, shared_ptr& recv_sibling); + virtual void parseTCPReplication(std::shared_ptr sockp, const ComboAddress& remote, std::shared_ptr recv_sibling); + virtual void parseReceivedReplicationMsg(const std::string& msg, const ComboAddress& remote, std::shared_ptr recv_sibling); struct SiblingQueueItem { std::string msg; ComboAddress remote; @@ -58,6 +59,7 @@ private: }; GlobalStateHolder>> d_siblings; SodiumNonce d_sodnonce; + std::string d_key; // The default key to use if no per-sibling key std::mutex d_sod_mutx; std::mutex d_sibling_queue_mutex; std::queue d_sibling_queue; diff --git a/wforce/wforce-sibling.cc b/wforce/wforce-sibling.cc index eb072c97..d06ae20f 100644 --- a/wforce/wforce-sibling.cc +++ b/wforce/wforce-sibling.cc @@ -103,6 +103,7 @@ Sibling::Sibling(const ComboAddress& ca, if (!d_key.empty()) { d_has_key = true; } + d_nonce.init(); if (proto != Protocol::NONE) { { std::lock_guard lock(mutx); diff --git a/wforce/wforce-web.cc b/wforce/wforce-web.cc index fde0a1e5..cf1d36dc 100644 --- a/wforce/wforce-web.cc +++ b/wforce/wforce-web.cc @@ -239,7 +239,7 @@ void parseSyncCmd(const YaHTTP::Request& req, YaHTTP::Response& resp, const std: encryption_key = msg["encryption_key"].string_value(); } else { - encryption_key = g_key; + encryption_key = g_replication.getEncryptionKey(); } thread t(syncDBThread, replication_ca, callback_url, callback_pw, encryption_key); t.detach(); @@ -398,7 +398,7 @@ void parseSetSiblingsCmd(const YaHTTP::Request& req, YaHTTP::Response& resp, con encryption_key = i["encryption_key"].string_value(); } else { - encryption_key = Base64Encode(g_key); + encryption_key = Base64Encode(g_replication.getEncryptionKey()); } Sibling::Protocol proto = Sibling::Protocol::UDP; diff --git a/wforce/wforce.cc b/wforce/wforce.cc index 637b0e90..e14786dd 100644 --- a/wforce/wforce.cc +++ b/wforce/wforce.cc @@ -155,8 +155,6 @@ double getDoubleTime() return 1.0*now.tv_sec + now.tv_usec/1000000.0; } -string g_key; - void controlClientThread(int fd, ComboAddress client) try { @@ -167,7 +165,8 @@ try writen2(fd, (char*)ours.value, sizeof(ours.value)); readingNonce.merge(ours, theirs); writingNonce.merge(theirs, ours); - + std::string key = g_replication.getEncryptionKey(); + setThreadName("wf/ctrl-client"); sock.setKeepAlive(); @@ -181,7 +180,7 @@ try string line(msg, len); try { - line = sodDecryptSym(line, g_key, readingNonce); + line = sodDecryptSym(line, key, readingNonce); } catch (std::runtime_error& e) { errlog("Could not decrypt client command: %s", e.what()); @@ -237,7 +236,7 @@ try catch(const LuaContext::SyntaxErrorException& e) { response = "Error: " + string(e.what()) + ": "; } - response = sodEncryptSym(response, g_key, writingNonce); + response = sodEncryptSym(response, key, writingNonce); putMsgLen(fd, response.length()); writen2(fd, response.c_str(), (uint16_t)response.length()); } @@ -288,10 +287,12 @@ void doClient(ComboAddress server, const std::string& command) readn2(fd, (char*)theirs.value, sizeof(theirs.value)); readingNonce.merge(ours, theirs); writingNonce.merge(theirs, ours); - + + std::string key = g_replication.getEncryptionKey(); + if(!command.empty()) { string response; - string msg=sodEncryptSym(command, g_key, writingNonce); + string msg=sodEncryptSym(command, key, writingNonce); putMsgLen(fd, msg.length()); writen2(fd, msg); uint16_t len{0}; @@ -299,7 +300,7 @@ void doClient(ComboAddress server, const std::string& command) char resp[len]; readn2(fd, resp, len); msg.assign(resp, len); - msg=sodDecryptSym(msg, g_key, readingNonce); + msg=sodDecryptSym(msg, key, readingNonce); cout< my_dbmap; { @@ -675,6 +677,8 @@ unsigned int checkHostUptime(const std::string& url, const std::string& password void checkSyncHosts() { bool found_sync_host = false; + std::string key = g_replication.getEncryptionKey(); + for (auto i : g_sync_data.sync_hosts) { std::string sync_host = i.first; std::string password = i.second; @@ -689,7 +693,7 @@ void checkSyncHosts() {"replication_port", ntohs(g_sync_data.sibling_listen_addr.sin4.sin_port)}, {"callback_url", callback_url}, {"callback_auth_pw", g_sync_data.webserver_password}, - {"encryption_key", g_key}}; + {"encryption_key", key}}; Json msg = callWforcePostURL(sync_url, password, post_json.dump(), err); if (!msg.is_null()) { if (!msg["status"].is_null()) { diff --git a/wforce/wforce.hh b/wforce/wforce.hh index 3c6cd15b..19f1b44a 100644 --- a/wforce/wforce.hh +++ b/wforce/wforce.hh @@ -72,8 +72,6 @@ extern GlobalStateHolder g_ACL; extern ComboAddress g_sibling_listen; extern ComboAddress g_serverControl; // not changed during runtime -extern std::string g_key; // in theory needs locking - struct dnsheader; void controlThread(int fd, ComboAddress local);