diff --git a/client.go b/client.go index 294723a..727f68a 100644 --- a/client.go +++ b/client.go @@ -16,6 +16,7 @@ import ( type Client interface { Name() string + Password() string Register(bool) Send(*irc.Message) Receive(*irc.Message) @@ -74,6 +75,10 @@ func (cl *RemoteClient) Name() string { return cl.name } +func (cl *RemoteClient) Password() string { + return cl.password +} + func (cl *RemoteClient) Register(success bool) { cl.registered <- success } diff --git a/server.go b/server.go index 30a3846..c93c483 100644 --- a/server.go +++ b/server.go @@ -48,6 +48,8 @@ type Server struct { connectionsCurrent float64 connectionsCount float64 queueLen float64 + + authCallback func(name, pass string) bool } // Create a new server instance. @@ -82,6 +84,10 @@ func NewServer(configPath, software, version string) *Server { 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. func (sv *Server) Run() { xlog.Info("%s/%s", sv.software, sv.version) @@ -141,17 +147,31 @@ func (sv *Server) dispatcher() { case cl := <-sv.addq: clid := strings.ToLower(cl.Name()) if _, exists := sv.clients[clid]; exists { - cl.Register(false) - xlog.Info("Client registration failed: '%s'", clid) - } else { - sv.clients[clid] = cl - sv.sendLogon(cl.Name()) - sv.connectionsCurrent = float64(len(sv.clients)) - cl.Register(true) - xlog.Info("Client registered: '%s'", clid) - xlog.Info("Server has %d client(s)", len(sv.clients)) - xlog.Debug("Goroutines running: %d", runtime.NumGoroutine()) + sv.sendReply(cl.Name(), ERR_NICKNAMEINUSE, "", "Nickname is already in use") + go func() { + time.Sleep(5 * time.Second) + cl.Register(false) + }() + 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.sendLogon(cl.Name()) + sv.connectionsCurrent = float64(len(sv.clients)) + cl.Register(true) + xlog.Info("Client registered: '%s'", clid) + xlog.Info("Server has %d client(s)", len(sv.clients)) + xlog.Debug("Goroutines running: %d", runtime.NumGoroutine()) case cl := <-sv.delq: clid := strings.ToLower(cl.Name()) cl.Destroy() @@ -397,7 +417,6 @@ func handleCmdTopic(sv *Server, msg *irc.Message) { //sv.sendReply(msg.Pre, RPL_TOPIC, ch, msg.Trail) } } - func handleCmdNames(sv *Server, msg *irc.Message) { ch := msg.Args[0] if _, exists := sv.chUsers[ch]; !exists {