"regexp"
"sort"
"strings"
+ "sync"
"time"
)
RENickname = regexp.MustCompile("^[a-zA-Z0-9-]{1,9}$")
)
+var passwordsRefreshLock sync.Mutex
+
type Daemon struct {
Verbose bool
hostname string
lastAlivenessCheck time.Time
logSink chan<- LogEvent
stateSink chan<- StateEvent
+ passwords map[string]string
}
func NewDaemon(hostname, motd string, logSink chan<- LogEvent, stateSink chan<- StateEvent) *Daemon {
// When client finishes NICK/USER workflow, then MOTD and LUSERS are send to him.
func (daemon *Daemon) ClientRegister(client *Client, command string, cols []string) {
switch command {
+ case "PASS":
+ if len(cols) == 1 || len(cols[1]) < 1 {
+ client.ReplyNotEnoughParameters("PASS")
+ return
+ }
+ client.password = cols[1]
case "NICK":
if len(cols) == 1 || len(cols[1]) < 1 {
client.ReplyParts("431", "No nickname given")
client.realname = strings.TrimLeft(args[3], ":")
}
if client.nickname != "*" && client.username != "" {
+ passwordsRefreshLock.Lock()
+ if daemon.passwords != nil && (client.password == "" || daemon.passwords[client.nickname] != client.password) {
+ passwordsRefreshLock.Unlock()
+ client.ReplyParts("462", "You may not register")
+ client.conn.Close()
+ return
+ }
+ passwordsRefreshLock.Unlock()
client.registered = true
client.ReplyNicknamed("001", "Hi, welcome to IRC")
client.ReplyNicknamed("002", "Your host is "+daemon.hostname+", running goircd")
client.ReplyNicknamed("004", daemon.hostname+" goircd o o")
daemon.SendLusers(client)
daemon.SendMotd(client)
+ log.Println(client, "logged in")
}
}
continue
}
roomNew, roomSink := daemon.RoomRegister(room)
+ log.Println("Room", roomNew, "created")
if key != "" {
roomNew.key = key
roomNew.StateSave()
log.Println(client, "command", command)
}
if command == "QUIT" {
+ log.Println(client, "quit")
delete(daemon.clients, client)
delete(daemon.clientAliveness, client)
client.conn.Close()
case "LIST":
daemon.SendList(client, cols)
case "LUSERS":
- go daemon.SendLusers(client)
+ daemon.SendLusers(client)
case "MODE":
if len(cols) == 1 || len(cols[1]) < 1 {
client.ReplyNotEnoughParameters("MODE")
}
cols := strings.Split(cols[1], " ")
nicknames := strings.Split(cols[len(cols)-1], ",")
- go daemon.SendWhois(client, nicknames)
+ daemon.SendWhois(client, nicknames)
default:
client.ReplyNicknamed("421", command, "Unknown command")
}
}
}
}
+
+func (daemon *Daemon) PasswordsRefresh() {
+ contents, err := ioutil.ReadFile(*passwords)
+ if err != nil {
+ log.Fatalf("Can no read passwords file %s: %s", *passwords, err)
+ return
+ }
+ processed := make(map[string]string)
+ for _, entry := range strings.Split(string(contents), "\n") {
+ loginAndPassword := strings.Split(entry, ":")
+ if len(loginAndPassword) == 2 {
+ processed[loginAndPassword[0]] = loginAndPassword[1]
+ }
+ }
+ log.Printf("Read %d passwords", len(processed))
+ passwordsRefreshLock.Lock()
+ daemon.passwords = processed
+ passwordsRefreshLock.Unlock()
+}