diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/channels.cpp | 2 | ||||
-rw-r--r-- | src/commands/cmd_userhost.cpp | 11 | ||||
-rw-r--r-- | src/configreader.cpp | 1 | ||||
-rw-r--r-- | src/dns.cpp | 8 | ||||
-rw-r--r-- | src/hashcomp.cpp | 4 | ||||
-rw-r--r-- | src/modules/extra/m_ssl_gnutls.cpp | 9 | ||||
-rw-r--r-- | src/modules/m_dccallow.cpp | 6 | ||||
-rw-r--r-- | src/modules/m_md5.cpp | 2 | ||||
-rw-r--r-- | src/modules/m_nationalchars.cpp | 19 | ||||
-rw-r--r-- | src/modules/m_restrictmsg.cpp | 12 | ||||
-rw-r--r-- | src/modules/m_sasl.cpp | 5 | ||||
-rw-r--r-- | src/modules/m_timedbans.cpp | 51 | ||||
-rw-r--r-- | src/usermanager.cpp | 16 | ||||
-rwxr-xr-x | src/version.sh | 2 | ||||
-rw-r--r-- | src/xline.cpp | 3 |
15 files changed, 129 insertions, 22 deletions
diff --git a/src/channels.cpp b/src/channels.cpp index 9f1eafd0c..6802e3d7d 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -412,7 +412,7 @@ Channel* Channel::ForceChan(Channel* Ptr, User* user, const std::string &privs, if (IS_LOCAL(user)) { - if (Ptr->topicset) + if (!Ptr->topic.empty()) { user->WriteNumeric(RPL_TOPIC, "%s %s :%s", user->nick.c_str(), Ptr->name.c_str(), Ptr->topic.c_str()); user->WriteNumeric(RPL_TOPICTIME, "%s %s %s %lu", user->nick.c_str(), Ptr->name.c_str(), Ptr->setby.c_str(), (unsigned long)Ptr->topicset); diff --git a/src/commands/cmd_userhost.cpp b/src/commands/cmd_userhost.cpp index 79685388f..7e1efd637 100644 --- a/src/commands/cmd_userhost.cpp +++ b/src/commands/cmd_userhost.cpp @@ -49,6 +49,8 @@ CmdResult CommandUserhost::Handle (const std::vector<std::string>& parameters, U unsigned int max = parameters.size(); if (max > 5) max = 5; + + bool has_privs = user->HasPrivPermission("users/auspex"); for (unsigned int i = 0; i < max; i++) { User *u = ServerInstance->FindNickOnly(parameters[i]); @@ -58,7 +60,12 @@ CmdResult CommandUserhost::Handle (const std::vector<std::string>& parameters, U retbuf = retbuf + u->nick; if (IS_OPER(u)) - retbuf = retbuf + "*"; + { + // XXX: +H hidden opers must not be shown as opers + ModeHandler* mh = ServerInstance->Modes->FindMode('H', MODETYPE_USER); + if ((u == user) || (has_privs) || (!mh) || (!u->IsModeSet('H')) || (mh->name != "hideoper")) + retbuf += '*'; + } retbuf = retbuf + "="; @@ -69,7 +76,7 @@ CmdResult CommandUserhost::Handle (const std::vector<std::string>& parameters, U retbuf = retbuf + u->ident + "@"; - if (user->HasPrivPermission("users/auspex")) + if (has_privs) { retbuf = retbuf + u->host; } diff --git a/src/configreader.cpp b/src/configreader.cpp index b3caf8c75..bcee938d5 100644 --- a/src/configreader.cpp +++ b/src/configreader.cpp @@ -963,6 +963,7 @@ void ConfigReaderThread::Finish() * XXX: The order of these is IMPORTANT, do not reorder them without testing * thoroughly!!! */ + ServerInstance->Users->RehashCloneCounts(); ServerInstance->XLines->CheckELines(); ServerInstance->XLines->ApplyLines(); ServerInstance->Res->Rehash(); diff --git a/src/dns.cpp b/src/dns.cpp index 75e5731fe..14305ccab 100644 --- a/src/dns.cpp +++ b/src/dns.cpp @@ -700,8 +700,16 @@ DNSResult DNS::GetResult() /* Identical handling to PTR */ case DNS_QUERY_PTR: + { /* Reverse lookups just come back as char* */ resultstr = std::string((const char*)data.first); + if (resultstr.find_first_not_of("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.-") != std::string::npos) + { + std::string ro = req->orig; + delete req; + return DNSResult(this_id | ERROR_MASK, "Invalid char(s) in reply", 0, ro); + } + } break; default: diff --git a/src/hashcomp.cpp b/src/hashcomp.cpp index 3fb7f84fb..e0347421b 100644 --- a/src/hashcomp.cpp +++ b/src/hashcomp.cpp @@ -140,7 +140,7 @@ void nspace::strlower(char *n) * only with *x replaced with national_case_insensitive_map[*x]. * This avoids a copy to use hash<const char*> */ - register size_t t = 0; + size_t t = 0; for (std::string::const_iterator x = s.begin(); x != s.end(); ++x) /* ++x not x++, as its faster */ t = 5 * t + national_case_insensitive_map[(unsigned char)*x]; return t; @@ -149,7 +149,7 @@ void nspace::strlower(char *n) size_t CoreExport irc::hash::operator()(const irc::string &s) const { - register size_t t = 0; + size_t t = 0; for (irc::string::const_iterator x = s.begin(); x != s.end(); ++x) /* ++x not x++, as its faster */ t = 5 * t + national_case_insensitive_map[(unsigned char)*x]; return t; diff --git a/src/modules/extra/m_ssl_gnutls.cpp b/src/modules/extra/m_ssl_gnutls.cpp index 3b67a6180..59ac1acb3 100644 --- a/src/modules/extra/m_ssl_gnutls.cpp +++ b/src/modules/extra/m_ssl_gnutls.cpp @@ -316,7 +316,7 @@ class ModuleSSLGnuTLS : public Module ServerInstance->GenRandom = &randhandler; Implementation eventlist[] = { I_On005Numeric, I_OnRehash, I_OnModuleRehash, I_OnUserConnect, - I_OnEvent, I_OnHookIO }; + I_OnEvent, I_OnHookIO, I_OnCheckReady }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); ServerInstance->Modules->AddService(iohook); @@ -974,6 +974,13 @@ info_done_dealloc: if (starttls.enabled) capHandler.HandleEvent(ev); } + + ModResult OnCheckReady(LocalUser* user) + { + if ((user->eh.GetIOHook() == this) && (sessions[user->eh.GetFd()].status != ISSL_HANDSHAKEN)) + return MOD_RES_DENY; + return MOD_RES_PASSTHRU; + } }; MODULE_INIT(ModuleSSLGnuTLS) diff --git a/src/modules/m_dccallow.cpp b/src/modules/m_dccallow.cpp index b42d12968..829c1d337 100644 --- a/src/modules/m_dccallow.cpp +++ b/src/modules/m_dccallow.cpp @@ -339,6 +339,9 @@ class ModuleDCCAllow : public Module while (ss >> buf) tokens.push_back(buf); + if (tokens.size() < 2) + return MOD_RES_PASSTHRU; + irc::string type = tokens[1].c_str(); ConfigTag* conftag = ServerInstance->Config->ConfValue("dccallow"); @@ -346,6 +349,9 @@ class ModuleDCCAllow : public Module if (type == "SEND") { + if (tokens.size() < 3) + return MOD_RES_PASSTHRU; + std::string defaultaction = conftag->getString("action"); std::string filename = tokens[2]; diff --git a/src/modules/m_md5.cpp b/src/modules/m_md5.cpp index 14ccf16a8..c902ee3cb 100644 --- a/src/modules/m_md5.cpp +++ b/src/modules/m_md5.cpp @@ -163,7 +163,7 @@ class MD5Provider : public HashProvider void MD5Transform(word32 buf[4], word32 const in[16]) { - register word32 a, b, c, d; + word32 a, b, c, d; a = buf[0]; b = buf[1]; 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("<nationalchars:casemapping> 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) diff --git a/src/modules/m_restrictmsg.cpp b/src/modules/m_restrictmsg.cpp index e814f3b16..2a9f1dc93 100644 --- a/src/modules/m_restrictmsg.cpp +++ b/src/modules/m_restrictmsg.cpp @@ -26,15 +26,22 @@ class ModuleRestrictMsg : public Module { + private: + bool uline; public: void init() { - Implementation eventlist[] = { I_OnUserPreMessage, I_OnUserPreNotice }; + OnRehash(NULL); + Implementation eventlist[] = { I_OnRehash, I_OnUserPreMessage, I_OnUserPreNotice }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); } + void OnRehash(User*) + { + uline = ServerInstance->Config->ConfValue("restrictmsg")->getBool("uline", false); + } virtual ModResult OnUserPreMessage(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list) { @@ -45,8 +52,9 @@ class ModuleRestrictMsg : public Module // message allowed if: // (1) the sender is opered // (2) the recipient is opered + // (3) the recipient is on a ulined server // anything else, blocked. - if (IS_OPER(u) || IS_OPER(user)) + if (IS_OPER(u) || IS_OPER(user) || (uline && ServerInstance->ULine(u->server))) { return MOD_RES_PASSTHRU; } diff --git a/src/modules/m_sasl.cpp b/src/modules/m_sasl.cpp index 66efcfe4e..32c9afc79 100644 --- a/src/modules/m_sasl.cpp +++ b/src/modules/m_sasl.cpp @@ -99,6 +99,9 @@ class SaslAuthenticator if (msg[0] != this->agent) return this->state; + if (msg.size() < 4) + return this->state; + if (msg[2] == "C") this->user->Write("AUTHENTICATE %s", msg[3].c_str()); else if (msg[2] == "D") @@ -290,7 +293,7 @@ class ModuleSASL : public Module Version GetVersion() { - return Version("Provides support for IRC Authentication Layer (aka: atheme SASL) via AUTHENTICATE.",VF_VENDOR); + return Version("Provides support for IRC Authentication Layer (aka: SASL) via AUTHENTICATE.", VF_VENDOR); } void OnEvent(Event &ev) diff --git a/src/modules/m_timedbans.cpp b/src/modules/m_timedbans.cpp index 497ac2569..b47327704 100644 --- a/src/modules/m_timedbans.cpp +++ b/src/modules/m_timedbans.cpp @@ -32,6 +32,7 @@ class TimedBan std::string channel; std::string mask; time_t expire; + Channel* chan; }; typedef std::vector<TimedBan> timedbans; @@ -41,6 +42,16 @@ timedbans TimedBanList; */ class CommandTban : public Command { + static bool IsBanSet(Channel* chan, const std::string& mask) + { + for (BanList::const_iterator i = chan->bans.begin(); i != chan->bans.end(); ++i) + { + if (!strcasecmp(i->data.c_str(), mask.c_str())) + return true; + } + return false; + } + public: CommandTban(Module* Creator) : Command(Creator,"TBAN", 3) { @@ -85,19 +96,25 @@ class CommandTban : public Command user->WriteServ("NOTICE "+user->nick+" :Invalid ban mask"); return CMD_FAILURE; } + + if (IsBanSet(channel, mask)) + { + user->WriteServ("NOTICE %s :Ban already set", user->nick.c_str()); + return CMD_FAILURE; + } + setban.push_back(mask); // use CallHandler to make it so that the user sets the mode // themselves ServerInstance->Parser->CallHandler("MODE",setban,user); - for (BanList::iterator i = channel->bans.begin(); i != channel->bans.end(); i++) - if (!strcasecmp(i->data.c_str(), mask.c_str())) - goto found; - return CMD_FAILURE; -found: + if (!IsBanSet(channel, mask)) + return CMD_FAILURE; + CUList tmp; T.channel = channelname; T.mask = mask; T.expire = expire + (IS_REMOTE(user) ? 5 : 0); + T.chan = channel; TimedBanList.push_back(T); // If halfop is loaded, send notice to halfops and above, otherwise send to ops and above @@ -114,6 +131,22 @@ found: } }; +class ChannelMatcher +{ + Channel* const chan; + + public: + ChannelMatcher(Channel* ch) + : chan(ch) + { + } + + bool operator()(const TimedBan& tb) const + { + return (tb.chan == chan); + } +}; + class ModuleTimedBans : public Module { CommandTban cmd; @@ -126,7 +159,7 @@ class ModuleTimedBans : public Module void init() { ServerInstance->Modules->AddService(cmd); - Implementation eventlist[] = { I_OnDelBan, I_OnBackgroundTimer }; + Implementation eventlist[] = { I_OnDelBan, I_OnBackgroundTimer, I_OnChannelDelete }; ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation)); } @@ -183,6 +216,12 @@ class ModuleTimedBans : public Module } } + void OnChannelDelete(Channel* chan) + { + // Remove all timed bans affecting the channel from internal bookkeeping + TimedBanList.erase(std::remove_if(TimedBanList.begin(), TimedBanList.end(), ChannelMatcher(chan)), TimedBanList.end()); + } + virtual Version GetVersion() { return Version("Adds timed bans", VF_COMMON | VF_VENDOR); diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 1918b5c4c..76446c5b5 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -287,6 +287,22 @@ void UserManager::RemoveCloneCounts(User *user) } } +void UserManager::RehashCloneCounts() +{ + local_clones.clear(); + global_clones.clear(); + + const user_hash& hash = *ServerInstance->Users->clientlist; + for (user_hash::const_iterator i = hash.begin(); i != hash.end(); ++i) + { + User* u = i->second; + + if (IS_LOCAL(u)) + AddLocalClone(u); + AddGlobalClone(u); + } +} + unsigned long UserManager::GlobalCloneCount(User *user) { clonemap::iterator x = global_clones.find(user->GetCIDRMask()); diff --git a/src/version.sh b/src/version.sh index 7c54efc71..8686e33ae 100755 --- a/src/version.sh +++ b/src/version.sh @@ -1,2 +1,2 @@ #!/bin/sh -echo "InspIRCd-2.0.18" +echo "InspIRCd-2.0.20" diff --git a/src/xline.cpp b/src/xline.cpp index b710c5c43..66d24f439 100644 --- a/src/xline.cpp +++ b/src/xline.cpp @@ -598,6 +598,9 @@ void GLine::Apply(User* u) bool ELine::Matches(User *u) { + if (u->exempt) + return false; + if (InspIRCd::Match(u->ident, this->identmask, ascii_case_insensitive_map)) { if (InspIRCd::MatchCIDR(u->host, this->hostmask, ascii_case_insensitive_map) || |