Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ server:
max-connections-per-duration: 64

# strict transport security, to get clients to automagically use TLS
# (irrelevant in the recommended configuration, with no public plaintext listener)
sts:
# whether to advertise STS
#
Expand Down Expand Up @@ -375,6 +376,12 @@ server:
# if you don't want to publicize how popular the server is
suppress-lusers: false

# publish additional key-value pairs in ISUPPORT (the 005 numeric).
# keys that collide with a key published by Ergo will be silently ignored.
additional-isupport:
#"draft/FILEHOST": "https://example.com/filehost"
#"draft/bazbat": "" # empty string means no value

# optionally map command alias names to existing ergo commands. most deployments
# should ignore this.
#command-aliases:
Expand Down
7 changes: 7 additions & 0 deletions irc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,7 @@ type Config struct {
OverrideServicesHostname string `yaml:"override-services-hostname"`
MaxLineLen int `yaml:"max-line-len"`
SuppressLusers bool `yaml:"suppress-lusers"`
AdditionalISupport map[string]string `yaml:"additional-isupport"`
CommandAliases map[string]string `yaml:"command-aliases"`
}

Expand Down Expand Up @@ -1778,6 +1779,12 @@ func (config *Config) generateISupport() (err error) {
}
isupport.Add("WHOX", "")

for key, value := range config.Server.AdditionalISupport {
if !isupport.Contains(key) {
isupport.Add(key, value)
}
}

err = isupport.RegenerateCachedReply()
return
}
Expand Down
32 changes: 28 additions & 4 deletions irc/isupport/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ func (il *List) AddNoValue(name string) {
il.Tokens[name] = ""
}

// Contains returns whether the list already contains a token
func (il *List) Contains(name string) bool {
_, ok := il.Tokens[name]
return ok
}

// getTokenString gets the appropriate string for a token+value.
func getTokenString(name string, value string) string {
if len(value) == 0 {
Expand Down Expand Up @@ -115,16 +121,34 @@ func (il *List) GetDifference(newil *List) [][]string {
return replies
}

func validateToken(token string) error {
if len(token) == 0 || token[0] == ':' || strings.Contains(token, " ") {
return fmt.Errorf("bad isupport token (cannot be sent as IRC parameter): `%s`", token)
}

if strings.ContainsAny(token, "\n\r\x00") {
return fmt.Errorf("bad isupport token (contains forbidden octets)")
}

// technically a token can be maxLastArgLength if it occurs alone,
// but fail it just to be safe
if len(token) >= maxLastArgLength {
return fmt.Errorf("bad isupport token (too long): `%s`", token)
}

return nil
}

// RegenerateCachedReply regenerates the cached RPL_ISUPPORT reply
func (il *List) RegenerateCachedReply() (err error) {
var tokens []string
for name, value := range il.Tokens {
token := getTokenString(name, value)
if token[0] == ':' || strings.Contains(token, " ") {
err = fmt.Errorf("bad isupport token (cannot contain spaces or start with :): %s", token)
continue
if tokenErr := validateToken(token); tokenErr == nil {
tokens = append(tokens, token)
} else {
err = tokenErr
}
tokens = append(tokens, token)
}
// make sure we get a sorted list of tokens, needed for tests and looks nice
slices.Sort(tokens)
Expand Down
7 changes: 7 additions & 0 deletions traditional.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ server:
max-connections-per-duration: 64

# strict transport security, to get clients to automagically use TLS
# (irrelevant in the recommended configuration, with no public plaintext listener)
sts:
# whether to advertise STS
#
Expand Down Expand Up @@ -347,6 +348,12 @@ server:
# if you don't want to publicize how popular the server is
suppress-lusers: false

# publish additional key-value pairs in ISUPPORT (the 005 numeric).
# keys that collide with a key published by Ergo will be silently ignored.
additional-isupport:
#"draft/FILEHOST": "https://example.com/filehost"
#"draft/bazbat": "" # empty string means no value

# optionally map command alias names to existing ergo commands. most deployments
# should ignore this.
#command-aliases:
Expand Down