From bc621b3612480775c945b10bcc9bd9b7e9739d97 Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 16 Jun 2017 11:39:17 -0400 Subject: chanserv: always lower channel ts to remove ops on new channels --- data/chanserv.example.conf | 7 ----- include/modules/chanserv/channel.h | 3 +++ modules/chanserv/main/channel.cpp | 10 +++++++ modules/chanserv/main/channel.h | 5 +++- modules/chanserv/main/channeltype.cpp | 1 + modules/chanserv/main/channeltype.h | 1 + modules/chanserv/main/chanserv.cpp | 51 +++++++---------------------------- 7 files changed, 29 insertions(+), 49 deletions(-) diff --git a/data/chanserv.example.conf b/data/chanserv.example.conf index e19d67b90..a2bc4360d 100644 --- a/data/chanserv.example.conf +++ b/data/chanserv.example.conf @@ -151,13 +151,6 @@ module * If set, prevents channel access entries from containing hostmasks. */ disallow_hostmask_access = false - - /* - * If set, ChanServ will always lower the timestamp of registered channels to their registration date. - * This prevents several race conditions where unauthorized users can join empty registered channels and set - * modes etc. prior to services deopping them. - */ - always_lower_ts = false } /* diff --git a/include/modules/chanserv/channel.h b/include/modules/chanserv/channel.h index 7c114eea0..a3b06b350 100644 --- a/include/modules/chanserv/channel.h +++ b/include/modules/chanserv/channel.h @@ -40,6 +40,9 @@ class CoreExport Channel : public Serialize::Object virtual time_t GetTimeRegistered() anope_abstract; virtual void SetTimeRegistered(time_t) anope_abstract; + virtual time_t GetChannelTS() anope_abstract; + virtual void SetChannelTS(time_t) anope_abstract; + virtual time_t GetLastUsed() anope_abstract; virtual void SetLastUsed(time_t) anope_abstract; diff --git a/modules/chanserv/main/channel.cpp b/modules/chanserv/main/channel.cpp index 5f7c71c8c..a2d56b6ec 100644 --- a/modules/chanserv/main/channel.cpp +++ b/modules/chanserv/main/channel.cpp @@ -81,6 +81,16 @@ void ChannelImpl::SetTimeRegistered(time_t t) Set(&ChannelType::time_registered, t); } +time_t ChannelImpl::GetChannelTS() +{ + return Get(&ChannelType::channel_ts); +} + +void ChannelImpl::SetChannelTS(time_t t) +{ + Set(&ChannelType::channel_ts, t); +} + time_t ChannelImpl::GetLastUsed() { return Get(&ChannelType::last_used); diff --git a/modules/chanserv/main/channel.h b/modules/chanserv/main/channel.h index eebddf91b..1fe9273c7 100644 --- a/modules/chanserv/main/channel.h +++ b/modules/chanserv/main/channel.h @@ -23,7 +23,7 @@ class ChannelImpl : public ChanServ::Channel Serialize::Storage founder, successor; Serialize::Storage name, desc; - Serialize::Storage time_registered, last_used; + Serialize::Storage time_registered, channel_ts, last_used; Serialize::Storage last_topic, last_topic_setter; Serialize::Storage last_topic_time; Serialize::Storage bantype; @@ -59,6 +59,9 @@ class ChannelImpl : public ChanServ::Channel time_t GetTimeRegistered() override; void SetTimeRegistered(time_t) override; + time_t GetChannelTS() override; + void SetChannelTS(time_t) override; + time_t GetLastUsed() override; void SetLastUsed(time_t) override; diff --git a/modules/chanserv/main/channeltype.cpp b/modules/chanserv/main/channeltype.cpp index ca74263cd..e3de67357 100644 --- a/modules/chanserv/main/channeltype.cpp +++ b/modules/chanserv/main/channeltype.cpp @@ -24,6 +24,7 @@ ChannelType::ChannelType(Module *me) : Serialize::Type(me) , name(this, "name", &ChannelImpl::name) , desc(this, "desc", &ChannelImpl::desc) , time_registered(this, "time_registered", &ChannelImpl::time_registered) + , channel_ts(this, "channel_ts", &ChannelImpl::channel_ts) , last_used(this, "last_used", &ChannelImpl::last_used) , last_topic(this, "last_topic", &ChannelImpl::last_topic) , last_topic_setter(this, "last_topic_setter", &ChannelImpl::last_topic_setter) diff --git a/modules/chanserv/main/channeltype.h b/modules/chanserv/main/channeltype.h index af4bc6cc9..c8515b289 100644 --- a/modules/chanserv/main/channeltype.h +++ b/modules/chanserv/main/channeltype.h @@ -31,6 +31,7 @@ class ChannelType : public Serialize::Type } name; Serialize::Field desc; Serialize::Field time_registered; + Serialize::Field channel_ts; Serialize::Field last_used; Serialize::Field last_topic; diff --git a/modules/chanserv/main/chanserv.cpp b/modules/chanserv/main/chanserv.cpp index 31f0c2c88..17716c3d4 100644 --- a/modules/chanserv/main/chanserv.cpp +++ b/modules/chanserv/main/chanserv.cpp @@ -47,14 +47,11 @@ class ChanServCore : public Module , public EventHook , public EventHook , public EventHook - , public EventHook , public EventHook - , public EventHook { Reference ChanServ; std::vector defaults; ExtensibleItem inhabit; - bool always_lower; std::vector Privileges; ChanServ::registered_channel_map registered_channels; ChannelType channel_type; @@ -79,11 +76,8 @@ class ChanServCore : public Module , EventHook(this) , EventHook(this) , EventHook(this) - , EventHook(this) , EventHook(this) - , EventHook(this) , inhabit(this, "inhabit") - , always_lower(false) , channel_type(this) , level_type(this) , mode_type(this) @@ -252,8 +246,6 @@ class ChanServCore : public Module defaults = { "keeptopic", "secure", "securefounder", "signkick" }; else if (defaults[0].equals_ci("none")) defaults.clear(); - - always_lower = conf->GetModule(this)->Get("always_lower_ts"); } void OnChannelCreate(Channel *c) override @@ -522,34 +514,22 @@ class ChanServCore : public Module void OnJoinChannel(User *u, Channel *c) override { - if (always_lower && c->ci && c->creation_time > c->ci->GetTimeRegistered()) + if (!c->ci) + return; + + time_t ts = c->ci->GetChannelTS(); + if (ts == 0) + ts = c->ci->GetTimeRegistered(); + + if (c->creation_time > ts) { - logger.Debug("Changing TS of {0} from {1} to {2}", c->name, c->creation_time, c->ci->GetTimeRegistered()); - c->creation_time = c->ci->GetTimeRegistered(); + logger.Debug("Changing TS of {0} from {1} to {2}", c->name, c->creation_time, ts); + c->creation_time = ts; IRCD->Send(c); c->Reset(); } } - EventReturn OnChannelModeSet(Channel *c, const MessageSource &setter, ChannelMode *mode, const Anope::string ¶m) override - { - if (!always_lower && Anope::CurTime == c->creation_time && c->ci && setter.GetUser() && !setter.GetUser()->server->IsULined()) - { - ChanUserContainer *cu = c->FindUser(setter.GetUser()); - ChannelMode *cm = ModeManager::FindChannelModeByName("OP"); - if (cu && cm && !cu->status.HasMode(cm->mchar)) - { - /* Our -o and their mode change crossing, bounce their mode */ - c->RemoveMode(nullptr, mode, param); - /* We don't set mlocks until after the join has finished processing, it will stack with this change, - * so there isn't much for the user to remove except -nt etc which is likely locked anyway. - */ - } - } - - return EVENT_CONTINUE; - } - void OnChanInfo(CommandSource &source, ChanServ::Channel *ci, InfoFormatter &info, bool show_all) override { if (!show_all) @@ -559,17 +539,6 @@ class ChanServCore : public Module if (!ci->IsNoExpire() && chanserv_expire && !Anope::NoExpire && ci->GetLastUsed() != Anope::CurTime) info[_("Expires")] = Anope::strftime(ci->GetLastUsed() + chanserv_expire, source.GetAccount()); } - - void OnSetCorrectModes(User *user, Channel *chan, ChanServ::AccessGroup &access, bool &give_modes, bool &take_modes) override - { - if (always_lower) - // Since we always lower the TS, the other side will remove the modes if the channel ts lowers, so we don't - // have to worry about it - take_modes = false; - else if (ModeManager::FindChannelModeByName("REGISTERED")) - // Otherwise if the registered channel mode exists, we should remove modes if the channel is not +r - take_modes = !chan->HasMode("REGISTERED"); - } }; MODULE_INIT(ChanServCore) -- cgit