1
0
Fork 0
forked from External/ergo

fix #561, take 2

This commit is contained in:
Shivaram Lingamneni 2019-11-20 17:14:42 -05:00
parent 5cce365092
commit 50783d5276
5 changed files with 85 additions and 18 deletions

View file

@ -10,6 +10,7 @@ import (
"fmt"
"net"
"strings"
"time"
"github.com/oragono/oragono/irc/modes"
"github.com/oragono/oragono/irc/utils"
@ -20,6 +21,13 @@ var (
errBadProxyLine = errors.New("Invalid PROXY/WEBIRC command")
)
const (
// https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
// "a 108-byte buffer is always enough to store all the line and a trailing zero
// for string processing."
maxProxyLineLen = 107
)
type webircConfig struct {
PasswordString string `yaml:"password"`
Password []byte `yaml:"password-bytes"`
@ -75,10 +83,10 @@ func (client *Client) ApplyProxiedIP(session *Session, proxiedIP string, tls boo
client.stateMutex.Lock()
defer client.stateMutex.Unlock()
session.proxiedIP = parsedProxiedIP
client.proxiedIP = parsedProxiedIP
session.rawHostname = rawHostname
client.rawHostname = rawHostname
session.proxiedIP = parsedProxiedIP
session.rawHostname = rawHostname
client.cloakedHostname = cloakedHostname
// nickmask will be updated when the client completes registration
// set tls info
@ -118,3 +126,36 @@ func handleProxyCommand(server *Server, client *Client, session *Session, line s
return errBadGatewayAddress
}
}
// read a PROXY line one byte at a time, to ensure we don't read anything beyond
// that into a buffer, which would break the TLS handshake
func readRawProxyLine(conn net.Conn) (result string) {
// normally this is covered by ping timeouts, but we're doing this outside
// of the normal client goroutine:
conn.SetDeadline(time.Now().Add(time.Minute))
defer conn.SetDeadline(time.Time{})
var buf [maxProxyLineLen]byte
oneByte := make([]byte, 1)
i := 0
for i < maxProxyLineLen {
n, err := conn.Read(oneByte)
if err != nil {
return
} else if n == 1 {
buf[i] = oneByte[0]
if buf[i] == '\n' {
candidate := string(buf[0 : i+1])
if strings.HasPrefix(candidate, "PROXY") {
return candidate
} else {
return
}
}
i += 1
}
}
// no \r\n, fail out
return
}