Clean(er) handling of nick collision and password mismatch

This commit is contained in:
Andreas Neue 2016-07-27 15:17:54 +02:00
parent ad4276152e
commit 6116aca94b
2 changed files with 35 additions and 11 deletions

View File

@ -16,6 +16,7 @@ import (
type Client interface { type Client interface {
Name() string Name() string
Password() string
Register(bool) Register(bool)
Send(*irc.Message) Send(*irc.Message)
Receive(*irc.Message) Receive(*irc.Message)
@ -74,6 +75,10 @@ func (cl *RemoteClient) Name() string {
return cl.name return cl.name
} }
func (cl *RemoteClient) Password() string {
return cl.password
}
func (cl *RemoteClient) Register(success bool) { func (cl *RemoteClient) Register(success bool) {
cl.registered <- success cl.registered <- success
} }

View File

@ -48,6 +48,8 @@ type Server struct {
connectionsCurrent float64 connectionsCurrent float64
connectionsCount float64 connectionsCount float64
queueLen float64 queueLen float64
authCallback func(name, pass string) bool
} }
// Create a new server instance. // Create a new server instance.
@ -82,6 +84,10 @@ func NewServer(configPath, software, version string) *Server {
return sv return sv
} }
func (sv *Server) SetAuthCallback(authCB func(name, pass string) bool) {
sv.authCallback = authCB
}
// Open the listening port and start the main server loop. // Open the listening port and start the main server loop.
func (sv *Server) Run() { func (sv *Server) Run() {
xlog.Info("%s/%s", sv.software, sv.version) xlog.Info("%s/%s", sv.software, sv.version)
@ -141,9 +147,24 @@ func (sv *Server) dispatcher() {
case cl := <-sv.addq: case cl := <-sv.addq:
clid := strings.ToLower(cl.Name()) clid := strings.ToLower(cl.Name())
if _, exists := sv.clients[clid]; exists { if _, exists := sv.clients[clid]; exists {
sv.sendReply(cl.Name(), ERR_NICKNAMEINUSE, "", "Nickname is already in use")
go func() {
time.Sleep(5 * time.Second)
cl.Register(false) cl.Register(false)
xlog.Info("Client registration failed: '%s'", clid) }()
} else { xlog.Info("Client registration failed: '%s' (client exists)", clid)
continue
}
if !sv.authCallback(cl.Name(), cl.Password()) {
sv.sendReply(cl.Name(), ERR_PASSWDMISMATCH, "", "Password incorrect")
go func() {
time.Sleep(5 * time.Second)
cl.Register(false)
}()
xlog.Info("Client registration failed: '%s' (wrong password)", clid)
continue
}
sv.clients[clid] = cl
sv.clients[clid] = cl sv.clients[clid] = cl
sv.sendLogon(cl.Name()) sv.sendLogon(cl.Name())
sv.connectionsCurrent = float64(len(sv.clients)) sv.connectionsCurrent = float64(len(sv.clients))
@ -151,7 +172,6 @@ func (sv *Server) dispatcher() {
xlog.Info("Client registered: '%s'", clid) xlog.Info("Client registered: '%s'", clid)
xlog.Info("Server has %d client(s)", len(sv.clients)) xlog.Info("Server has %d client(s)", len(sv.clients))
xlog.Debug("Goroutines running: %d", runtime.NumGoroutine()) xlog.Debug("Goroutines running: %d", runtime.NumGoroutine())
}
case cl := <-sv.delq: case cl := <-sv.delq:
clid := strings.ToLower(cl.Name()) clid := strings.ToLower(cl.Name())
cl.Destroy() cl.Destroy()
@ -397,7 +417,6 @@ func handleCmdTopic(sv *Server, msg *irc.Message) {
//sv.sendReply(msg.Pre, RPL_TOPIC, ch, msg.Trail) //sv.sendReply(msg.Pre, RPL_TOPIC, ch, msg.Trail)
} }
} }
func handleCmdNames(sv *Server, msg *irc.Message) { func handleCmdNames(sv *Server, msg *irc.Message) {
ch := msg.Args[0] ch := msg.Args[0]
if _, exists := sv.chUsers[ch]; !exists { if _, exists := sv.chUsers[ch]; !exists {