From 2d35c3396a1f00375d45b874dafb9e0bdb520a9b Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Tue, 13 Aug 2019 20:11:11 +0100 Subject: Fix some remaining uses of ato[il]. --- src/modules/extra/m_pgsql.cpp | 2 +- src/modules/m_delaymsg.cpp | 2 +- src/modules/m_xline_db.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_pgsql.cpp b/src/modules/extra/m_pgsql.cpp index 5d059ec9c..37cf92704 100644 --- a/src/modules/extra/m_pgsql.cpp +++ b/src/modules/extra/m_pgsql.cpp @@ -103,7 +103,7 @@ class PgSQLresult : public SQL::Result { rows = PQntuples(res); if (!rows) - rows = atoi(PQcmdTuples(res)); + rows = ConvToNum(PQcmdTuples(res)); } ~PgSQLresult() diff --git a/src/modules/m_delaymsg.cpp b/src/modules/m_delaymsg.cpp index 04d4119c7..cf26df8c1 100644 --- a/src/modules/m_delaymsg.cpp +++ b/src/modules/m_delaymsg.cpp @@ -34,7 +34,7 @@ class DelayMsgMode : public ParamMode bool ResolveModeConflict(std::string& their_param, const std::string& our_param, Channel*) CXX11_OVERRIDE { - return (atoi(their_param.c_str()) < atoi(our_param.c_str())); + return ConvToNum(their_param) < ConvToNum(our_param); } ModeAction OnSet(User* source, Channel* chan, std::string& parameter) CXX11_OVERRIDE; diff --git a/src/modules/m_xline_db.cpp b/src/modules/m_xline_db.cpp index 00605f259..97531aae8 100644 --- a/src/modules/m_xline_db.cpp +++ b/src/modules/m_xline_db.cpp @@ -211,8 +211,8 @@ class ModuleXLineDB continue; } - XLine* xl = xlf->Generate(ServerInstance->Time(), atoi(command_p[5].c_str()), command_p[3], command_p[6], command_p[2]); - xl->SetCreateTime(atoi(command_p[4].c_str())); + XLine* xl = xlf->Generate(ServerInstance->Time(), ConvToNum(command_p[5]), command_p[3], command_p[6], command_p[2]); + xl->SetCreateTime(ConvToNum(command_p[4])); if (ServerInstance->XLines->AddLine(xl, NULL)) { -- cgit v1.3.1-10-gc9f91 From 8745660fcdac7c1b80c94cfc0ff60928cd4dd4b7 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Tue, 20 Aug 2019 16:17:18 +0100 Subject: Initialise and deallocate the MySQL library correctly. --- src/modules/extra/m_mysql.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/modules') diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp index c50d2abf5..7b6e2906d 100644 --- a/src/modules/extra/m_mysql.cpp +++ b/src/modules/extra/m_mysql.cpp @@ -412,6 +412,9 @@ ModuleSQL::ModuleSQL() void ModuleSQL::init() { + if (mysql_library_init(0, NULL, NULL)) + throw ModuleException("Unable to initialise the MySQL library!"); + Dispatcher = new DispatcherThread(this); ServerInstance->Threads.Start(Dispatcher); } @@ -424,10 +427,13 @@ ModuleSQL::~ModuleSQL() Dispatcher->OnNotify(); delete Dispatcher; } + for(ConnMap::iterator i = connections.begin(); i != connections.end(); i++) { delete i->second; } + + mysql_library_end(); } void ModuleSQL::ReadConfig(ConfigStatus& status) -- cgit v1.3.1-10-gc9f91 From f9175f65188fe6c37cda1d94529297008670ab65 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Tue, 20 Aug 2019 15:04:54 +0100 Subject: Improve escaping strings in the MySQL module. --- src/modules/extra/m_mysql.cpp | 52 ++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 23 deletions(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_mysql.cpp b/src/modules/extra/m_mysql.cpp index 7b6e2906d..dcdbe0004 100644 --- a/src/modules/extra/m_mysql.cpp +++ b/src/modules/extra/m_mysql.cpp @@ -253,6 +253,31 @@ class MySQLresult : public SQL::Result */ class SQLConnection : public SQL::Provider { + private: + bool EscapeString(SQL::Query* query, const std::string& in, std::string& out) + { + // In the worst case each character may need to be encoded as using two bytes and one + // byte is the NUL terminator. + std::vector buffer(in.length() * 2 + 1); + + // The return value of mysql_escape_string() is either an error or the length of the + // encoded string not including the NUL terminator. + // + // Unfortunately, someone genius decided that mysql_escape_string should return an + // unsigned type even though -1 is returned on error so checking whether an error + // happened is a bit cursed. + unsigned long escapedsize = mysql_escape_string(&buffer[0], in.c_str(), in.length()); + if (escapedsize == static_cast(-1)) + { + SQL::Error err(SQL::QSEND_FAIL, InspIRCd::Format("%u: %s", mysql_errno(connection), mysql_error(connection))); + query->OnError(err); + return false; + } + + out.append(&buffer[0], escapedsize); + return true; + } + public: reference config; MYSQL *connection; @@ -356,21 +381,8 @@ class SQLConnection : public SQL::Provider { if (q[i] != '?') res.push_back(q[i]); - else - { - if (param < p.size()) - { - std::string parm = p[param++]; - // In the worst case, each character may need to be encoded as using two bytes, - // and one byte is the terminating null - std::vector buffer(parm.length() * 2 + 1); - - // The return value of mysql_real_escape_string() is the length of the encoded string, - // not including the terminating null - unsigned long escapedsize = mysql_real_escape_string(connection, &buffer[0], parm.c_str(), parm.length()); - res.append(&buffer[0], escapedsize); - } - } + else if (param < p.size() && !EscapeString(call, p[param++], res)) + return; } Submit(call, res); } @@ -391,14 +403,8 @@ class SQLConnection : public SQL::Provider i--; SQL::ParamMap::const_iterator it = p.find(field); - if (it != p.end()) - { - std::string parm = it->second; - // NOTE: See above - std::vector buffer(parm.length() * 2 + 1); - unsigned long escapedsize = mysql_escape_string(&buffer[0], parm.c_str(), parm.length()); - res.append(&buffer[0], escapedsize); - } + if (it != p.end() && !EscapeString(call, it->second, res)) + return; } } Submit(call, res); -- cgit v1.3.1-10-gc9f91 From 9ed9396278c2499f5322575c87aa4daea33992e3 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Fri, 23 Aug 2019 10:42:38 +0100 Subject: Silence some GCC warnings. --- src/modules/extra/m_ssl_gnutls.cpp | 6 +++--- src/modules/m_ircv3_servertime.cpp | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 9347440cc..80c076148 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -51,9 +51,6 @@ # endif #endif -// Fix warnings about using std::auto_ptr on C++11 or newer. -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - #include #include @@ -61,6 +58,9 @@ # pragma GCC diagnostic pop #endif +// Fix warnings about using std::auto_ptr on C++11 or newer. +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + #ifndef GNUTLS_VERSION_NUMBER #define GNUTLS_VERSION_NUMBER LIBGNUTLS_VERSION_NUMBER #define GNUTLS_VERSION LIBGNUTLS_VERSION diff --git a/src/modules/m_ircv3_servertime.cpp b/src/modules/m_ircv3_servertime.cpp index 3e059719d..7a4ac5d2a 100644 --- a/src/modules/m_ircv3_servertime.cpp +++ b/src/modules/m_ircv3_servertime.cpp @@ -46,6 +46,8 @@ class ServerTimeTag } public: + using ServerProtocol::MessageEventListener::OnBuildMessage; + ServerTimeTag(Module* mod) : IRCv3::ServerTime::Manager(mod) , IRCv3::CapTag(mod, "server-time", "time") -- cgit v1.3.1-10-gc9f91 From 78f9c572119aef08c9115ad61caa41e82b41c98a Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Mon, 26 Aug 2019 09:43:23 +0100 Subject: Fix the haproxy module losing initial data in some circumstances. --- src/modules/m_haproxy.cpp | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'src/modules') diff --git a/src/modules/m_haproxy.cpp b/src/modules/m_haproxy.cpp index 4d0e52514..19aac8ebd 100644 --- a/src/modules/m_haproxy.cpp +++ b/src/modules/m_haproxy.cpp @@ -219,7 +219,16 @@ class HAProxyHook : public IOHookMiddle return true; } - int ReadProxyAddress(StreamSocket* sock) + int ReadData(std::string& destrecvq) + { + // Once connected we handle no special data. + std::string& recvq = GetRecvQ(); + destrecvq.append(recvq); + recvq.clear(); + return 1; + } + + int ReadProxyAddress(StreamSocket* sock, std::string& destrecvq) { // Block until we have the entire address. std::string& recvq = GetRecvQ(); @@ -276,14 +285,15 @@ class HAProxyHook : public IOHookMiddle // Erase the processed proxy information from the receive queue. recvq.erase(0, address_length); + break; } // We're done! state = HPS_CONNECTED; - return 1; + return ReadData(destrecvq); } - int ReadProxyHeader(StreamSocket* sock) + int ReadProxyHeader(StreamSocket* sock, std::string& destrecvq) { // Block until we have a header. std::string& recvq = GetRecvQ(); @@ -359,7 +369,7 @@ class HAProxyHook : public IOHookMiddle } state = HPS_WAITING_FOR_ADDRESS; - return ReadProxyAddress(sock); + return ReadProxyAddress(sock, destrecvq); } public: @@ -384,16 +394,13 @@ class HAProxyHook : public IOHookMiddle switch (state) { case HPS_WAITING_FOR_HEADER: - return ReadProxyHeader(sock); + return ReadProxyHeader(sock, destrecvq); case HPS_WAITING_FOR_ADDRESS: - return ReadProxyAddress(sock); + return ReadProxyAddress(sock, destrecvq); case HPS_CONNECTED: - std::string& recvq = GetRecvQ(); - destrecvq.append(recvq); - recvq.clear(); - return 1; + return ReadData(destrecvq); } // We should never reach this point. -- cgit v1.3.1-10-gc9f91 From e566a2d666f6f54eeab364794145e3b0999383ed Mon Sep 17 00:00:00 2001 From: iwalkalone Date: Tue, 3 Sep 2019 00:52:20 +0200 Subject: When silence mask is prefixed by + or -, it should only remove the first character, not the entire string (#1698). --- src/modules/m_silence.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/m_silence.cpp b/src/modules/m_silence.cpp index 1e73bda27..55e1da81d 100644 --- a/src/modules/m_silence.cpp +++ b/src/modules/m_silence.cpp @@ -282,7 +282,7 @@ class CommandSilence : public SplitCommand std::string mask = parameters[0]; if (mask[0] == '-' || mask[0] == '+') { - mask.erase(0); + mask.erase(0, 1); if (mask.empty()) mask.assign("*"); ModeParser::CleanMask(mask); -- cgit v1.3.1-10-gc9f91 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(-) (limited to 'src/modules') 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.3.1-10-gc9f91 From 5a2af6ded883d71c6c4c9f1497cca1721f8b0742 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sat, 14 Sep 2019 10:36:48 -0500 Subject: m_chanfilter: Apply filters to part messages (#1702) --- src/modules/m_chanfilter.cpp | 89 ++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 24 deletions(-) (limited to 'src/modules') diff --git a/src/modules/m_chanfilter.cpp b/src/modules/m_chanfilter.cpp index 6131ab916..e955175a8 100644 --- a/src/modules/m_chanfilter.cpp +++ b/src/modules/m_chanfilter.cpp @@ -59,6 +59,25 @@ class ModuleChanFilter : public Module bool hidemask; bool notifyuser; + ChanFilter::ListItem* Match(User* user, Channel* chan, const std::string& text) + { + ModResult res = CheckExemption::Call(exemptionprov, user, chan, "filter"); + if (!IS_LOCAL(user) || res == MOD_RES_ALLOW) + return NULL; + + ListModeBase::ModeList* list = cf.GetList(chan); + if (!list) + return NULL; + + for (ListModeBase::ModeList::iterator i = list->begin(); i != list->end(); i++) + { + if (InspIRCd::Match(text, i->mask)) + return &*i; + } + + return NULL; + } + public: ModuleChanFilter() @@ -76,40 +95,62 @@ class ModuleChanFilter : public Module cf.DoRehash(); } + void OnUserPart(Membership* memb, std::string& partmessage, CUList& except_list) CXX11_OVERRIDE + { + if (!memb) + return; + + User* user = memb->user; + Channel* chan = memb->chan; + ChanFilter::ListItem* match = Match(user, chan, partmessage); + if (!match) + return; + + // Match() checks the user is local, we can assume from here + LocalUser* luser = IS_LOCAL(user); + + std::string oldreason(partmessage); + partmessage = "Reason filtered"; + if (!notifyuser) + { + // Send fake part + ClientProtocol::Messages::Part partmsg(memb, oldreason); + ClientProtocol::Event ev(ServerInstance->GetRFCEvents().part, partmsg); + luser->Send(ev); + + // Don't send the user the changed message + except_list.insert(user); + return; + } + + if (hidemask) + user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your part message contained a censored word)"); + else + user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your part message contained a censored word: " + match->mask + ")"); + } + ModResult OnUserPreMessage(User* user, const MessageTarget& target, MessageDetails& details) CXX11_OVERRIDE { if (target.type != MessageTarget::TYPE_CHANNEL) return MOD_RES_PASSTHRU; Channel* chan = target.Get(); - ModResult res = CheckExemption::Call(exemptionprov, user, chan, "filter"); - - if (!IS_LOCAL(user) || res == MOD_RES_ALLOW) - return MOD_RES_PASSTHRU; - - ListModeBase::ModeList* list = cf.GetList(chan); - - if (list) + ChanFilter::ListItem* match = Match(user, chan, details.text); + if (match) { - for (ListModeBase::ModeList::iterator i = list->begin(); i != list->end(); i++) + if (!notifyuser) { - if (InspIRCd::Match(details.text, i->mask)) - { - if (!notifyuser) - { - details.echo_original = true; - return MOD_RES_DENY; - } - - if (hidemask) - user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your message contained a censored word)"); - else - user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your message contained a censored word: " + i->mask + ")"); - return MOD_RES_DENY; - } + details.echo_original = true; + return MOD_RES_DENY; } - } + if (hidemask) + user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your message contained a censored word)"); + else + user->WriteNumeric(ERR_CANNOTSENDTOCHAN, chan->name, "Cannot send to channel (your message contained a censored word: " + match->mask + ")"); + + return MOD_RES_DENY; + } return MOD_RES_PASSTHRU; } -- cgit v1.3.1-10-gc9f91 From 436e358b5dc3de0e431ba9651ecf580d8ede2b06 Mon Sep 17 00:00:00 2001 From: linuxdaemon Date: Sat, 14 Sep 2019 13:00:44 -0500 Subject: m_alias: Add option to strip colors when matching --- src/modules/m_alias.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/m_alias.cpp b/src/modules/m_alias.cpp index a275853e9..577938e49 100644 --- a/src/modules/m_alias.cpp +++ b/src/modules/m_alias.cpp @@ -50,6 +50,9 @@ class Alias /** Format that must be matched for use */ std::string format; + + /** Strip color codes before match? */ + bool StripColor; }; class ModuleAlias : public Module @@ -94,6 +97,7 @@ class ModuleAlias : public Module a.UserCommand = tag->getBool("usercommand", true); a.OperOnly = tag->getBool("operonly"); a.format = tag->getString("format"); + a.StripColor = tag->getBool("stripcolor"); std::transform(a.AliasedCommand.begin(), a.AliasedCommand.end(), a.AliasedCommand.begin(), ::toupper); newAliases.insert(std::make_pair(a.AliasedCommand, a)); @@ -261,10 +265,14 @@ class ModuleAlias : public Module int DoAlias(User *user, Channel *c, Alias *a, const std::string& compare, const std::string& safe) { + std::string stripped(compare); + if (a->StripColor) + InspIRCd::StripColor(stripped); + /* Does it match the pattern? */ if (!a->format.empty()) { - if (!InspIRCd::Match(compare, a->format)) + if (!InspIRCd::Match(stripped, a->format)) return 0; } -- cgit v1.3.1-10-gc9f91 From c05f1fee8a1a8991107ff2d00a9153e33c4d51ed Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Mon, 16 Sep 2019 12:22:28 +0100 Subject: Fix the noctcp user mode not applying to channel CTCPs. Closes #1704. --- src/modules/m_noctcp.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src/modules') diff --git a/src/modules/m_noctcp.cpp b/src/modules/m_noctcp.cpp index f288820b8..475151cb7 100644 --- a/src/modules/m_noctcp.cpp +++ b/src/modules/m_noctcp.cpp @@ -78,6 +78,14 @@ class ModuleNoCTCP : public Module user->WriteNumeric(ERR_CANNOTSENDTOCHAN, c->name, "Can't send CTCP to channel (+C is set)"); return MOD_RES_DENY; } + + const Channel::MemberMap& members = c->GetUsers(); + for (Channel::MemberMap::const_iterator member = members.begin(); member != members.end(); ++member) + { + User* u = member->first; + if (u->IsModeSet(ncu)) + details.exemptions.insert(u); + } break; } case MessageTarget::TYPE_USER: -- cgit v1.3.1-10-gc9f91 From 9982ec4e5b027ed24b1fda5e6fd3ab35b98de1a7 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Mon, 16 Sep 2019 13:43:29 +0100 Subject: Fix cloaking not ignoring the case of a user's hostname. This new mode is recommended but disabled by default for compat reasons. Closes #480. Closes #1419. Co-Authored-By: B00mX0r --- docs/conf/modules.conf.example | 6 ++++-- src/modules/m_cloaking.cpp | 24 ++++++++++++++++-------- 2 files changed, 20 insertions(+), 10 deletions(-) (limited to 'src/modules') diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index f15276b47..678139049 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -554,11 +554,13 @@ # +# prefix="net-" +# ignorecase="no"> # # +# prefix="net-" +# ignorecase="no"> #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-# # Clones module: Adds an oper command /CLONES for detecting cloned diff --git a/src/modules/m_cloaking.cpp b/src/modules/m_cloaking.cpp index d9b2eb789..c5db9ff8a 100644 --- a/src/modules/m_cloaking.cpp +++ b/src/modules/m_cloaking.cpp @@ -49,6 +49,9 @@ struct CloakInfo // The number of parts of the hostname shown when using half cloaking. unsigned int domainparts; + // Whether to ignore the case of a hostname when cloaking it. + bool ignorecase; + // The secret used for generating cloaks. std::string key; @@ -58,9 +61,10 @@ struct CloakInfo // The suffix for IP cloaks (e.g. .IP). std::string suffix; - CloakInfo(CloakMode Mode, const std::string& Key, const std::string& Prefix, const std::string& Suffix, unsigned int DomainParts = 0) + CloakInfo(CloakMode Mode, const std::string& Key, const std::string& Prefix, const std::string& Suffix, bool IgnoreCase, unsigned int DomainParts = 0) : mode(Mode) , domainparts(DomainParts) + , ignorecase(IgnoreCase) , key(Key) , prefix(Prefix) , suffix(Suffix) @@ -248,7 +252,10 @@ class ModuleCloaking : public Module input.append(1, id); input.append(info.key); input.append(1, '\0'); // null does not terminate a C++ string - input.append(item); + if (info.ignorecase) + std::transform(item.begin(), item.end(), std::back_inserter(input), ::tolower); + else + input.append(item); std::string rv = Hash->GenerateRaw(input).substr(0,len); for(size_t i = 0; i < len; i++) @@ -388,17 +395,17 @@ class ModuleCloaking : public Module { case MODE_HALF_CLOAK: // Use old cloaking verification to stay compatible with 2.0 - // But verify domainparts when use 3.0-only features - if (info.domainparts == 3) + // But verify domainparts and ignorecase when use 3.0-only features + if (info.domainparts == 3 && !info.ignorecase) testcloak = info.prefix + SegmentCloak(info, "*", 3, 8) + info.suffix; else { irc::sockets::sockaddrs sa; - testcloak = GenCloak(info, sa, "", testcloak + ConvToStr(info.domainparts)); + testcloak = GenCloak(info, sa, "", testcloak + ConvToStr(info.domainparts)) + (info.ignorecase ? "-ci" : ""); } break; case MODE_OPAQUE: - testcloak = info.prefix + SegmentCloak(info, "*", 4, 8) + info.suffix; + testcloak = info.prefix + SegmentCloak(info, "*", 4, 8) + info.suffix + (info.ignorecase ? "-ci" : ""); } } return Version("Provides masking of user hostnames", VF_COMMON|VF_VENDOR, testcloak); @@ -424,16 +431,17 @@ class ModuleCloaking : public Module if (i == tags.first && key.length() < minkeylen) throw ModuleException("Your cloaking key is not secure. It should be at least " + ConvToStr(minkeylen) + " characters long, at " + tag->getTagLocation()); + const bool ignorecase = tag->getBool("ignorecase"); const std::string mode = tag->getString("mode"); const std::string prefix = tag->getString("prefix"); const std::string suffix = tag->getString("suffix", ".IP"); if (stdalgo::string::equalsci(mode, "half")) { unsigned int domainparts = tag->getUInt("domainparts", 3, 1, 10); - newcloaks.push_back(CloakInfo(MODE_HALF_CLOAK, key, prefix, suffix, domainparts)); + newcloaks.push_back(CloakInfo(MODE_HALF_CLOAK, key, prefix, suffix, ignorecase, domainparts)); } else if (stdalgo::string::equalsci(mode, "full")) - newcloaks.push_back(CloakInfo(MODE_OPAQUE, key, prefix, suffix)); + newcloaks.push_back(CloakInfo(MODE_OPAQUE, key, prefix, suffix, ignorecase)); else throw ModuleException(mode + " is an invalid value for ; acceptable values are 'half' and 'full', at " + tag->getTagLocation()); } -- cgit v1.3.1-10-gc9f91 From b64177d3fb4f113c4db3325575970964867f01cc Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Fri, 20 Sep 2019 15:13:42 +0100 Subject: Lower the acceptable drift for clocks on link. --- src/modules/m_spanningtree/treesocket2.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/modules') diff --git a/src/modules/m_spanningtree/treesocket2.cpp b/src/modules/m_spanningtree/treesocket2.cpp index d4acdc0c8..966d624bb 100644 --- a/src/modules/m_spanningtree/treesocket2.cpp +++ b/src/modules/m_spanningtree/treesocket2.cpp @@ -155,17 +155,17 @@ void TreeSocket::ProcessLine(std::string &line) } else if (command == "BURST") { - if (params.size()) + if (!params.empty()) { time_t them = ConvToNum(params[0]); time_t delta = them - ServerInstance->Time(); - if ((delta < -600) || (delta > 600)) + if ((delta < -60) || (delta > 60)) { - ServerInstance->SNO->WriteGlobalSno('l', "\002ERROR\002: Your clocks are off by %ld seconds (this is more than five minutes). Link aborted, \002PLEASE SYNC YOUR CLOCKS!\002", labs((long)delta)); - SendError("Your clocks are out by "+ConvToStr(labs((long)delta))+" seconds (this is more than five minutes). Link aborted, PLEASE SYNC YOUR CLOCKS!"); + ServerInstance->SNO->WriteGlobalSno('l', "\002ERROR\002: Your clocks are off by %ld seconds (this is more than one minute). Link aborted, \002PLEASE SYNC YOUR CLOCKS!\002", labs((long)delta)); + SendError("Your clocks are out by "+ConvToStr(labs((long)delta))+" seconds (this is more than one minute). Link aborted, PLEASE SYNC YOUR CLOCKS!"); return; } - else if ((delta < -30) || (delta > 30)) + else if ((delta < -15) || (delta > 15)) { ServerInstance->SNO->WriteGlobalSno('l', "\002WARNING\002: Your clocks are off by %ld seconds. Please consider syncing your clocks.", labs((long)delta)); } -- cgit v1.3.1-10-gc9f91