3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-11-22 20:09:41 +01:00

initial work on #1483

Add the new utf8-only cap, disallow non-utf8 when websockets are enabled
This commit is contained in:
Shivaram Lingamneni 2021-01-15 06:19:13 -05:00
parent 5095a4d814
commit db81b15acb
4 changed files with 18 additions and 12 deletions

View File

@ -686,9 +686,12 @@ func (client *Client) run(session *Session) {
if err == errInvalidUtf8 { if err == errInvalidUtf8 {
invalidUtf8 = true // handle as normal, including labeling invalidUtf8 = true // handle as normal, including labeling
} else if err != nil { } else if err != nil {
quitMessage := "connection closed" var quitMessage string
if err == errReadQ { switch err {
quitMessage = "readQ exceeded" case errReadQ, errWSBinaryMessage:
quitMessage = err.Error()
default:
quitMessage = "connection closed"
} }
client.Quit(quitMessage, session) client.Quit(quitMessage, session)
// since the client did not actually send us a QUIT, // since the client did not actually send us a QUIT,

View File

@ -837,6 +837,9 @@ func (conf *Config) prepareListeners() (err error) {
} }
lconf.RequireProxy = block.TLS.Proxy || block.Proxy lconf.RequireProxy = block.TLS.Proxy || block.Proxy
lconf.WebSocket = block.WebSocket lconf.WebSocket = block.WebSocket
if lconf.WebSocket && !conf.Server.EnforceUtf8 {
return fmt.Errorf("enabling a websocket listener requires the use of server.enforce-utf8")
}
lconf.HideSTS = block.HideSTS lconf.HideSTS = block.HideSTS
conf.Server.trueListeners[addr] = lconf conf.Server.trueListeners[addr] = lconf
} }
@ -1446,6 +1449,9 @@ func (config *Config) generateISupport() (err error) {
if config.Server.Casemapping == CasemappingPRECIS { if config.Server.Casemapping == CasemappingPRECIS {
isupport.Add("UTF8MAPPING", precisUTF8MappingToken) isupport.Add("UTF8MAPPING", precisUTF8MappingToken)
} }
if config.Server.EnforceUtf8 {
isupport.Add("UTF8ONLY", "")
}
isupport.Add("WHOX", "") isupport.Add("WHOX", "")
err = isupport.RegenerateCachedReply() err = isupport.RegenerateCachedReply()

View File

@ -21,6 +21,7 @@ const (
var ( var (
crlf = []byte{'\r', '\n'} crlf = []byte{'\r', '\n'}
errReadQ = errors.New("ReadQ Exceeded") errReadQ = errors.New("ReadQ Exceeded")
errWSBinaryMessage = errors.New("WebSocket binary messages are unsupported")
) )
// IRCConn abstracts away the distinction between a regular // IRCConn abstracts away the distinction between a regular
@ -148,11 +149,7 @@ func (wc IRCWSConn) UnderlyingConn() *utils.WrappedConn {
func (wc IRCWSConn) WriteLine(buf []byte) (err error) { func (wc IRCWSConn) WriteLine(buf []byte) (err error) {
buf = bytes.TrimSuffix(buf, crlf) buf = bytes.TrimSuffix(buf, crlf)
if !globalUtf8EnforcementSetting && !utf8.Valid(buf) { // #1483: if we have websockets at all, then we're enforcing utf8
// there's not much we can do about this;
// silently drop the message
return nil
}
return wc.conn.WriteMessage(websocket.TextMessage, buf) return wc.conn.WriteMessage(websocket.TextMessage, buf)
} }
@ -172,8 +169,7 @@ func (wc IRCWSConn) ReadLine() (line []byte, err error) {
if messageType == websocket.TextMessage { if messageType == websocket.TextMessage {
return line, nil return line, nil
} else { } else {
// for purposes of fakelag, treat non-text message as an empty line return nil, errWSBinaryMessage
return nil, nil
} }
} else if err == websocket.ErrReadLimit { } else if err == websocket.ErrReadLimit {
return line, errReadQ return line, errReadQ

View File

@ -166,6 +166,7 @@ func (wl *WSListener) handle(w http.ResponseWriter, r *http.Request) {
} }
return false return false
}, },
Subprotocols: []string{"text.ircv3.net"},
} }
conn, err := wsUpgrader.Upgrade(w, r, nil) conn, err := wsUpgrader.Upgrade(w, r, nil)