Added OPER and auth file parsing.
This commit is contained in:
parent
0383fcab8b
commit
9b71bdcbdd
30
main.go
30
main.go
@ -4,6 +4,8 @@ import (
|
|||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"flag"
|
"flag"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
@ -15,6 +17,8 @@ func main() {
|
|||||||
|
|
||||||
serverName := flag.String("irc-servername", "rosella", "Server name displayed to clients")
|
serverName := flag.String("irc-servername", "rosella", "Server name displayed to clients")
|
||||||
|
|
||||||
|
authFile := flag.String("irc-authfile", "", "File containing usernames and passwords of operators.\nPasswords hashed with SHA1, one username and password per line, space separated. Lines starting with a # are ignored.")
|
||||||
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
|
|
||||||
log.Printf("Rosella Initialising.")
|
log.Printf("Rosella Initialising.")
|
||||||
@ -22,6 +26,32 @@ func main() {
|
|||||||
//Init rosella itself
|
//Init rosella itself
|
||||||
server := NewServer()
|
server := NewServer()
|
||||||
server.name = *serverName
|
server.name = *serverName
|
||||||
|
|
||||||
|
if *authFile != "" {
|
||||||
|
log.Printf("Loading auth file: %q", *authFile)
|
||||||
|
|
||||||
|
f, err := os.Open(*authFile)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
data := make([]byte, 1024)
|
||||||
|
size, err := f.Read(data)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
lines := strings.Split(string(data[:size]), "\n")
|
||||||
|
for _, line := range lines {
|
||||||
|
if strings.HasPrefix(line, "#") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
|
||||||
|
if len(fields) == 2 {
|
||||||
|
server.operatorMap[fields[0]] = fields[1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
server.Run()
|
server.Run()
|
||||||
|
|
||||||
tlsConfig := new(tls.Config)
|
tlsConfig := new(tls.Config)
|
||||||
|
39
rosella.go
39
rosella.go
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/sha1"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
@ -18,6 +19,7 @@ type Server struct {
|
|||||||
name string
|
name string
|
||||||
clientMap map[string]*Client //Map of nicks → clients
|
clientMap map[string]*Client //Map of nicks → clients
|
||||||
channelMap map[string]*Channel //Map of channel names → channels
|
channelMap map[string]*Channel //Map of channel names → channels
|
||||||
|
operatorMap map[string]string //Map of usernames → SHA1 hashed passwords
|
||||||
}
|
}
|
||||||
|
|
||||||
type Client struct {
|
type Client struct {
|
||||||
@ -28,6 +30,7 @@ type Client struct {
|
|||||||
nick string
|
nick string
|
||||||
registered bool
|
registered bool
|
||||||
connected bool
|
connected bool
|
||||||
|
operator bool
|
||||||
channelMap map[string]*Channel
|
channelMap map[string]*Channel
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,6 +60,7 @@ const (
|
|||||||
rplKill
|
rplKill
|
||||||
rplMsg
|
rplMsg
|
||||||
rplList
|
rplList
|
||||||
|
rplOper
|
||||||
errMoreArgs
|
errMoreArgs
|
||||||
errNoNick
|
errNoNick
|
||||||
errInvalidNick
|
errInvalidNick
|
||||||
@ -65,6 +69,7 @@ const (
|
|||||||
errNoSuchNick
|
errNoSuchNick
|
||||||
errUnknownCommand
|
errUnknownCommand
|
||||||
errNotReg
|
errNotReg
|
||||||
|
errPassword
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -76,7 +81,8 @@ func NewServer() *Server {
|
|||||||
return &Server{eventChan: make(chan Event),
|
return &Server{eventChan: make(chan Event),
|
||||||
name: "rosella",
|
name: "rosella",
|
||||||
clientMap: make(map[string]*Client),
|
clientMap: make(map[string]*Client),
|
||||||
channelMap: make(map[string]*Channel)}
|
channelMap: make(map[string]*Channel),
|
||||||
|
operatorMap: make(map[string]string)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Run() {
|
func (s *Server) Run() {
|
||||||
@ -300,6 +306,31 @@ func (s *Server) handleEvent(e Event) {
|
|||||||
|
|
||||||
e.client.reply(rplList, chanList...)
|
e.client.reply(rplList, chanList...)
|
||||||
}
|
}
|
||||||
|
case command == "OPER":
|
||||||
|
if e.client.registered == false {
|
||||||
|
e.client.reply(errNotReg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(args) < 2 {
|
||||||
|
e.client.reply(errMoreArgs)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
username := args[0]
|
||||||
|
password := args[1]
|
||||||
|
|
||||||
|
if hashedPassword, exists := s.operatorMap[username]; exists {
|
||||||
|
h := sha1.New()
|
||||||
|
io.WriteString(h, password)
|
||||||
|
pass := fmt.Sprintf("%x", h.Sum(nil))
|
||||||
|
if hashedPassword == pass {
|
||||||
|
e.client.operator = true
|
||||||
|
e.client.reply(rplOper)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
e.client.reply(errPassword)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
e.client.reply(errUnknownCommand, command)
|
e.client.reply(errUnknownCommand, command)
|
||||||
@ -477,8 +508,10 @@ func (c *Client) reply(code int, args ...string) {
|
|||||||
c.outputChan <- fmt.Sprintf(":%s 322 %s %s", c.server.name, c.nick, listItem)
|
c.outputChan <- fmt.Sprintf(":%s 322 %s %s", c.server.name, c.nick, listItem)
|
||||||
}
|
}
|
||||||
c.outputChan <- fmt.Sprintf(":%s 323 %s", c.server.name, c.nick)
|
c.outputChan <- fmt.Sprintf(":%s 323 %s", c.server.name, c.nick)
|
||||||
|
case rplOper:
|
||||||
|
c.outputChan <- fmt.Sprintf(":%s 381 %s :You are now an operator", c.server.name, c.nick)
|
||||||
case errMoreArgs:
|
case errMoreArgs:
|
||||||
c.outputChan <- fmt.Sprintf(":%s 461 %s %s :Not enough params", c.server.name, c.nick, args[0])
|
c.outputChan <- fmt.Sprintf(":%s 461 %s :Not enough params", c.server.name, c.nick)
|
||||||
case errNoNick:
|
case errNoNick:
|
||||||
c.outputChan <- fmt.Sprintf(":%s 431 %s :No nickname given", c.server.name, c.nick)
|
c.outputChan <- fmt.Sprintf(":%s 431 %s :No nickname given", c.server.name, c.nick)
|
||||||
case errInvalidNick:
|
case errInvalidNick:
|
||||||
@ -493,6 +526,8 @@ func (c *Client) reply(code int, args ...string) {
|
|||||||
c.outputChan <- fmt.Sprintf(":%s 421 %s %s :Unknown command", c.server.name, c.nick, args[0])
|
c.outputChan <- fmt.Sprintf(":%s 421 %s %s :Unknown command", c.server.name, c.nick, args[0])
|
||||||
case errNotReg:
|
case errNotReg:
|
||||||
c.outputChan <- fmt.Sprintf(":%s 451 :You have not registered", c.server.name)
|
c.outputChan <- fmt.Sprintf(":%s 451 :You have not registered", c.server.name)
|
||||||
|
case errPassword:
|
||||||
|
c.outputChan <- fmt.Sprintf(":%s 464 %s :Error, password incorrect", c.server.name, c.nick)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user