]> git.netwichtig.de Git - user/henk/code/inspircd.git/commitdiff
Add internal serialisations of the DCC allow and silence lists.
authorPeter Powell <petpow@saberuk.com>
Tue, 3 Sep 2019 11:27:14 +0000 (12:27 +0100)
committerPeter Powell <petpow@saberuk.com>
Tue, 3 Sep 2019 11:28:58 +0000 (12:28 +0100)
src/modules/m_dccallow.cpp
src/modules/m_silence.cpp

index e0ea4c7aeed89e7d20ab38cdc05bb0320e4e8ff5..23fc129951419207352eb5dd2f6f9ad120920d33 100644 (file)
@@ -98,14 +98,83 @@ typedef std::vector<DCCAllow> dccallowlist;
 dccallowlist* dl;
 typedef std::vector<BannedFileList> bannedfilelist;
 bannedfilelist bfl;
-typedef SimpleExtItem<dccallowlist> DCCAllowExt;
 
-class CommandDccallow : public Command
+class DCCAllowExt : public SimpleExtItem<dccallowlist>
 {
-       DCCAllowExt& ext;
-
  public:
        unsigned int maxentries;
+
+       DCCAllowExt(Module* Creator)
+               : SimpleExtItem<dccallowlist>("dccallow", ExtensionItem::EXT_USER, Creator)
+       {
+       }
+
+       void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE
+       {
+               LocalUser* user = IS_LOCAL(static_cast<User*>(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<dccallowlist*>(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");
index 55e1da81d654d53c18f108edf514444f63418d81..19141d0902a1a1e4b16435e8cee7f4a44a1a0506 100644 (file)
@@ -180,6 +180,84 @@ class SilenceEntry
 
 typedef insp::flat_set<SilenceEntry> SilenceList;
 
+class SilenceExtItem : public SimpleExtItem<SilenceList>
+{
+ public:
+       unsigned int maxsilence;
+
+       SilenceExtItem(Module* Creator)
+               : SimpleExtItem<SilenceList>("silence_list", ExtensionItem::EXT_USER, Creator)
+       {
+       }
+
+       void FromInternal(Extensible* container, const std::string& value) CXX11_OVERRIDE
+       {
+               LocalUser* user = IS_LOCAL(static_cast<User*>(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<SilenceList*>(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<SilenceList> 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 = "[(+|-)<mask> [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<std::string, std::string>& 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