3
0
mirror of https://github.com/ergochat/ergo.git synced 2024-12-22 18:52:41 +01:00

pass the correct quit message when a proxied client is banned

If you were banned and the ban was only detected when you proxied
(because you were proxying from a DLINE'd IP), you'd get an incorrect
quit message: `QUIT: Bad or unauthorized PROXY command`. This propagates
the correct ban message as the quit line.
This commit is contained in:
Shivaram Lingamneni 2019-05-13 01:54:50 -04:00
parent 89a50d772c
commit 316d45917d
3 changed files with 23 additions and 22 deletions

View File

@ -13,7 +13,6 @@ var (
errAccountAlreadyVerified = errors.New(`Account is already verified`) errAccountAlreadyVerified = errors.New(`Account is already verified`)
errAccountCantDropPrimaryNick = errors.New("Can't unreserve primary nickname") errAccountCantDropPrimaryNick = errors.New("Can't unreserve primary nickname")
errAccountCreation = errors.New("Account could not be created") errAccountCreation = errors.New("Account could not be created")
errAccountCredUpdate = errors.New("Could not update password hash to new method")
errAccountDoesNotExist = errors.New("Account does not exist") errAccountDoesNotExist = errors.New("Account does not exist")
errAccountInvalidCredentials = errors.New("Invalid account credentials") errAccountInvalidCredentials = errors.New("Invalid account credentials")
errAccountBadPassphrase = errors.New(`Passphrase contains forbidden characters or is otherwise invalid`) errAccountBadPassphrase = errors.New(`Passphrase contains forbidden characters or is otherwise invalid`)
@ -28,7 +27,6 @@ var (
errCallbackFailed = errors.New("Account verification could not be sent") errCallbackFailed = errors.New("Account verification could not be sent")
errCertfpAlreadyExists = errors.New(`An account already exists for your certificate fingerprint`) errCertfpAlreadyExists = errors.New(`An account already exists for your certificate fingerprint`)
errChannelNotOwnedByAccount = errors.New("Channel not owned by the specified account") errChannelNotOwnedByAccount = errors.New("Channel not owned by the specified account")
errChannelDoesNotExist = errors.New("Channel does not exist")
errChannelAlreadyRegistered = errors.New("Channel is already registered") errChannelAlreadyRegistered = errors.New("Channel is already registered")
errChannelNameInUse = errors.New(`Channel name in use`) errChannelNameInUse = errors.New(`Channel name in use`)
errInvalidChannelName = errors.New(`Invalid channel name`) errInvalidChannelName = errors.New(`Invalid channel name`)
@ -38,12 +36,10 @@ var (
errNicknameReserved = errors.New("nickname is reserved") errNicknameReserved = errors.New("nickname is reserved")
errNoExistingBan = errors.New("Ban does not exist") errNoExistingBan = errors.New("Ban does not exist")
errNoSuchChannel = errors.New(`No such channel`) errNoSuchChannel = errors.New(`No such channel`)
errRenamePrivsNeeded = errors.New(`Only chanops can rename channels`)
errInsufficientPrivs = errors.New("Insufficient privileges") errInsufficientPrivs = errors.New("Insufficient privileges")
errSaslFail = errors.New("SASL failed")
errResumeTokenAlreadySet = errors.New("Client was already assigned a resume token")
errInvalidUsername = errors.New("Invalid username") errInvalidUsername = errors.New("Invalid username")
errFeatureDisabled = errors.New(`That feature is disabled`) errFeatureDisabled = errors.New(`That feature is disabled`)
errBanned = errors.New("IP or nickmask banned")
errInvalidParams = errors.New("Invalid parameters") errInvalidParams = errors.New("Invalid parameters")
) )

View File

@ -46,24 +46,22 @@ func (wc *webircConfig) Populate() (err error) {
} }
// ApplyProxiedIP applies the given IP to the client. // ApplyProxiedIP applies the given IP to the client.
func (client *Client) ApplyProxiedIP(session *Session, proxiedIP string, tls bool) (success bool) { func (client *Client) ApplyProxiedIP(session *Session, proxiedIP string, tls bool) (err error, quitMsg string) {
// PROXY and WEBIRC are never accepted from a Tor listener, even if the address itself // PROXY and WEBIRC are never accepted from a Tor listener, even if the address itself
// is whitelisted: // is whitelisted:
if client.isTor { if client.isTor {
return false return errBadProxyLine, ""
} }
// ensure IP is sane // ensure IP is sane
parsedProxiedIP := net.ParseIP(proxiedIP).To16() parsedProxiedIP := net.ParseIP(proxiedIP).To16()
if parsedProxiedIP == nil { if parsedProxiedIP == nil {
client.Quit(fmt.Sprintf(client.t("Proxied IP address is not valid: [%s]"), proxiedIP), session) return errBadProxyLine, fmt.Sprintf(client.t("Proxied IP address is not valid: [%s]"), proxiedIP)
return false
} }
isBanned, banMsg := client.server.checkBans(parsedProxiedIP) isBanned, banMsg := client.server.checkBans(parsedProxiedIP)
if isBanned { if isBanned {
client.Quit(banMsg, session) return errBanned, banMsg
return false
} }
// given IP is sane! override the client's current IP // given IP is sane! override the client's current IP
@ -84,7 +82,7 @@ func (client *Client) ApplyProxiedIP(session *Session, proxiedIP string, tls boo
client.certfp = "" client.certfp = ""
client.SetMode(modes.TLS, tls) client.SetMode(modes.TLS, tls)
return true return nil, ""
} }
// handle the PROXY command: http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt // handle the PROXY command: http://www.haproxy.org/download/1.8/doc/proxy-protocol.txt
@ -93,9 +91,13 @@ func (client *Client) ApplyProxiedIP(session *Session, proxiedIP string, tls boo
// unfortunately, an ipv6 SOURCEIP can start with a double colon; in this case, // unfortunately, an ipv6 SOURCEIP can start with a double colon; in this case,
// the message is invalid IRC and can't be parsed normally, hence the special handling. // the message is invalid IRC and can't be parsed normally, hence the special handling.
func handleProxyCommand(server *Server, client *Client, session *Session, line string) (err error) { func handleProxyCommand(server *Server, client *Client, session *Session, line string) (err error) {
var quitMsg string
defer func() { defer func() {
if err != nil { if err != nil {
client.Quit(client.t("Bad or unauthorized PROXY command"), session) if quitMsg == "" {
quitMsg = client.t("Bad or unauthorized PROXY command")
}
client.Quit(quitMsg, session)
} }
}() }()
@ -106,13 +108,10 @@ func handleProxyCommand(server *Server, client *Client, session *Session, line s
if utils.IPInNets(client.realIP, server.Config().Server.proxyAllowedFromNets) { if utils.IPInNets(client.realIP, server.Config().Server.proxyAllowedFromNets) {
// assume PROXY connections are always secure // assume PROXY connections are always secure
if client.ApplyProxiedIP(session, params[2], true) { err, quitMsg = client.ApplyProxiedIP(session, params[2], true)
return nil return
} else { } else {
return errBadProxyLine
}
}
// real source IP is not authorized to issue PROXY: // real source IP is not authorized to issue PROXY:
return errBadGatewayAddress return errBadGatewayAddress
}
} }

View File

@ -2576,7 +2576,13 @@ func webircHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Re
if strings.HasPrefix(proxiedIP, "[") && strings.HasSuffix(proxiedIP, "]") { if strings.HasPrefix(proxiedIP, "[") && strings.HasSuffix(proxiedIP, "]") {
proxiedIP = proxiedIP[1 : len(proxiedIP)-1] proxiedIP = proxiedIP[1 : len(proxiedIP)-1]
} }
return !client.ApplyProxiedIP(rb.session, proxiedIP, secure) err, quitMsg := client.ApplyProxiedIP(rb.session, proxiedIP, secure)
if err != nil {
client.Quit(quitMsg, rb.session)
return true
} else {
return false
}
} }
} }