Refined permission management, implemented KICK, forbid PRIVMSG to chan from outside

This commit is contained in:
Andreas Neue 2016-07-31 23:56:25 +02:00
parent 0b6442a17e
commit 8088acc214
1 changed files with 84 additions and 51 deletions

135
server.go
View File

@ -22,7 +22,7 @@ const (
) )
var myinfo string = "%s %s/%s * *" var myinfo string = "%s %s/%s * *"
var isupport string = "CASEMAPPING=rfc1459 CHANTYPES=# NICKLEN=32 PREFIX=(aohv)&@%%+" var isupport string = "CASEMAPPING=rfc1459 CHANTYPES=# NICKLEN=32 PREFIX=(ohv)@%%+"
type Server struct { type Server struct {
queue chan *irc.Message queue chan *irc.Message
@ -338,6 +338,15 @@ func (sv *Server) channelCheckMode(chid, mode string) bool {
return true return true
} }
func (sv *Server) channelCheckPerm(chid, clid, modes string) bool {
for _, m := range modes {
if sv.channelCheckMode(chid, string(m)+" "+clid) {
return true
}
}
return false
}
type commandHook struct { type commandHook struct {
HookFn func(sv *Server, msg *irc.Message) HookFn func(sv *Server, msg *irc.Message)
MinArgs int MinArgs int
@ -352,10 +361,12 @@ var svCommandHooks = map[string]commandHook{
"QUIT": {handleCmdQuit, 0, false, ""}, "QUIT": {handleCmdQuit, 0, false, ""},
"MODE": {handleCmdMode, 1, false, ""}, "MODE": {handleCmdMode, 1, false, ""},
"TOPIC": {handleCmdTopic, 1, false, ""}, "TOPIC": {handleCmdTopic, 1, false, ""},
"KICK": {handleCmdKick, 2, false, ""},
"NAMES": {handleCmdNames, 1, false, ""}, "NAMES": {handleCmdNames, 1, false, ""},
"WHOIS": {handleCmdWhois, 0, false, ""}, "WHOIS": {handleCmdWhois, 0, false, ""},
"PING": {handleCmdPing, 1, false, ""}, "PING": {handleCmdPing, 1, false, ""},
"REHASH": {handleCmdRehash, 0, false, "ao"}, "REHASH": {handleCmdRehash, 0, false, "ao"},
"KILL": {handleCmdKill, 0, false, "ao"},
/* /*
"LIST": {handleCmdList, 0, false, false}, "LIST": {handleCmdList, 0, false, false},
"VERSION": {handleCmdVersion, 0, false, false}, "VERSION": {handleCmdVersion, 0, false, false},
@ -366,7 +377,6 @@ var svCommandHooks = map[string]commandHook{
"INFO": {handleCmdInfo, 0, false, false}, "INFO": {handleCmdInfo, 0, false, false},
"WHO": {handleCmdWho, 0, false, false}, "WHO": {handleCmdWho, 0, false, false},
"WHOWAS": {handleCmdWhowas, 0, false, false}, "WHOWAS": {handleCmdWhowas, 0, false, false},
"KILL": {handleCmdKill, 0, false, false},
"PONG": {handleCmdPong, 0, false, false}, "PONG": {handleCmdPong, 0, false, false},
"ERROR": {handleCmdError, 0, false, false}, "ERROR": {handleCmdError, 0, false, false},
"AWAY": {handleCmdAway, 0, false, false}, "AWAY": {handleCmdAway, 0, false, false},
@ -383,7 +393,12 @@ func handleCmdPrivmsg(sv *Server, msg *irc.Message) {
clid := strings.ToLower(msg.Pre) clid := strings.ToLower(msg.Pre)
chid := strings.ToLower(msg.Args[0]) chid := strings.ToLower(msg.Args[0])
if sv.channelCheckMode(chid, "m") && if sv.channelCheckMode(chid, "m") &&
!sv.channelCheckMode(chid, "v "+clid) { !sv.channelCheckPerm(chid, clid, "ohv") {
sv.sendReply(clid, ERR_CANNOTSENDTOCHAN, chid, "Cannot send to channel")
return
}
if _, exists := sv.chUsers[clid]; !exists {
sv.sendReply(clid, ERR_CANNOTSENDTOCHAN, chid, "Cannot send to channel")
return return
} }
} }
@ -452,58 +467,52 @@ func handleCmdMode(sv *Server, msg *irc.Message) {
if len(msg.Args) < 2 { if len(msg.Args) < 2 {
return return
} }
modeFlag := msg.Args[1] mode := ""
if len(msg.Args) < 3 { modeSwitch := msg.Args[1]
//modeTar := "" modeTarget := ""
} else { if len(modeSwitch) < 2 {
//modeTar := strings.ToLower(msg.Args[2]) return
} }
switch modeFlag { if len(msg.Args) > 2 {
modeTarget = strings.ToLower(msg.Args[2])
}
switch modeSwitch[1] {
// maybe this can be done more elegant // maybe this can be done more elegant
case "+o": case 'o':
if !sv.channelCheckMode(chid, "o "+clid) { if !sv.channelCheckPerm(chid, clid, "o") {
goto noPerm goto noPerm
} }
case "-o": case 'h':
if !sv.channelCheckMode(chid, "o "+clid) { if !sv.channelCheckPerm(chid, clid, "o") {
goto noPerm goto noPerm
} }
case "+h": case 'b':
if !sv.channelCheckMode(chid, "o "+clid) { if !sv.channelCheckPerm(chid, clid, "oh") {
goto noPerm goto noPerm
} }
case "-h": case 'v':
if !sv.channelCheckMode(chid, "o "+clid) { if !sv.channelCheckPerm(chid, clid, "oh") {
goto noPerm goto noPerm
} }
case "+b": case 'm':
if !sv.channelCheckMode(chid, "o "+clid) && if !sv.channelCheckPerm(chid, clid, "oh") {
!sv.channelCheckMode(chid, "h "+clid) {
goto noPerm goto noPerm
} }
case "-b": case 't':
if !sv.channelCheckMode(chid, "o "+clid) && if !sv.channelCheckPerm(chid, clid, "oh") {
!sv.channelCheckMode(chid, "h "+clid) {
goto noPerm
}
case "+v":
if !sv.channelCheckMode(chid, "o "+clid) &&
!sv.channelCheckMode(chid, "h "+clid) {
goto noPerm
}
case "-v":
if !sv.channelCheckMode(chid, "o "+clid) &&
!sv.channelCheckMode(chid, "h "+clid) {
goto noPerm
}
case "+m":
if !sv.channelCheckMode(chid, "o "+clid) {
goto noPerm
}
case "-m":
if !sv.channelCheckMode(chid, "o "+clid) {
goto noPerm goto noPerm
} }
default:
return
}
mode = string(modeSwitch[1])
if modeTarget != "" {
mode = mode + " " + modeTarget
}
if modeSwitch[0] == '+' {
sv.chModes[chid][mode] = true
} else {
delete(sv.chModes[chid], mode)
} }
sv.sendMsg(msg) sv.sendMsg(msg)
return return
@ -513,24 +522,45 @@ func handleCmdMode(sv *Server, msg *irc.Message) {
} }
func handleCmdTopic(sv *Server, msg *irc.Message) { func handleCmdTopic(sv *Server, msg *irc.Message) {
ch := msg.Args[0] chid := strings.ToLower(msg.Args[0])
if _, exists := sv.chUsers[ch]; !exists { clid := strings.ToLower(msg.Pre)
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, ch, "No such channel") if _, exists := sv.chUsers[chid]; !exists {
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, chid, "No such channel")
} }
if msg.Trail == "" { if msg.Trail == "" {
sv.sendReply(msg.Pre, RPL_TOPIC, ch, sv.chTopics[ch]) sv.sendReply(msg.Pre, RPL_TOPIC, chid, sv.chTopics[chid])
} else { } else {
sv.chTopics[ch] = msg.Trail if sv.channelCheckMode(chid, "t") &&
!sv.channelCheckPerm(chid, clid, "oh") {
sv.sendReply(clid, ERR_CHANOPRIVSNEEDED, chid, "You're not channel operator")
return
}
sv.chTopics[chid] = msg.Trail
sv.sendMsg(msg) sv.sendMsg(msg)
//sv.sendReply(msg.Pre, RPL_TOPIC, ch, msg.Trail) //sv.sendReply(msg.Pre, RPL_TOPIC, ch, msg.Trail)
} }
} }
func handleCmdNames(sv *Server, msg *irc.Message) {
ch := msg.Args[0] func handleCmdKick(sv *Server, msg *irc.Message) {
if _, exists := sv.chUsers[ch]; !exists { chid := strings.ToLower(msg.Args[0])
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, ch, "No such channel") clid := strings.ToLower(msg.Pre)
target := strings.ToLower(msg.Args[1])
if !sv.channelCheckPerm(chid, clid, "oh") {
sv.sendReply(clid, ERR_CHANOPRIVSNEEDED, chid, "You're not channel operator")
} }
sv.channelNames(msg.Pre, ch) sv.sendMsg(msg)
delete(sv.chUsers[chid], target)
delete(sv.chModes[chid], "o "+target)
delete(sv.chModes[chid], "h "+target)
delete(sv.chModes[chid], "v "+target)
}
func handleCmdNames(sv *Server, msg *irc.Message) {
chid := strings.ToLower(msg.Args[0])
if _, exists := sv.chUsers[chid]; !exists {
sv.sendReply(msg.Pre, ERR_NOSUCHCHANNEL, chid, "No such channel")
}
sv.channelNames(msg.Pre, chid)
} }
func handleCmdWhois(sv *Server, msg *irc.Message) { func handleCmdWhois(sv *Server, msg *irc.Message) {
@ -546,3 +576,6 @@ func handleCmdRehash(sv *Server, msg *irc.Message) {
sv.sendReply(msg.Pre, RPL_REHASHING, "", "Rehashing.") sv.sendReply(msg.Pre, RPL_REHASHING, "", "Rehashing.")
xlog.Info("Rehashing") xlog.Info("Rehashing")
} }
func handleCmdKill(sv *Server, msg *irc.Message) {
}