diff --git a/irc/config.go b/irc/config.go index 81f70d1b..1e4ae0a1 100644 --- a/irc/config.go +++ b/irc/config.go @@ -294,9 +294,10 @@ type Config struct { Accounts AccountConfig Channels struct { - DefaultModes *string `yaml:"default-modes"` - defaultModes modes.Modes - Registration ChannelRegistrationConfig + DefaultModes *string `yaml:"default-modes"` + defaultModes modes.Modes + MaxChannelsPerClient int `yaml:"max-channels-per-client"` + Registration ChannelRegistrationConfig } OperClasses map[string]*OperClassConfig `yaml:"oper-classes"` @@ -790,6 +791,9 @@ func LoadConfig(filename string) (config *Config, err error) { config.Accounts.Registration.BcryptCost = passwd.DefaultCost } + if config.Channels.MaxChannelsPerClient == 0 { + config.Channels.MaxChannelsPerClient = 100 + } if config.Channels.Registration.MaxChannelsPerAccount == 0 { config.Channels.Registration.MaxChannelsPerAccount = 10 } diff --git a/irc/getters.go b/irc/getters.go index ff3f8c85..72ef9c89 100644 --- a/irc/getters.go +++ b/irc/getters.go @@ -184,6 +184,12 @@ func (client *Client) Channels() (result []*Channel) { return } +func (client *Client) NumChannels() int { + client.stateMutex.RLock() + defer client.stateMutex.RUnlock() + return len(client.channels) +} + func (client *Client) WhoWas() (result WhoWas) { return client.Details().WhoWas } diff --git a/irc/handlers.go b/irc/handlers.go index 45112aad..394d2676 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -1148,7 +1148,13 @@ func joinHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp keys = strings.Split(msg.Params[1], ",") } + config := server.Config() + oper := client.Oper() for i, name := range channels { + if config.Channels.MaxChannelsPerClient <= client.NumChannels() && oper == nil { + rb.Add(nil, server.name, ERR_UNKNOWNERROR, client.Nick(), name, client.t("You have joined too many channels already")) + return false + } var key string if len(keys) > i { key = keys[i] diff --git a/oragono.yaml b/oragono.yaml index 1f49900b..6f23e243 100644 --- a/oragono.yaml +++ b/oragono.yaml @@ -275,6 +275,9 @@ channels: # see /QUOTE HELP cmodes for more channel modes default-modes: +nt + # how many channels can a client be in at once? + max-channels-per-client: 100 + # channel registration - requires an account registration: # can users register new channels?