mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-23 03:02:48 +01:00
commit
02d635d3eb
@ -121,16 +121,14 @@ type Session struct {
|
|||||||
// sets the session quit message, if there isn't one already
|
// sets the session quit message, if there isn't one already
|
||||||
func (sd *Session) SetQuitMessage(message string) (set bool) {
|
func (sd *Session) SetQuitMessage(message string) (set bool) {
|
||||||
if message == "" {
|
if message == "" {
|
||||||
|
message = "Connection closed"
|
||||||
|
}
|
||||||
if sd.quitMessage == "" {
|
if sd.quitMessage == "" {
|
||||||
sd.quitMessage = "Connection closed"
|
sd.quitMessage = message
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
sd.quitMessage = message
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the negotiated message length based on session capabilities
|
// set the negotiated message length based on session capabilities
|
||||||
@ -286,18 +284,30 @@ func (client *Client) doIdentLookup(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) isAuthorized(config *Config) bool {
|
type AuthOutcome uint
|
||||||
|
|
||||||
|
const (
|
||||||
|
authSuccess AuthOutcome = iota
|
||||||
|
authFailPass
|
||||||
|
authFailTorSaslRequired
|
||||||
|
authFailSaslRequired
|
||||||
|
)
|
||||||
|
|
||||||
|
func (client *Client) isAuthorized(config *Config) AuthOutcome {
|
||||||
saslSent := client.account != ""
|
saslSent := client.account != ""
|
||||||
// PASS requirement
|
// PASS requirement
|
||||||
if (config.Server.passwordBytes != nil) && !client.sentPassCommand && !(config.Accounts.SkipServerPassword && saslSent) {
|
if (config.Server.passwordBytes != nil) && !client.sentPassCommand && !(config.Accounts.SkipServerPassword && saslSent) {
|
||||||
return false
|
return authFailPass
|
||||||
}
|
}
|
||||||
// Tor connections may be required to authenticate with SASL
|
// Tor connections may be required to authenticate with SASL
|
||||||
if client.isTor && config.Server.TorListeners.RequireSasl && !saslSent {
|
if client.isTor && config.Server.TorListeners.RequireSasl && !saslSent {
|
||||||
return false
|
return authFailTorSaslRequired
|
||||||
}
|
}
|
||||||
// finally, enforce require-sasl
|
// finally, enforce require-sasl
|
||||||
return !config.Accounts.RequireSasl.Enabled || saslSent || utils.IPInNets(client.IP(), config.Accounts.RequireSasl.exemptedNets)
|
if config.Accounts.RequireSasl.Enabled && !saslSent && !utils.IPInNets(client.IP(), config.Accounts.RequireSasl.exemptedNets) {
|
||||||
|
return authFailSaslRequired
|
||||||
|
}
|
||||||
|
return authSuccess
|
||||||
}
|
}
|
||||||
|
|
||||||
func (session *Session) resetFakelag() {
|
func (session *Session) resetFakelag() {
|
||||||
|
@ -45,8 +45,8 @@ func (cmd *Command) Run(server *Server, client *Client, session *Session, msg ir
|
|||||||
rb.Send(true)
|
rb.Send(true)
|
||||||
|
|
||||||
// after each command, see if we can send registration to the client
|
// after each command, see if we can send registration to the client
|
||||||
if !client.registered {
|
if !exiting && !client.registered {
|
||||||
server.tryRegister(client, session)
|
exiting = server.tryRegister(client, session)
|
||||||
}
|
}
|
||||||
|
|
||||||
// most servers do this only for PING/PONG, but we'll do it for any command:
|
// most servers do this only for PING/PONG, but we'll do it for any command:
|
||||||
|
@ -2229,13 +2229,9 @@ func passHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp
|
|||||||
|
|
||||||
// check the provided password
|
// check the provided password
|
||||||
password := []byte(msg.Params[0])
|
password := []byte(msg.Params[0])
|
||||||
if bcrypt.CompareHashAndPassword(serverPassword, password) != nil {
|
client.sentPassCommand = bcrypt.CompareHashAndPassword(serverPassword, password) == nil
|
||||||
rb.Add(nil, server.name, ERR_PASSWDMISMATCH, client.nick, client.t("Password incorrect"))
|
|
||||||
client.Quit(client.t("Password incorrect"), rb.session)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
client.sentPassCommand = true
|
// if they failed the check, we'll bounce them later when they try to complete registration
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,8 +274,10 @@ func (nt *NickTimer) Touch(rb *ResponseBuffer) {
|
|||||||
for _, mSession := range nt.client.Sessions() {
|
for _, mSession := range nt.client.Sessions() {
|
||||||
if mSession == session {
|
if mSession == session {
|
||||||
rb.Add(nil, nsPrefix, "NOTICE", tnick, message)
|
rb.Add(nil, nsPrefix, "NOTICE", tnick, message)
|
||||||
|
rb.Add(nil, nt.client.server.name, "WARN", "*", "ACCOUNT_REQUIRED", message)
|
||||||
} else {
|
} else {
|
||||||
mSession.Send(nil, nsPrefix, "NOTICE", tnick, message)
|
mSession.Send(nil, nsPrefix, "NOTICE", tnick, message)
|
||||||
|
mSession.Send(nil, nt.client.server.name, "WARN", "*", "ACCOUNT_REQUIRED", message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if shouldRename {
|
} else if shouldRename {
|
||||||
|
@ -165,7 +165,6 @@ const (
|
|||||||
ERR_CANNOTSENDRP = "573"
|
ERR_CANNOTSENDRP = "573"
|
||||||
RPL_WHOISSECURE = "671"
|
RPL_WHOISSECURE = "671"
|
||||||
RPL_YOURLANGUAGESARE = "687"
|
RPL_YOURLANGUAGESARE = "687"
|
||||||
RPL_WHOISLANGUAGE = "690"
|
|
||||||
ERR_CHANNAMEINUSE = "692"
|
ERR_CHANNAMEINUSE = "692"
|
||||||
ERR_CANNOTRENAME = "693"
|
ERR_CANNOTRENAME = "693"
|
||||||
RPL_HELPSTART = "704"
|
RPL_HELPSTART = "704"
|
||||||
|
@ -330,7 +330,7 @@ func (server *Server) createListener(addr string, tlsConfig *tls.Config, isTor b
|
|||||||
// server functionality
|
// server functionality
|
||||||
//
|
//
|
||||||
|
|
||||||
func (server *Server) tryRegister(c *Client, session *Session) {
|
func (server *Server) tryRegister(c *Client, session *Session) (exiting bool) {
|
||||||
// if the session just sent us a RESUME line, try to resume
|
// if the session just sent us a RESUME line, try to resume
|
||||||
if session.resumeDetails != nil {
|
if session.resumeDetails != nil {
|
||||||
session.tryResume()
|
session.tryResume()
|
||||||
@ -344,11 +344,19 @@ func (server *Server) tryRegister(c *Client, session *Session) {
|
|||||||
|
|
||||||
// client MUST send PASS if necessary, or authenticate with SASL if necessary,
|
// client MUST send PASS if necessary, or authenticate with SASL if necessary,
|
||||||
// before completing the other registration commands
|
// before completing the other registration commands
|
||||||
config := server.Config()
|
authOutcome := c.isAuthorized(server.Config())
|
||||||
if !c.isAuthorized(config) {
|
var quitMessage string
|
||||||
c.Quit(c.t("Bad password"), nil)
|
switch authOutcome {
|
||||||
c.destroy(nil)
|
case authFailPass:
|
||||||
return
|
quitMessage = c.t("Password incorrect")
|
||||||
|
c.Send(nil, server.name, ERR_PASSWDMISMATCH, "*", quitMessage)
|
||||||
|
case authFailSaslRequired, authFailTorSaslRequired:
|
||||||
|
quitMessage = c.t("You must log in with SASL to join this server")
|
||||||
|
c.Send(nil, c.server.name, "FAIL", "*", "ACCOUNT_REQUIRED", quitMessage)
|
||||||
|
}
|
||||||
|
if authOutcome != authSuccess {
|
||||||
|
c.Quit(quitMessage, nil)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
rb := NewResponseBuffer(session)
|
rb := NewResponseBuffer(session)
|
||||||
@ -363,8 +371,7 @@ func (server *Server) tryRegister(c *Client, session *Session) {
|
|||||||
isBanned, info := server.klines.CheckMasks(c.AllNickmasks()...)
|
isBanned, info := server.klines.CheckMasks(c.AllNickmasks()...)
|
||||||
if isBanned {
|
if isBanned {
|
||||||
c.Quit(info.BanMessage(c.t("You are banned from this server (%s)")), nil)
|
c.Quit(info.BanMessage(c.t("You are banned from this server (%s)")), nil)
|
||||||
c.destroy(nil)
|
return true
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if session.client != c {
|
if session.client != c {
|
||||||
@ -377,12 +384,13 @@ func (server *Server) tryRegister(c *Client, session *Session) {
|
|||||||
|
|
||||||
// registration has succeeded:
|
// registration has succeeded:
|
||||||
c.SetRegistered()
|
c.SetRegistered()
|
||||||
|
|
||||||
// count new user in statistics
|
// count new user in statistics
|
||||||
server.stats.ChangeTotal(1)
|
server.stats.ChangeTotal(1)
|
||||||
|
server.monitorManager.AlertAbout(c, true)
|
||||||
|
|
||||||
server.playRegistrationBurst(session)
|
server.playRegistrationBurst(session)
|
||||||
|
return false
|
||||||
server.monitorManager.AlertAbout(c, true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *Server) playRegistrationBurst(session *Session) {
|
func (server *Server) playRegistrationBurst(session *Session) {
|
||||||
@ -480,14 +488,6 @@ func (client *Client) getWhoisOf(target *Client, rb *ResponseBuffer) {
|
|||||||
rb.Add(nil, client.server.name, RPL_WHOISBOT, cnick, tnick, ircfmt.Unescape(fmt.Sprintf(client.t("is a $bBot$b on %s"), client.server.Config().Network.Name)))
|
rb.Add(nil, client.server.name, RPL_WHOISBOT, cnick, tnick, ircfmt.Unescape(fmt.Sprintf(client.t("is a $bBot$b on %s"), client.server.Config().Network.Name)))
|
||||||
}
|
}
|
||||||
|
|
||||||
tLanguages := target.Languages()
|
|
||||||
if 0 < len(tLanguages) {
|
|
||||||
params := []string{cnick, tnick}
|
|
||||||
params = append(params, client.server.Languages().Codes(tLanguages)...)
|
|
||||||
params = append(params, client.t("can speak these languages"))
|
|
||||||
rb.Add(nil, client.server.name, RPL_WHOISLANGUAGE, params...)
|
|
||||||
}
|
|
||||||
|
|
||||||
if target.certfp != "" && (client.HasMode(modes.Operator) || client == target) {
|
if target.certfp != "" && (client.HasMode(modes.Operator) || client == target) {
|
||||||
rb.Add(nil, client.server.name, RPL_WHOISCERTFP, cnick, tnick, fmt.Sprintf(client.t("has client certificate fingerprint %s"), target.certfp))
|
rb.Add(nil, client.server.name, RPL_WHOISCERTFP, cnick, tnick, fmt.Sprintf(client.t("has client certificate fingerprint %s"), target.certfp))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user