3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-25 21:39:25 +01:00
add validation for isupport tokens
This commit is contained in:
Shivaram Lingamneni 2018-12-30 17:26:39 -05:00
parent b34bab16a7
commit ba2aacaf5b
3 changed files with 57 additions and 9 deletions

View File

@ -3,8 +3,11 @@
package isupport package isupport
import "fmt" import (
import "sort" "fmt"
"sort"
"strings"
)
const ( const (
maxLastArgLength = 400 maxLastArgLength = 400
@ -102,7 +105,7 @@ func (il *List) GetDifference(newil *List) [][]string {
} }
// RegenerateCachedReply regenerates the cached RPL_ISUPPORT reply // RegenerateCachedReply regenerates the cached RPL_ISUPPORT reply
func (il *List) RegenerateCachedReply() { func (il *List) RegenerateCachedReply() (err error) {
il.CachedReply = make([][]string, 0) il.CachedReply = make([][]string, 0)
var length int // Length of the current cache var length int // Length of the current cache
var cache []string // Token list cache var cache []string // Token list cache
@ -116,6 +119,10 @@ func (il *List) RegenerateCachedReply() {
for _, name := range tokens { for _, name := range tokens {
token := getTokenString(name, il.Tokens[name]) token := getTokenString(name, il.Tokens[name])
if token[0] == ':' || strings.Contains(token, " ") {
err = fmt.Errorf("bad isupport token (cannot contain spaces or start with :): %s", token)
continue
}
if len(token)+length <= maxLastArgLength { if len(token)+length <= maxLastArgLength {
// account for the space separating tokens // account for the space separating tokens
@ -136,4 +143,6 @@ func (il *List) RegenerateCachedReply() {
if len(cache) > 0 { if len(cache) > 0 {
il.CachedReply = append(il.CachedReply, cache) il.CachedReply = append(il.CachedReply, cache)
} }
return
} }

View File

@ -26,7 +26,10 @@ func TestISUPPORT(t *testing.T) {
tListLong.AddNoValue("D") tListLong.AddNoValue("D")
tListLong.AddNoValue("E") tListLong.AddNoValue("E")
tListLong.AddNoValue("F") tListLong.AddNoValue("F")
tListLong.RegenerateCachedReply() err := tListLong.RegenerateCachedReply()
if err != nil {
t.Error(err)
}
longReplies := [][]string{ longReplies := [][]string{
{"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D"}, {"1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D"},
@ -44,7 +47,10 @@ func TestISUPPORT(t *testing.T) {
tList1.Add("INVEX", "i") tList1.Add("INVEX", "i")
tList1.AddNoValue("EXTBAN") tList1.AddNoValue("EXTBAN")
tList1.Add("RANDKILL", "whenever") tList1.Add("RANDKILL", "whenever")
tList1.RegenerateCachedReply() err = tList1.RegenerateCachedReply()
if err != nil {
t.Error(err)
}
expected := [][]string{{"CASEMAPPING=rfc1459-strict", "EXTBAN", "INVEX=i", "RANDKILL=whenever", "SASL=yes"}} expected := [][]string{{"CASEMAPPING=rfc1459-strict", "EXTBAN", "INVEX=i", "RANDKILL=whenever", "SASL=yes"}}
if !reflect.DeepEqual(tList1.CachedReply, expected) { if !reflect.DeepEqual(tList1.CachedReply, expected) {
@ -58,7 +64,10 @@ func TestISUPPORT(t *testing.T) {
tList2.AddNoValue("INVEX") tList2.AddNoValue("INVEX")
tList2.Add("EXTBAN", "TestBah") tList2.Add("EXTBAN", "TestBah")
tList2.AddNoValue("STABLEKILL") tList2.AddNoValue("STABLEKILL")
tList2.RegenerateCachedReply() err = tList2.RegenerateCachedReply()
if err != nil {
t.Error(err)
}
expected = [][]string{{"CASEMAPPING=ascii", "EXTBAN=TestBah", "INVEX", "SASL=yes", "STABLEKILL"}} expected = [][]string{{"CASEMAPPING=ascii", "EXTBAN=TestBah", "INVEX", "SASL=yes", "STABLEKILL"}}
if !reflect.DeepEqual(tList2.CachedReply, expected) { if !reflect.DeepEqual(tList2.CachedReply, expected) {
@ -72,3 +81,26 @@ func TestISUPPORT(t *testing.T) {
t.Error("difference reply does not match expected difference reply") t.Error("difference reply does not match expected difference reply")
} }
} }
func TestBadToken(t *testing.T) {
list := NewList()
list.Add("NETWORK", "Bad Network Name")
list.Add("SASL", "yes")
list.Add("CASEMAPPING", "rfc1459-strict")
list.Add("INVEX", "i")
list.AddNoValue("EXTBAN")
err := list.RegenerateCachedReply()
if err == nil {
t.Error("isupport token generation should fail due to space in network name")
}
// should produce a list containing the other, valid params
numParams := 0
for _, tokenLine := range list.CachedReply {
numParams += len(tokenLine)
}
if numParams != 4 {
t.Errorf("expected the other 4 params to be generated, got %v", list.CachedReply)
}
}

View File

@ -147,7 +147,7 @@ func NewServer(config *Config, logger *logger.Manager) (*Server, error) {
} }
// setISupport sets up our RPL_ISUPPORT reply. // setISupport sets up our RPL_ISUPPORT reply.
func (server *Server) setISupport() { func (server *Server) setISupport() (err error) {
maxTargetsString := strconv.Itoa(maxTargets) maxTargetsString := strconv.Itoa(maxTargets)
config := server.Config() config := server.Config()
@ -192,11 +192,15 @@ func (server *Server) setISupport() {
isupport.Add("REGCREDTYPES", "passphrase,certfp") isupport.Add("REGCREDTYPES", "passphrase,certfp")
} }
isupport.RegenerateCachedReply() err = isupport.RegenerateCachedReply()
if err != nil {
return
}
server.configurableStateMutex.Lock() server.configurableStateMutex.Lock()
server.isupport = isupport server.isupport = isupport
server.configurableStateMutex.Unlock() server.configurableStateMutex.Unlock()
return
} }
func loadChannelList(channel *Channel, list string, maskMode modes.Mode) { func loadChannelList(channel *Channel, list string, maskMode modes.Mode) {
@ -787,7 +791,10 @@ func (server *Server) applyConfig(config *Config, initial bool) (err error) {
// set RPL_ISUPPORT // set RPL_ISUPPORT
var newISupportReplies [][]string var newISupportReplies [][]string
oldISupportList := server.ISupport() oldISupportList := server.ISupport()
server.setISupport() err = server.setISupport()
if err != nil {
return err
}
if oldISupportList != nil { if oldISupportList != nil {
newISupportReplies = oldISupportList.GetDifference(server.ISupport()) newISupportReplies = oldISupportList.GetDifference(server.ISupport())
} }