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"
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -15,6 +17,8 @@ func main() {
|
||||
|
||||
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()
|
||||
|
||||
log.Printf("Rosella Initialising.")
|
||||
@ -22,6 +26,32 @@ func main() {
|
||||
//Init rosella itself
|
||||
server := NewServer()
|
||||
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()
|
||||
|
||||
tlsConfig := new(tls.Config)
|
||||
|
53
rosella.go
53
rosella.go
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha1"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@ -13,11 +14,12 @@ import (
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
eventChan chan Event
|
||||
running bool
|
||||
name string
|
||||
clientMap map[string]*Client //Map of nicks → clients
|
||||
channelMap map[string]*Channel //Map of channel names → channels
|
||||
eventChan chan Event
|
||||
running bool
|
||||
name string
|
||||
clientMap map[string]*Client //Map of nicks → clients
|
||||
channelMap map[string]*Channel //Map of channel names → channels
|
||||
operatorMap map[string]string //Map of usernames → SHA1 hashed passwords
|
||||
}
|
||||
|
||||
type Client struct {
|
||||
@ -28,6 +30,7 @@ type Client struct {
|
||||
nick string
|
||||
registered bool
|
||||
connected bool
|
||||
operator bool
|
||||
channelMap map[string]*Channel
|
||||
}
|
||||
|
||||
@ -57,6 +60,7 @@ const (
|
||||
rplKill
|
||||
rplMsg
|
||||
rplList
|
||||
rplOper
|
||||
errMoreArgs
|
||||
errNoNick
|
||||
errInvalidNick
|
||||
@ -65,6 +69,7 @@ const (
|
||||
errNoSuchNick
|
||||
errUnknownCommand
|
||||
errNotReg
|
||||
errPassword
|
||||
)
|
||||
|
||||
var (
|
||||
@ -74,9 +79,10 @@ var (
|
||||
|
||||
func NewServer() *Server {
|
||||
return &Server{eventChan: make(chan Event),
|
||||
name: "rosella",
|
||||
clientMap: make(map[string]*Client),
|
||||
channelMap: make(map[string]*Channel)}
|
||||
name: "rosella",
|
||||
clientMap: make(map[string]*Client),
|
||||
channelMap: make(map[string]*Channel),
|
||||
operatorMap: make(map[string]string)}
|
||||
}
|
||||
|
||||
func (s *Server) Run() {
|
||||
@ -300,6 +306,31 @@ func (s *Server) handleEvent(e Event) {
|
||||
|
||||
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:
|
||||
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 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:
|
||||
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:
|
||||
c.outputChan <- fmt.Sprintf(":%s 431 %s :No nickname given", c.server.name, c.nick)
|
||||
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])
|
||||
case errNotReg:
|
||||
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