From 8ffce4d2f3ab29677b466238ce900a85b6c9d693 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Tue, 9 Jun 2015 20:11:20 +0100 Subject: Fix various issues with the nationalchars module. - Strip the directory name in the default casemapping value. - Error out if the casemapping value contains a space. - Error out if the locale file failed to load. - Fix relative file path when building on Windows. - Install nationalchars files on Windows. --- src/modules/m_nationalchars.cpp | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'src/modules') diff --git a/src/modules/m_nationalchars.cpp b/src/modules/m_nationalchars.cpp index bf95f0f9f..bc90c9fad 100644 --- a/src/modules/m_nationalchars.cpp +++ b/src/modules/m_nationalchars.cpp @@ -284,11 +284,19 @@ class ModuleNationalChars : public Module { ConfigTag* tag = ServerInstance->Config->ConfValue("nationalchars"); charset = tag->getString("file"); - casemapping = tag->getString("casemapping", charset); + casemapping = tag->getString("casemapping", ServerConfig::CleanFilename(charset.c_str())); + if (casemapping.find(' ') != std::string::npos) + throw ModuleException(" must not contain any spaces!"); +#if defined _WIN32 + if (!ServerInstance->Config->StartsWithWindowsDriveLetter(charset)) + charset.insert(0, "./locales/"); +#else if(charset[0] != '/') charset.insert(0, "../locales/"); +#endif unsigned char * tables[8] = { m_additional, m_additionalMB, m_additionalUp, m_lower, m_upper, m_additionalUtf8, m_additionalUtf8range, m_additionalUtf8interval }; - loadtables(charset, tables, 8, 5); + if (!loadtables(charset, tables, 8, 5)) + throw ModuleException("The locale file failed to load. Check your log file for more information."); forcequit = tag->getBool("forcequit"); CheckForceQuit("National character set changed"); CheckRehash(); @@ -330,13 +338,13 @@ class ModuleNationalChars : public Module } /*so Bynets Unreal distribution stuff*/ - void loadtables(std::string filename, unsigned char ** tables, unsigned char cnt, char faillimit) + bool loadtables(std::string filename, unsigned char ** tables, unsigned char cnt, char faillimit) { std::ifstream ifs(filename.c_str()); if (ifs.fail()) { ServerInstance->Logs->Log("m_nationalchars",DEFAULT,"loadtables() called for missing file: %s", filename.c_str()); - return; + return false; } for (unsigned char n=0; n< cnt; n++) @@ -351,11 +359,12 @@ class ModuleNationalChars : public Module if (loadtable(ifs, tables[n], 255) && (n < faillimit)) { ServerInstance->Logs->Log("m_nationalchars",DEFAULT,"loadtables() called for illegal file: %s (line %d)", filename.c_str(), n+1); - return; + return false; } } makereverse(m_additional, m_reverse_additional, sizeof(m_additional)); + return true; } unsigned char symtoi(const char *t,unsigned char base) -- cgit v1.2.3 From b2db94675b1881ab40f2e6c625f716f79e1efcc4 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 28 Sep 2015 10:36:17 +0200 Subject: Fix incorrect std::string::operator[] usage Passing a position equal to length() to the non-const version of operator[] is undefined --- src/modules/m_check.cpp | 2 +- src/modules/m_namedmodes.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/m_check.cpp b/src/modules/m_check.cpp index 9c5c414f1..5063368b8 100644 --- a/src/modules/m_check.cpp +++ b/src/modules/m_check.cpp @@ -174,7 +174,7 @@ class CommandCheck : public Command /* /check on a channel */ user->SendText(checkstr + " timestamp " + timestring(targchan->age)); - if (targchan->topic[0] != 0) + if (!targchan->topic.empty()) { /* there is a topic, assume topic related information exists */ user->SendText(checkstr + " topic " + targchan->topic); diff --git a/src/modules/m_namedmodes.cpp b/src/modules/m_namedmodes.cpp index 4db1f70b9..cad18cff4 100644 --- a/src/modules/m_namedmodes.cpp +++ b/src/modules/m_namedmodes.cpp @@ -65,6 +65,8 @@ class CommandProp : public Command while (i < parameters.size()) { std::string prop = parameters[i++]; + if (prop.empty()) + continue; bool plus = prop[0] != '-'; if (prop[0] == '+' || prop[0] == '-') prop.erase(prop.begin()); -- cgit v1.2.3 From 91fe9afed5ee65f1d6dc1d0d3cdee628125f4d0d Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Mon, 23 Nov 2015 10:53:30 +0100 Subject: m_operprefix Unset mode on unload Fixes issue #1109 reported by @Sheogorath-SI --- src/modules/m_operprefix.cpp | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'src/modules') diff --git a/src/modules/m_operprefix.cpp b/src/modules/m_operprefix.cpp index 9f1f6cc5e..7d5e6d118 100644 --- a/src/modules/m_operprefix.cpp +++ b/src/modules/m_operprefix.cpp @@ -58,6 +58,39 @@ class OperPrefixMode : public ModeHandler } bool NeedsOper() { return true; } + + void RemoveMode(Channel* chan, irc::modestacker* stack) + { + irc::modestacker modestack(false); + const UserMembList* users = chan->GetUsers(); + for (UserMembCIter i = users->begin(); i != users->end(); ++i) + { + if (i->second->hasMode(mode)) + { + if (stack) + stack->Push(this->GetModeChar(), i->first->nick); + else + modestack.Push(this->GetModeChar(), i->first->nick); + } + } + + if (stack) + return; + + std::deque stackresult; + std::vector mode_junk; + mode_junk.push_back(chan->name); + while (modestack.GetStackedLine(stackresult)) + { + mode_junk.insert(mode_junk.end(), stackresult.begin(), stackresult.end()); + ServerInstance->SendMode(mode_junk, ServerInstance->FakeClient); + mode_junk.erase(mode_junk.begin() + 1, mode_junk.end()); + } + } + + void RemoveMode(User* user, irc::modestacker* stack) + { + } }; class ModuleOperPrefixMode; -- cgit v1.2.3 From be0d7ab72ab276f63eacc5c6600ea13e9dc0666c Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Thu, 26 Nov 2015 04:07:50 +0000 Subject: Fix CAP REQ to be atomic like the standard dictates. Reported by @dequis on IRC. --- src/modules/m_cap.cpp | 16 ++++++++-------- src/modules/m_cap.h | 5 ++++- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'src/modules') diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp index e9f4dae90..37478243f 100644 --- a/src/modules/m_cap.cpp +++ b/src/modules/m_cap.cpp @@ -72,17 +72,17 @@ class CommandCAP : public Command reghold.set(user, 1); Data.Send(); - if (Data.ack.size() > 0) + if (Data.wanted.empty()) { - std::string AckResult = irc::stringjoiner(" ", Data.ack, 0, Data.ack.size() - 1).GetJoined(); - user->WriteServ("CAP %s ACK :%s", user->nick.c_str(), AckResult.c_str()); + user->WriteServ("CAP %s ACK :%s", user->nick.c_str(), parameters[1].c_str()); + return CMD_SUCCESS; } - if (Data.wanted.size() > 0) - { - std::string NakResult = irc::stringjoiner(" ", Data.wanted, 0, Data.wanted.size() - 1).GetJoined(); - user->WriteServ("CAP %s NAK :%s", user->nick.c_str(), NakResult.c_str()); - } + // HACK: reset all of the caps which were enabled on this user because a cap request is atomic. + for (std::vector >::iterator iter = Data.changed.begin(); iter != Data.changed.end(); ++iter) + iter->first->ext.set(user, iter->second); + + user->WriteServ("CAP %s NAK :%s", user->nick.c_str(), parameters[1].c_str()); } else if (subcommand == "END") { diff --git a/src/modules/m_cap.h b/src/modules/m_cap.h index 409671f48..23cf8cf69 100644 --- a/src/modules/m_cap.h +++ b/src/modules/m_cap.h @@ -21,6 +21,8 @@ #ifndef M_CAP_H #define M_CAP_H +class GenericCap; + class CapEvent : public Event { public: @@ -35,6 +37,7 @@ class CapEvent : public Event CapEventType type; std::vector wanted; std::vector ack; + std::vector > changed; // HACK: clean this up before 2.2 User* user; CapEvent(Module* sender, User* u, CapEventType capevtype) : Event(sender, "cap_request"), type(capevtype), user(u) {} }; @@ -67,7 +70,7 @@ class GenericCap // we can handle this, so ACK it, and remove it from the wanted list data->ack.push_back(*it); data->wanted.erase(it); - ext.set(data->user, enablecap ? 1 : 0); + data->changed.push_back(std::make_pair(this, ext.set(data->user, enablecap ? 1 : 0))); break; } } -- cgit v1.2.3 From e114a7ec08836cdd8c005f320a7f372435b33786 Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Mon, 7 Dec 2015 09:48:33 +0000 Subject: Work around irc::spacesepstream not stripping extraneous spaces. --- src/modules/m_cap.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/m_cap.cpp b/src/modules/m_cap.cpp index 37478243f..6b4387fdd 100644 --- a/src/modules/m_cap.cpp +++ b/src/modules/m_cap.cpp @@ -66,7 +66,12 @@ class CommandCAP : public Command while (cap_stream.GetToken(cap_)) { - Data.wanted.push_back(cap_); + // Whilst the handling of extraneous spaces is not currently defined in the CAP specification + // every single other implementation ignores extraneous spaces. Lets copy them for + // compatibility purposes. + trim(cap_); + if (!cap_.empty()) + Data.wanted.push_back(cap_); } reghold.set(user, 1); -- cgit v1.2.3 From dbb7672c6ae643a997098566f59882d5e4632c88 Mon Sep 17 00:00:00 2001 From: Adam Date: Thu, 11 Feb 2016 08:14:07 -0500 Subject: Update m_ssl_gnutls to use libgnutls-30 for gnutls 3.4 --- src/modules/extra/m_ssl_gnutls.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 59ac1acb3..813a8ecfa 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -28,7 +28,7 @@ #include "m_cap.h" #ifdef _WIN32 -# pragma comment(lib, "libgnutls-28.lib") +# pragma comment(lib, "libgnutls-30.lib") #endif /* $ModDesc: Provides SSL support for clients */ -- cgit v1.2.3 From 4e70a39299df540d8fece60b33ac75f31624b3ed Mon Sep 17 00:00:00 2001 From: Peter Powell Date: Sat, 4 Jul 2015 11:56:15 +0100 Subject: Fix hidden operators being shown in LUSERS. --- src/modules/m_hideoper.cpp | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/m_hideoper.cpp b/src/modules/m_hideoper.cpp index 88b0c4cdf..9d50bd2e5 100644 --- a/src/modules/m_hideoper.cpp +++ b/src/modules/m_hideoper.cpp @@ -28,25 +28,43 @@ class HideOper : public SimpleUserModeHandler { public: + size_t opercount; + HideOper(Module* Creator) : SimpleUserModeHandler(Creator, "hideoper", 'H') + , opercount(0) { oper = true; } + + ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) + { + if (SimpleUserModeHandler::OnModeChange(source, dest, channel, parameter, adding) == MODEACTION_DENY) + return MODEACTION_DENY; + + if (adding) + opercount++; + else + opercount--; + + return MODEACTION_ALLOW; + } }; class ModuleHideOper : public Module { HideOper hm; + bool active; public: ModuleHideOper() : hm(this) + , active(false) { } void init() { ServerInstance->Modules->AddService(hm); - Implementation eventlist[] = { I_OnWhoisLine, I_OnSendWhoLine, I_OnStats }; + Implementation eventlist[] = { I_OnWhoisLine, I_OnSendWhoLine, I_OnStats, I_OnNumeric, I_OnUserQuit }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); } @@ -60,6 +78,28 @@ class ModuleHideOper : public Module return Version("Provides support for hiding oper status with user mode +H", VF_VENDOR); } + void OnUserQuit(User* user, const std::string&, const std::string&) + { + if (user->IsModeSet('H')) + hm.opercount--; + } + + ModResult OnNumeric(User* user, unsigned int numeric, const std::string& text) + { + if (numeric != 252 || active || user->HasPrivPermission("users/auspex")) + return MOD_RES_PASSTHRU; + + // If there are no visible operators then we shouldn't send the numeric. + size_t opercount = ServerInstance->Users->all_opers.size() - hm.opercount; + if (opercount) + { + active = true; + user->WriteNumeric(252, "%s %lu :operator(s) online", user->nick.c_str(), opercount); + active = false; + } + return MOD_RES_DENY; + } + ModResult OnWhoisLine(User* user, User* dest, int &numeric, std::string &text) { /* Dont display numeric 313 (RPL_WHOISOPER) if they have +H set and the -- cgit v1.2.3 From bbd8815115acc7e463daa0f7bcd156cb3e51e6d5 Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Fri, 12 Feb 2016 18:20:07 +0100 Subject: m_ircv3 Fix AWAY being sent on join to the joining user if it has away-notify enabled and is away --- src/modules/m_ircv3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/m_ircv3.cpp b/src/modules/m_ircv3.cpp index da42d823d..b7dd0e81b 100644 --- a/src/modules/m_ircv3.cpp +++ b/src/modules/m_ircv3.cpp @@ -222,7 +222,7 @@ class ModuleIRCv3 : public Module { // Send the away notify line if the current member is local, has the away-notify cap and isn't excepted User* member = IS_LOCAL(it->first); - if ((member) && (cap_awaynotify.ext.get(member)) && (last_excepts.find(member) == last_excepts.end())) + if ((member) && (cap_awaynotify.ext.get(member)) && (last_excepts.find(member) == last_excepts.end()) && (it->second != memb)) { member->Write(line); } -- cgit v1.2.3 From 748b3a0d89e7ecc9a766471b79fb78f63a5ca2bb Mon Sep 17 00:00:00 2001 From: Attila Molnar Date: Fri, 12 Feb 2016 18:30:01 +0100 Subject: m_dccallow Add config option to control max entries on a list Default to 20 --- docs/conf/modules.conf.example | 3 ++- src/modules/m_dccallow.cpp | 11 ++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/modules') diff --git a/docs/conf/modules.conf.example b/docs/conf/modules.conf.example index 98b614acd..97d69da90 100644 --- a/docs/conf/modules.conf.example +++ b/docs/conf/modules.conf.example @@ -671,6 +671,7 @@ # length - Default duration of entries in DCCALLOW list. # action - Default action to take if no action is # specified, can be 'block' or 'allow'. +# maxentries - Max number of nicks to allow on a DCCALLOW list. # # File configuration: # pattern - The glob pattern to match against. @@ -678,7 +679,7 @@ # that matches this pattern, can be 'block' or # 'allow'. # -# +# # # diff --git a/src/modules/m_dccallow.cpp b/src/modules/m_dccallow.cpp index 829c1d337..043486283 100644 --- a/src/modules/m_dccallow.cpp +++ b/src/modules/m_dccallow.cpp @@ -58,6 +58,7 @@ SimpleExtItem* ext; class CommandDccallow : public Command { public: + unsigned int maxentries; CommandDccallow(Module* parent) : Command(parent, "DCCALLOW", 0) { syntax = "[(+|-) [