Added OPER and auth file parsing.

This commit is contained in:
Harry Jeffery 2013-08-23 23:59:33 +01:00
parent 0383fcab8b
commit 9b71bdcbdd
2 changed files with 74 additions and 9 deletions

30
main.go
View File

@ -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)

View File

@ -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)
} }
} }