From 96befc58f073b4f96771b57d728b16742294c2fe Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 22 Dec 2020 03:53:00 +0000 Subject: Send RPL_SAVENICK from irc2 when renaming a user to their UUID. --- src/modules/m_codepage.cpp | 3 +++ src/modules/m_spanningtree/svsnick.cpp | 1 + 2 files changed, 4 insertions(+) (limited to 'src/modules') diff --git a/src/modules/m_codepage.cpp b/src/modules/m_codepage.cpp index 7a20e6e52..4054c72c1 100644 --- a/src/modules/m_codepage.cpp +++ b/src/modules/m_codepage.cpp @@ -83,7 +83,10 @@ class ModuleCodepage { LocalUser* user = *iter; if (user->nick != user->uuid && !ServerInstance->IsNick(user->nick)) + { + user->WriteNumeric(RPL_SAVENICK, user->uuid, "Your nickname is no longer valid."); user->ChangeNick(user->uuid); + } } } diff --git a/src/modules/m_spanningtree/svsnick.cpp b/src/modules/m_spanningtree/svsnick.cpp index e9292f445..8d1bc80ba 100644 --- a/src/modules/m_spanningtree/svsnick.cpp +++ b/src/modules/m_spanningtree/svsnick.cpp @@ -67,6 +67,7 @@ CmdResult CommandSVSNick::Handle(User* user, Params& parameters) if (!u->ChangeNick(nick, NickTS)) { // Changing to 'nick' failed (it may already be in use), change to the uuid + u->WriteNumeric(RPL_SAVENICK, u->uuid, "Your nickname is in use by an older user on a new server."); u->ChangeNick(u->uuid); } } -- cgit v1.3.1-10-gc9f91 From 79cc3caeb8f485ab0bdc405ab4ead54a25ab097c Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 22 Dec 2020 04:10:07 +0000 Subject: After changing the codepage rename duplicate users to their UUID. --- src/modules/m_codepage.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/modules') diff --git a/src/modules/m_codepage.cpp b/src/modules/m_codepage.cpp index 4054c72c1..45fdb3d83 100644 --- a/src/modules/m_codepage.cpp +++ b/src/modules/m_codepage.cpp @@ -76,6 +76,21 @@ class ModuleCodepage hashmap.swap(newhash); } + void CheckDuplicateNick() + { + insp::flat_set duplicates; + const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers(); + for (UserManager::LocalList::const_iterator iter = list.begin(); iter != list.end(); ++iter) + { + LocalUser* user = *iter; + if (user->nick != user->uuid && !duplicates.insert(user->nick).second) + { + user->WriteNumeric(RPL_SAVENICK, user->uuid, "Your nickname is no longer available."); + user->ChangeNick(user->uuid); + } + } + } + void CheckInvalidNick() { const UserManager::LocalList& list = ServerInstance->Users.GetLocalUsers(); @@ -115,6 +130,7 @@ class ModuleCodepage ServerInstance->Config->CaseMapping = origcasemapname; national_case_insensitive_map = origcasemap; + CheckDuplicateNick(); CheckRehash(casemap); ServerInstance->ISupport.Build(); -- cgit v1.3.1-10-gc9f91 From 744efed4e2ca5b1957e541238ed14e9931019479 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Tue, 22 Dec 2020 05:48:53 +0000 Subject: Add support for multiple hostmasks in . --- docs/conf/modules.conf.example | 21 +++++++------ src/modules/m_cgiirc.cpp | 70 +++++++++++++++++++++++++----------------- 2 files changed, 52 insertions(+), 39 deletions(-) (limited to 'src/modules') diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index 7b80c902b..30082ead2 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -375,14 +375,14 @@ # message to the server on connection. For more details please read the # IRCv3 WebIRC specification at: https://ircv3.net/specs/extensions/webirc.html # -# When using this method you must specify a wildcard mask or CIDR range -# to allow gateway connections from and at least one of either a TLS (SSL) -# client certificate fingerprint for the gateway or a password to be -# sent in the WEBIRC command. +# When using this method you must specify one or more wildcard masks +# or CIDR ranges to allow gateway connections from and at least one of +# either a TLS (SSL) client certificate fingerprint for the gateway or +# a password to be sent in the WEBIRC command. # # +# mask="192.0.2.0/24 198.51.100.*"> # # MaskList; + // Encapsulates information about an ident host. class IdentHost { private: - std::string hostmask; + MaskList hostmasks; std::string newident; public: - IdentHost(const std::string& mask, const std::string& ident) - : hostmask(mask) + IdentHost(const MaskList& masks, const std::string& ident) + : hostmasks(masks) , newident(ident) { } @@ -60,10 +63,19 @@ class IdentHost bool Matches(LocalUser* user) const { - if (!InspIRCd::Match(user->GetRealHost(), hostmask, ascii_case_insensitive_map)) - return false; + for (MaskList::const_iterator iter = hostmasks.begin(); iter != hostmasks.end(); ++iter) + { + // Does the user's hostname match this hostmask? + if (InspIRCd::Match(user->GetRealHost(), *iter, ascii_case_insensitive_map)) + return true; - return InspIRCd::MatchCIDR(user->GetIPString(), hostmask, ascii_case_insensitive_map); + // Does the user's IP address match this hostmask? + if (InspIRCd::MatchCIDR(user->GetIPString(), *iter, ascii_case_insensitive_map)) + return true; + } + + // The user didn't match any hostmasks. + return false; } }; @@ -71,14 +83,14 @@ class IdentHost class WebIRCHost { private: - std::string hostmask; + MaskList hostmasks; std::string fingerprint; std::string password; std::string passhash; public: - WebIRCHost(const std::string& mask, const std::string& fp, const std::string& pass, const std::string& hash) - : hostmask(mask) + WebIRCHost(const MaskList& masks, const std::string& fp, const std::string& pass, const std::string& hash) + : hostmasks(masks) , fingerprint(fp) , password(pass) , passhash(hash) @@ -96,26 +108,22 @@ class WebIRCHost if (!fingerprint.empty() && !InspIRCd::TimingSafeCompare(fp, fingerprint)) return false; - // Does the user's hostname match our hostmask? - if (InspIRCd::Match(user->GetRealHost(), hostmask, ascii_case_insensitive_map)) - return true; + for (MaskList::const_iterator iter = hostmasks.begin(); iter != hostmasks.end(); ++iter) + { + // Does the user's hostname match this hostmask? + if (InspIRCd::Match(user->GetRealHost(), *iter, ascii_case_insensitive_map)) + return true; + + // Does the user's IP address match this hostmask? + if (InspIRCd::MatchCIDR(user->GetIPString(), *iter, ascii_case_insensitive_map)) + return true; + } - // Does the user's IP address match our hostmask? - return InspIRCd::MatchCIDR(user->GetIPString(), hostmask, ascii_case_insensitive_map); + // The user didn't match any hostmasks. + return false; } }; -/* - * WEBIRC - * This is used for the webirc method of CGIIRC auth, and is (really) the best way to do these things. - * Syntax: WEBIRC password gateway hostname ip - * Where password is a shared key, gateway is the name of the WebIRC gateway and version (e.g. cgiirc), hostname - * is the resolved host of the client issuing the command and IP is the real IP of the client. - * - * How it works: - * To tie in with the rest of cgiirc module, and to avoid race conditions, /webirc is only processed locally - * and simply sets metadata on the user, which is later decoded on full connect to give something meaningful. - */ class CommandWebIRC : public SplitCommand { public: @@ -289,9 +297,13 @@ class ModuleCgiIRC { ConfigTag* tag = i->second; + MaskList masks; + irc::spacesepstream maskstream(tag->getString("mask")); + for (std::string mask; maskstream.GetToken(mask); ) + masks.push_back(mask); + // Ensure that we have the parameter. - const std::string mask = tag->getString("mask"); - if (mask.empty()) + if (masks.empty()) throw ModuleException(" is a mandatory field, at " + tag->getTagLocation()); // Determine what lookup type this host uses. @@ -300,7 +312,7 @@ class ModuleCgiIRC { // The IP address should be looked up from the hex IP address. const std::string newident = tag->getString("newident", "gateway", ServerInstance->IsIdent); - identhosts.push_back(IdentHost(mask, newident)); + identhosts.push_back(IdentHost(masks, newident)); } else if (stdalgo::string::equalsci(type, "webirc")) { @@ -319,7 +331,7 @@ class ModuleCgiIRC tag->getTagLocation().c_str()); } - webirchosts.push_back(WebIRCHost(mask, fingerprint, password, passwordhash)); + webirchosts.push_back(WebIRCHost(masks, fingerprint, password, passwordhash)); } else { -- cgit v1.3.1-10-gc9f91 From 71ad7b2cd22ace30dae3506a39858c804e7f1895 Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Fri, 25 Dec 2020 03:42:11 +0000 Subject: Replace spaces with underscores when checking for class bans. --- src/modules/m_classban.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/m_classban.cpp b/src/modules/m_classban.cpp index 89cbf0efe..b2cbb1e59 100644 --- a/src/modules/m_classban.cpp +++ b/src/modules/m_classban.cpp @@ -22,14 +22,28 @@ class ModuleClassBan : public Module { + private: + std::string space; + std::string underscore; + public: + ModuleClassBan() + : space(" ") + , underscore("_") + { + } + ModResult OnCheckBan(User* user, Channel* c, const std::string& mask) CXX11_OVERRIDE { LocalUser* localUser = IS_LOCAL(user); if ((localUser) && (mask.length() > 2) && (mask[0] == 'n') && (mask[1] == ':')) { - if (InspIRCd::Match(localUser->GetClass()->name, mask.substr(2))) + // Replace spaces with underscores as they're prohibited in mode parameters. + std::string classname(localUser->GetClass()->name); + stdalgo::string::replace_all(classname, space, underscore); + if (InspIRCd::Match(classname, mask.substr(2))) return MOD_RES_DENY; + } return MOD_RES_PASSTHRU; } -- cgit v1.3.1-10-gc9f91 From bf3bfec6d58f566b98eb09ba0bf83d6a46ca400f Mon Sep 17 00:00:00 2001 From: Sadie Powell Date: Fri, 25 Dec 2020 03:46:43 +0000 Subject: Avoid doing more work than necessary when checking the O: extban. --- src/modules/m_operchans.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'src/modules') diff --git a/src/modules/m_operchans.cpp b/src/modules/m_operchans.cpp index 072595269..f133d85f7 100644 --- a/src/modules/m_operchans.cpp +++ b/src/modules/m_operchans.cpp @@ -66,15 +66,10 @@ class ModuleOperChans : public Module if (!user->IsOper()) return MOD_RES_PASSTHRU; - // Check whether the oper's type matches the ban. - const std::string submask = mask.substr(2); - if (InspIRCd::Match(user->oper->name, submask)) - return MOD_RES_DENY; - - // If the oper's type contains spaces recheck with underscores. + // Replace spaces with underscores as they're prohibited in mode parameters. std::string opername(user->oper->name); stdalgo::string::replace_all(opername, space, underscore); - if (InspIRCd::Match(opername, submask)) + if (InspIRCd::Match(opername, mask.substr(2))) return MOD_RES_DENY; return MOD_RES_PASSTHRU; -- cgit v1.3.1-10-gc9f91 From e8f3587b80c26ee4fbd160db9a83ed8914a63e22 Mon Sep 17 00:00:00 2001 From: Matt Schatz Date: Wed, 30 Dec 2020 09:55:28 -0700 Subject: Disallow an empty last parameter in MAP. --- src/modules/m_spanningtree/override_map.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/modules') diff --git a/src/modules/m_spanningtree/override_map.cpp b/src/modules/m_spanningtree/override_map.cpp index 5122fd0ed..edc4b0a12 100644 --- a/src/modules/m_spanningtree/override_map.cpp +++ b/src/modules/m_spanningtree/override_map.cpp @@ -36,6 +36,7 @@ CommandMap::CommandMap(Module* Creator) : Command(Creator, "MAP", 0, 1) { + allow_empty_last_param = false; Penalty = 2; } -- cgit v1.3.1-10-gc9f91