From db4b23bb48800a8f181e90ebf2da4a6c0fd66041 Mon Sep 17 00:00:00 2001 From: leah Date: Fri, 13 Jun 2025 19:15:25 +0100 Subject: [PATCH] enforce max-keys --- default.yaml | 2 +- irc/config.go | 2 +- irc/getters.go | 22 ++++++++++++++++++++++ irc/handlers.go | 8 ++++++++ irc/metadata.go | 1 + 5 files changed, 33 insertions(+), 2 deletions(-) diff --git a/default.yaml b/default.yaml index 7eb5f74c..22fd27fd 100644 --- a/default.yaml +++ b/default.yaml @@ -1094,7 +1094,7 @@ metadata: # how many keys can a client subscribe to? # set to 0 to disable subscriptions or -1 to allow unlimited subscriptions. max-subs: 100 - # how many keys can a given target store? set to -1 to allow unlimited keys. + # how many keys can a user store about themselves? set to -1 to allow unlimited keys. max-keys: 1000 # experimental support for mobile push notifications diff --git a/irc/config.go b/irc/config.go index f186850f..37e1fad4 100644 --- a/irc/config.go +++ b/irc/config.go @@ -728,7 +728,7 @@ type Config struct { Enabled bool MaxSubs int `yaml:"max-subs"` MaxKeys int `yaml:"max-keys"` - MaxValueBytes int `yaml:"max-value-length"` + MaxValueBytes int `yaml:"max-value-length"` // todo: currently unenforced!! } WebPush struct { diff --git a/irc/getters.go b/irc/getters.go index 1a0d9f03..4aa8c1fb 100644 --- a/irc/getters.go +++ b/irc/getters.go @@ -935,6 +935,17 @@ func (channel *Channel) ClearMetadata() MetadataStore { return oldMap } +func (channel *Channel) CountMetadata() int { + channel.stateMutex.RLock() + defer channel.stateMutex.RUnlock() + + if channel.metadata == nil { + return 0 + } + + return len(channel.metadata) +} + func (client *Client) GetMetadata(key string) (string, error) { client.stateMutex.RLock() defer client.stateMutex.RUnlock() @@ -982,3 +993,14 @@ func (client *Client) ClearMetadata() MetadataStore { return oldMap } + +func (client *Client) CountMetadata() int { + client.stateMutex.RLock() + defer client.stateMutex.RUnlock() + + if client.metadata == nil { + return 0 + } + + return len(client.metadata) +} diff --git a/irc/handlers.go b/irc/handlers.go index c03bfc18..b53d4f0d 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -3167,6 +3167,14 @@ func metadataHandler(server *Server, client *Client, msg ircmsg.Message, rb *Res return } + maxKeys := server.Config().Metadata.MaxKeys + isSelf := targetClient != nil && client == targetClient + + if isSelf && maxKeys > 0 && t.CountMetadata() >= maxKeys { + rb.Add(nil, server.name, "FAIL", "METADATA", "LIMIT_REACHED", client.nick, client.t("You have too many keys set on yourself")) + return + } + server.logger.Debug("metadata", "setting", key, value, "on", target) t.SetMetadata(key, value) diff --git a/irc/metadata.go b/irc/metadata.go index fdc86b4a..62242cc4 100644 --- a/irc/metadata.go +++ b/irc/metadata.go @@ -23,6 +23,7 @@ type MetadataHaver = interface { DeleteMetadata(key string) ListMetadata() MetadataStore ClearMetadata() MetadataStore + CountMetadata() int } func notifySubscribers(server *Server, session *Session, target string, key string, value string) {