From 889d521e05f2e922683d48c74eb00290e7a2f548 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Wed, 17 Jul 2024 00:06:50 +0100 Subject: Shuffle the modules about a bit. --- modules/dccallow.cpp | 627 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 627 insertions(+) create mode 100644 modules/dccallow.cpp (limited to 'modules/dccallow.cpp') diff --git a/modules/dccallow.cpp b/modules/dccallow.cpp new file mode 100644 index 000000000..823f8419b --- /dev/null +++ b/modules/dccallow.cpp @@ -0,0 +1,627 @@ +/* + * InspIRCd -- Internet Relay Chat Daemon + * + * Copyright (C) 2021 Dominic Hamon + * Copyright (C) 2018 linuxdaemon + * Copyright (C) 2016 Adam + * Copyright (C) 2013, 2017-2024 Sadie Powell + * Copyright (C) 2012-2016 Attila Molnar + * Copyright (C) 2012, 2019 Robby + * Copyright (C) 2009 Matt Smith + * Copyright (C) 2009 Daniel De Graaf + * Copyright (C) 2008 John Brooks + * Copyright (C) 2008 Craig Edwards + * Copyright (C) 2007-2008 Robin Burchell + * Copyright (C) 2007-2008 Dennis Friis + * Copyright (C) 2006 jamie + * + * This file is part of InspIRCd. InspIRCd is free software: you can + * redistribute it and/or modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation, version 2. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "inspircd.h" +#include "extension.h" +#include "numerichelper.h" +#include "timeutils.h" + +enum +{ + // From ircd-ratbox. + RPL_HELPSTART = 704, + RPL_HELPTXT = 705, + RPL_ENDOFHELP = 706, + + // InspIRCd-specific? + RPL_DCCALLOWSTART = 990, + RPL_DCCALLOWLIST = 991, + RPL_DCCALLOWEND = 992, + RPL_DCCALLOWTIMED = 993, + RPL_DCCALLOWPERMANENT = 994, + RPL_DCCALLOWREMOVED = 995, + ERR_DCCALLOWINVALID = 996, + RPL_DCCALLOWEXPIRED = 997, + ERR_UNKNOWNDCCALLOWCMD = 998 +}; + +static const char* const helptext[] = +{ + "You may allow DCCs from specific users by specifying a", + "DCC allow for the user you want to receive DCCs from.", + "For example, to allow the user Brain to send you inspircd.exe", + "you would type:", + "/DCCALLOW +Brain", + "Brain would then be able to send you files. They would have to", + "resend the file again if the server gave them an error message", + "before you added them to your DCCALLOW list.", + "DCCALLOW entries will be temporary. If you want to add", + "them to your DCCALLOW list until you leave IRC, type:", + "/DCCALLOW +Brain 0", + "To remove the user from your DCCALLOW list, type:", + "/DCCALLOW -Brain", + "To see the users in your DCCALLOW list, type:", + "/DCCALLOW LIST", + "NOTE: If the user leaves IRC or changes their nickname", + " they will be removed from your DCCALLOW list.", + " Your DCCALLOW list will be deleted when you leave IRC." +}; + +class BannedFileList final +{ +public: + std::string filemask; + std::string action; +}; + +class DCCAllow final +{ +public: + std::string nickname; + std::string hostmask; + time_t set_on; + unsigned long length; + + DCCAllow() = default; + + DCCAllow(const std::string& nick, const std::string& hm, time_t so, unsigned long ln) + : nickname(nick) + , hostmask(hm) + , set_on(so) + , length(ln) + { + } +}; + +typedef std::vector userlist; +userlist ul; +typedef std::vector dccallowlist; +dccallowlist* dl; +typedef std::vector bannedfilelist; +bannedfilelist bfl; + +class DCCAllowExt final + : public SimpleExtItem +{ +public: + unsigned long maxentries; + + DCCAllowExt(Module* Creator) + : SimpleExtItem(Creator, "dccallow", ExtensionType::USER) + { + } + + void FromInternal(Extensible* container, const std::string& value) noexcept override + { + if (container->extype != this->extype) + return; + + LocalUser* user = IS_LOCAL(static_cast(container)); + if (!user) + return; + + // Remove the old list and create a new one. + Unset(user, false); + auto* list = new dccallowlist(); + + irc::spacesepstream ts(value); + while (!ts.StreamEnd()) + { + // Check we have space for another entry. + if (list->size() >= maxentries) + { + ServerInstance->Logs.Debug(MODNAME, "Oversized DCC allow list received for {}: {}", + user->uuid, value); + 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.Debug(MODNAME, "Malformed DCC allow list received for {}: {}", + user->uuid, value); + delete list; + return; + } + + // Store the DCC allow entry. + list->push_back(dccallow); + } + + // If we have an empty list then don't store it. + if (list->empty()) + { + delete list; + return; + } + + // The value was well formed. + Set(user, list); + } + + std::string ToInternal(const Extensible* container, void* item) const noexcept 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 final + : public Command +{ +public: + DCCAllowExt& ext; + unsigned long defaultlength; + CommandDccallow(Module* parent, DCCAllowExt& Ext) + : Command(parent, "DCCALLOW", 0) + , ext(Ext) + { + syntax = { "[(+|-) [