diff options
Diffstat (limited to 'src/murmur')
-rw-r--r-- | src/murmur/Messages.cpp | 56 | ||||
-rw-r--r-- | src/murmur/Meta.cpp | 6 | ||||
-rw-r--r-- | src/murmur/Meta.h | 3 | ||||
-rw-r--r-- | src/murmur/Server.cpp | 11 | ||||
-rw-r--r-- | src/murmur/Server.h | 3 | ||||
-rw-r--r-- | src/murmur/ServerUser.cpp | 3 | ||||
-rw-r--r-- | src/murmur/ServerUser.h | 1 |
7 files changed, 82 insertions, 1 deletions
diff --git a/src/murmur/Messages.cpp b/src/murmur/Messages.cpp index cfde87e2a..6fb23e141 100644 --- a/src/murmur/Messages.cpp +++ b/src/murmur/Messages.cpp @@ -10,6 +10,7 @@ #include "Group.h" #include "Message.h" #include "Meta.h" +#include "MumbleConstants.h" #include "Server.h" #include "ServerDB.h" #include "ServerUser.h" @@ -2165,6 +2166,61 @@ void Server::msgServerConfig(ServerUser *, MumbleProto::ServerConfig &) { void Server::msgSuggestConfig(ServerUser *, MumbleProto::SuggestConfig &) { } +void Server::msgPluginDataTransmission(ServerUser *sender, MumbleProto::PluginDataTransmission &msg) { + // A client's plugin has sent us a message that we shall delegate to its receivers + + if (sender->m_pluginMessageBucket.ratelimit(1)) { + qWarning("Dropping plugin message sent from \"%s\" (%d)", qUtf8Printable(sender->qsName), sender->uiSession); + return; + } + + if (!msg.has_data() || !msg.has_dataid()) { + // Messages without data and/or without a data ID can't be used by the clients. Thus we don't even have to send them + return; + } + + if (msg.data().size() > Mumble::Plugins::PluginMessage::MAX_DATA_LENGTH) { + qWarning("Dropping plugin message sent from \"%s\" (%d) - data too large", qUtf8Printable(sender->qsName), sender->uiSession); + return; + } + if (msg.dataid().size() > Mumble::Plugins::PluginMessage::MAX_DATA_ID_LENGTH) { + qWarning("Dropping plugin message sent from \"%s\" (%d) - data ID too long", qUtf8Printable(sender->qsName), sender->uiSession); + return; + } + + // Always set the sender's session and don't rely on it being set correctly (would + // allow spoofing the sender's session) + msg.set_sendersession(sender->uiSession); + + // Copy needed data from message in order to be able to remove info about receivers from the message as this doesn't + // matter for the client + size_t receiverAmount = msg.receiversessions_size(); + const ::google::protobuf::RepeatedField< ::google::protobuf::uint32 > receiverSessions = msg.receiversessions(); + + msg.clear_receiversessions(); + + QSet<uint32_t> uniqueReceivers; + uniqueReceivers.reserve(receiverSessions.size()); + + for(int i = 0; static_cast<size_t>(i) < receiverAmount; i++) { + uint32_t userSession = receiverSessions.Get(i); + + if (!uniqueReceivers.contains(userSession)) { + uniqueReceivers.insert(userSession); + } else { + // Duplicate entry -> ignore + continue; + } + + ServerUser *receiver = qhUsers.value(receiverSessions.Get(i)); + + if (receiver) { + // We can simply redirect the message we have received to the clients + sendMessage(receiver, msg); + } + } +} + #undef RATELIMIT #undef MSG_SETUP #undef MSG_SETUP_NO_UNIDLE diff --git a/src/murmur/Meta.cpp b/src/murmur/Meta.cpp index 6ebaeb18d..5e1456167 100644 --- a/src/murmur/Meta.cpp +++ b/src/murmur/Meta.cpp @@ -104,6 +104,9 @@ MetaParams::MetaParams() { iMessageLimit = 1; iMessageBurst = 5; + iPluginMessageLimit = 4; + iPluginMessageBurst = 15; + qsCiphers = MumbleSSL::defaultOpenSSLCipherString(); bLogGroupChanges = false; @@ -402,6 +405,9 @@ void MetaParams::read(QString fname) { iMessageLimit = typeCheckedFromSettings("messagelimit", 1); iMessageBurst = typeCheckedFromSettings("messageburst", 5); + iPluginMessageLimit = typeCheckedFromSettings("pluginmessagelimit", 4); + iPluginMessageBurst = typeCheckedFromSettings("pluginmessageburst", 15); + bool bObfuscate = typeCheckedFromSettings("obfuscate", false); if (bObfuscate) { qWarning("IP address obfuscation enabled."); diff --git a/src/murmur/Meta.h b/src/murmur/Meta.h index bac90df5b..91b48f535 100644 --- a/src/murmur/Meta.h +++ b/src/murmur/Meta.h @@ -104,6 +104,9 @@ public: unsigned int iMessageLimit; unsigned int iMessageBurst; + unsigned int iPluginMessageLimit; + unsigned int iPluginMessageBurst; + QSslCertificate qscCert; QSslKey qskKey; diff --git a/src/murmur/Server.cpp b/src/murmur/Server.cpp index 4c8dd0939..c0c979814 100644 --- a/src/murmur/Server.cpp +++ b/src/murmur/Server.cpp @@ -418,6 +418,8 @@ void Server::readParams() { qrChannelName = Meta::mp.qrChannelName; iMessageLimit = Meta::mp.iMessageLimit; iMessageBurst = Meta::mp.iMessageBurst; + iPluginMessageLimit = Meta::mp.iPluginMessageLimit; + iPluginMessageBurst = Meta::mp.iPluginMessageBurst; qvSuggestVersion = Meta::mp.qvSuggestVersion; qvSuggestPositional = Meta::mp.qvSuggestPositional; qvSuggestPushToTalk = Meta::mp.qvSuggestPushToTalk; @@ -526,6 +528,15 @@ void Server::readParams() { if (iMessageBurst < 1) { // Prevent disabling messages entirely iMessageBurst = 1; } + + iPluginMessageLimit = getConf("mpluginessagelimit", iPluginMessageLimit).toUInt(); + if (iPluginMessageLimit < 1) { // Prevent disabling messages entirely + iPluginMessageLimit = 1; + } + iPluginMessageBurst = getConf("pluginmessageburst", iPluginMessageBurst).toUInt(); + if (iPluginMessageBurst < 1) { // Prevent disabling messages entirely + iPluginMessageBurst = 1; + } } void Server::setLiveConf(const QString &key, const QString &value) { diff --git a/src/murmur/Server.h b/src/murmur/Server.h index abebd0ffe..ac854cea6 100644 --- a/src/murmur/Server.h +++ b/src/murmur/Server.h @@ -140,6 +140,9 @@ public: unsigned int iMessageLimit; unsigned int iMessageBurst; + unsigned int iPluginMessageLimit; + unsigned int iPluginMessageBurst; + QVariant qvSuggestVersion; QVariant qvSuggestPositional; QVariant qvSuggestPushToTalk; diff --git a/src/murmur/ServerUser.cpp b/src/murmur/ServerUser.cpp index f2dac8abb..367889bee 100644 --- a/src/murmur/ServerUser.cpp +++ b/src/murmur/ServerUser.cpp @@ -13,7 +13,8 @@ #endif ServerUser::ServerUser(Server *p, QSslSocket *socket) - : Connection(p, socket), User(), s(nullptr), leakyBucket(p->iMessageLimit, p->iMessageBurst) { + : Connection(p, socket), User(), s(nullptr), + leakyBucket(p->iMessageLimit, p->iMessageBurst), m_pluginMessageBucket(5, 20) { sState = ServerUser::Connected; sUdpSocket = INVALID_SOCKET; diff --git a/src/murmur/ServerUser.h b/src/murmur/ServerUser.h index fd40071ca..c34ebeaf7 100644 --- a/src/murmur/ServerUser.h +++ b/src/murmur/ServerUser.h @@ -147,6 +147,7 @@ public: QMap< QString, QString > qmWhisperRedirect; LeakyBucket leakyBucket; + LeakyBucket m_pluginMessageBucket; int iLastPermissionCheck; QMap< int, unsigned int > qmPermissionSent; |