From 685dfe016e406d09a7445e1693d2317afe25ba7a Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Tue, 3 Sep 2019 12:27:14 +0100 Subject: Add internal serialisations of the DCC allow and silence lists. --- src/modules/m_dccallow.cpp | 83 ++++++++++++++++++++++++++++++++++++++---- src/modules/m_silence.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 159 insertions(+), 13 deletions(-) diff --git a/src/modules/m_dccallow.cpp b/src/modules/m_dccallow.cpp index e0ea4c7ae..23fc12995 100644 --- a/src/modules/m_dccallow.cpp +++ b/src/modules/m_dccallow.cpp @@ -98,14 +98,83 @@ typedef std::vector dccallowlist; dccallowlist* dl; typedef std::vector bannedfilelist; bannedfilelist bfl; -typedef SimpleExtItem DCCAllowExt; -class CommandDccallow : public Command +class DCCAllowExt : public SimpleExtItem { - DCCAllowExt& ext; - public: unsigned int maxentries; + + DCCAllowExt(Module* Creator) + : SimpleExtItem("dccallow", ExtensionItem::EXT_USER, Creator) + { + } + + void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE + { + LocalUser* user = IS_LOCAL(static_cast(container)); + if (!user) + return; + + // Remove the old list and create a new one. + unset(user); + dccallowlist* list = new dccallowlist(); + + irc::spacesepstream ts(value); + while (!ts.StreamEnd()) + { + // Check we have space for another entry. + if (list->size() >= maxentries) + { + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Oversized DCC allow list received for %s: %s", + user->uuid.c_str(), value.c_str()); + delete list; + return; + } + + // Extract the fields. + DCCAllow dccallow; + if (!ts.GetToken(dccallow.nickname) || + !ts.GetToken(dccallow.hostmask) || + !ts.GetNumericToken(dccallow.set_on) || + !ts.GetNumericToken(dccallow.length)) + { + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Malformed DCC allow list received for %s: %s", + user->uuid.c_str(), value.c_str()); + delete list; + return; + } + + // Store the DCC allow entry. + list->push_back(dccallow); + } + + } + + std::string ToInternal(const Extensible* container, void* item) const CXX11_OVERRIDE + { + dccallowlist* list = static_cast(item); + std::string buf; + for (dccallowlist::const_iterator iter = list->begin(); iter != list->end(); ++iter) + { + if (iter != list->begin()) + buf.push_back(' '); + + buf.append(iter->nickname); + buf.push_back(' '); + buf.append(iter->hostmask); + buf.push_back(' '); + buf.append(ConvToStr(iter->set_on)); + buf.push_back(' '); + buf.append(ConvToStr(iter->length)); + } + return buf; + } +}; + +class CommandDccallow : public Command +{ + public: + DCCAllowExt& ext; unsigned long defaultlength; CommandDccallow(Module* parent, DCCAllowExt& Ext) : Command(parent, "DCCALLOW", 0) @@ -191,7 +260,7 @@ class CommandDccallow : public Command ul.push_back(user); } - if (dl->size() >= maxentries) + if (dl->size() >= ext.maxentries) { user->WriteNumeric(ERR_DCCALLOWINVALID, user->nick, "Too many nicks on DCCALLOW list"); return CMD_FAILURE; @@ -301,7 +370,7 @@ class ModuleDCCAllow : public Module public: ModuleDCCAllow() - : ext("dccallow", ExtensionItem::EXT_USER, this) + : ext(this) , cmd(this, ext) , blockchat(false) { @@ -521,7 +590,7 @@ class ModuleDCCAllow : public Module bfl.swap(newbfl); ConfigTag* tag = ServerInstance->Config->ConfValue("dccallow"); - cmd.maxentries = tag->getUInt("maxentries", 20); + cmd.ext.maxentries = tag->getUInt("maxentries", 20); cmd.defaultlength = tag->getDuration("length", 0); blockchat = tag->getBool("blockchat"); defaultaction = tag->getString("action"); diff --git a/src/modules/m_silence.cpp b/src/modules/m_silence.cpp index 55e1da81d..19141d090 100644 --- a/src/modules/m_silence.cpp +++ b/src/modules/m_silence.cpp @@ -180,6 +180,84 @@ class SilenceEntry typedef insp::flat_set SilenceList; +class SilenceExtItem : public SimpleExtItem +{ + public: + unsigned int maxsilence; + + SilenceExtItem(Module* Creator) + : SimpleExtItem("silence_list", ExtensionItem::EXT_USER, Creator) + { + } + + void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE + { + LocalUser* user = IS_LOCAL(static_cast(container)); + if (!user) + return; + + // Remove the old list and create a new one. + unset(user); + SilenceList* list = new SilenceList(); + + irc::spacesepstream ts(value); + while (!ts.StreamEnd()) + { + // Check we have space for another entry. + if (list->size() >= maxsilence) + { + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Oversized silence list received for %s: %s", + user->uuid.c_str(), value.c_str()); + delete list; + return; + } + + // Extract the mask and the flags. + std::string mask; + std::string flagstr; + if (!ts.GetToken(mask) || !ts.GetToken(flagstr)) + { + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Malformed silence list received for %s: %s", + user->uuid.c_str(), value.c_str()); + delete list; + return; + } + + // Try to parse the flags. + uint32_t flags; + if (!SilenceEntry::FlagsToBits(flagstr, flags)) + { + ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Malformed silence flags received for %s: %s", + user->uuid.c_str(), flagstr.c_str()); + delete list; + return; + } + + // Store the silence entry. + list->insert(SilenceEntry(flags, mask)); + } + + // The value was well formed. + set(user, list); + } + + std::string ToInternal(const Extensible* container, void* item) const CXX11_OVERRIDE + { + SilenceList* list = static_cast(item); + std::string buf; + for (SilenceList::const_iterator iter = list->begin(); iter != list->end(); ++iter) + { + if (iter != list->begin()) + buf.push_back(' '); + + buf.append(iter->mask); + buf.push_back(' '); + buf.append(SilenceEntry::BitsToFlags(iter->flags)); + } + return buf; + } +}; + class SilenceMessage : public ClientProtocol::Message { public: @@ -199,7 +277,7 @@ class CommandSilence : public SplitCommand CmdResult AddSilence(LocalUser* user, const std::string& mask, uint32_t flags) { SilenceList* list = ext.get(user); - if (list && list->size() > maxsilence) + if (list && list->size() > ext.maxsilence) { user->WriteNumeric(ERR_SILELISTFULL, mask, SilenceEntry::BitsToFlags(flags), "Your SILENCE list is full"); return CMD_FAILURE; @@ -258,13 +336,12 @@ class CommandSilence : public SplitCommand } public: - SimpleExtItem ext; - unsigned int maxsilence; + SilenceExtItem ext; CommandSilence(Module* Creator) : SplitCommand(Creator, "SILENCE") , msgprov(Creator, "SILENCE") - , ext("silence_list", ExtensionItem::EXT_USER, Creator) + , ext(Creator) { allow_empty_last_param = false; syntax = "[(+|-) [CcdiNnPpTtx]]"; @@ -364,13 +441,13 @@ class ModuleSilence { ConfigTag* tag = ServerInstance->Config->ConfValue("silence"); exemptuline = tag->getBool("exemptuline", true); - cmd.maxsilence = tag->getUInt("maxentries", 32, 1); + cmd.ext.maxsilence = tag->getUInt("maxentries", 32, 1); } void On005Numeric(std::map& tokens) CXX11_OVERRIDE { tokens["ESILENCE"] = "CcdiNnPpTtx"; - tokens["SILENCE"] = ConvToStr(cmd.maxsilence); + tokens["SILENCE"] = ConvToStr(cmd.ext.maxsilence); } ModResult OnUserPreInvite(User* source, User* dest, Channel* channel, time_t timeout) CXX11_OVERRIDE -- cgit v1.2.3