mirror of
https://github.com/ergochat/ergo.git
synced 2024-11-10 22:19:31 +01:00
xline: Add ANDKILL param to kill all matching clients
This commit is contained in:
parent
3101f16478
commit
ebb9d629d7
@ -137,6 +137,11 @@ func NewClient(server *Server, conn net.Conn, isTLS bool) *Client {
|
|||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IP returns the IP address of this client.
|
||||||
|
func (client *Client) IP() net.IP {
|
||||||
|
return net.ParseIP(IPString(client.socket.conn.RemoteAddr()))
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// command goroutine
|
// command goroutine
|
||||||
//
|
//
|
||||||
@ -475,7 +480,7 @@ func (client *Client) destroy() {
|
|||||||
friends.Remove(client)
|
friends.Remove(client)
|
||||||
|
|
||||||
// remove from connection limits
|
// remove from connection limits
|
||||||
ipaddr := net.ParseIP(IPString(client.socket.conn.RemoteAddr()))
|
ipaddr := client.IP()
|
||||||
// this check shouldn't be required but eh
|
// this check shouldn't be required but eh
|
||||||
if ipaddr != nil {
|
if ipaddr != nil {
|
||||||
client.server.connectionLimitsMutex.Lock()
|
client.server.connectionLimitsMutex.Lock()
|
||||||
|
45
irc/dline.go
45
irc/dline.go
@ -183,7 +183,7 @@ func (dm *DLineManager) CheckIP(addr net.IP) (isBanned bool, info *IPBanInfo) {
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DLINE [MYSELF] [duration] <ip>/<net> [ON <server>] [reason [| oper reason]]
|
// DLINE [ANDKILL] [MYSELF] [duration] <ip>/<net> [ON <server>] [reason [| oper reason]]
|
||||||
func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||||
// check oper permissions
|
// check oper permissions
|
||||||
if !client.class.Capabilities["oper:local_ban"] {
|
if !client.class.Capabilities["oper:local_ban"] {
|
||||||
@ -193,6 +193,13 @@ func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
|
|
||||||
currentArg := 0
|
currentArg := 0
|
||||||
|
|
||||||
|
// when setting a ban, if they say "ANDKILL" we should also kill all users who match it
|
||||||
|
var andKill bool
|
||||||
|
if len(msg.Params) > currentArg+1 && strings.ToLower(msg.Params[currentArg]) == "andkill" {
|
||||||
|
andKill = true
|
||||||
|
currentArg++
|
||||||
|
}
|
||||||
|
|
||||||
// when setting a ban that covers the oper's current connection, we require them to say
|
// when setting a ban that covers the oper's current connection, we require them to say
|
||||||
// "DLINE MYSELF" so that we're sure they really mean it.
|
// "DLINE MYSELF" so that we're sure they really mean it.
|
||||||
var dlineMyself bool
|
var dlineMyself bool
|
||||||
@ -232,13 +239,13 @@ func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
|
|
||||||
if hostNet == nil {
|
if hostNet == nil {
|
||||||
hostString = hostAddr.String()
|
hostString = hostAddr.String()
|
||||||
if !dlineMyself && hostAddr.Equal(net.ParseIP(IPString(client.socket.conn.RemoteAddr()))) {
|
if !dlineMyself && hostAddr.Equal(client.IP()) {
|
||||||
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, "This ban matches you. To DLINE yourself, you must use the command: /DLINE MYSELF <arguments>")
|
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, "This ban matches you. To DLINE yourself, you must use the command: /DLINE MYSELF <arguments>")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
hostString = hostNet.String()
|
hostString = hostNet.String()
|
||||||
if !dlineMyself && hostNet.Contains(net.ParseIP(IPString(client.socket.conn.RemoteAddr()))) {
|
if !dlineMyself && hostNet.Contains(client.IP()) {
|
||||||
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, "This ban matches you. To DLINE yourself, you must use the command: /DLINE MYSELF <arguments>")
|
client.Send(nil, server.name, ERR_UNKNOWNERROR, client.nick, msg.Command, "This ban matches you. To DLINE yourself, you must use the command: /DLINE MYSELF <arguments>")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -315,7 +322,37 @@ func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
client.Notice(fmt.Sprintf("Added D-Line for %s", hostString))
|
client.Notice(fmt.Sprintf("Added D-Line for %s", hostString))
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
var killClient bool
|
||||||
|
if andKill {
|
||||||
|
var clientsToKill []*Client
|
||||||
|
var toKill bool
|
||||||
|
|
||||||
|
server.clients.ByNickMutex.RLock()
|
||||||
|
for _, mcl := range server.clients.ByNick {
|
||||||
|
if hostNet == nil {
|
||||||
|
toKill = hostAddr.Equal(mcl.IP())
|
||||||
|
} else {
|
||||||
|
toKill = hostNet.Contains(mcl.IP())
|
||||||
|
}
|
||||||
|
|
||||||
|
if toKill {
|
||||||
|
clientsToKill = append(clientsToKill, mcl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server.clients.ByNickMutex.RUnlock()
|
||||||
|
|
||||||
|
for _, mcl := range clientsToKill {
|
||||||
|
mcl.Quit(fmt.Sprintf("You have been banned from this server (%s)", reason))
|
||||||
|
if mcl == client {
|
||||||
|
killClient = true
|
||||||
|
} else {
|
||||||
|
// if mcl == client, we kill them below
|
||||||
|
mcl.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return killClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func unDLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
func unDLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||||
|
@ -145,7 +145,7 @@ Prints debug information about the IRCd. <option> can be one of:
|
|||||||
},
|
},
|
||||||
"dline": {
|
"dline": {
|
||||||
oper: true,
|
oper: true,
|
||||||
text: `DLINE [MYSELF] [duration] <ip>/<net> [ON <server>] [reason [| oper reason]]
|
text: `DLINE [ANDKILL] [MYSELF] [duration] <ip>/<net> [ON <server>] [reason [| oper reason]]
|
||||||
|
|
||||||
Bans an IP address or network from connecting to the server. If the duration is
|
Bans an IP address or network from connecting to the server. If the duration is
|
||||||
given then only for that long. The reason is shown to the user themselves, but
|
given then only for that long. The reason is shown to the user themselves, but
|
||||||
@ -154,6 +154,8 @@ operators getting info about the DLINEs that exist.
|
|||||||
|
|
||||||
Bans are saved across subsequent launches of the server.
|
Bans are saved across subsequent launches of the server.
|
||||||
|
|
||||||
|
"ANDKILL" means that all matching clients are also removed from the server.
|
||||||
|
|
||||||
"MYSELF" is required when the DLINE matches the address the person applying it is connected
|
"MYSELF" is required when the DLINE matches the address the person applying it is connected
|
||||||
from. If "MYSELF" is not given, trying to DLINE yourself will result in an error.
|
from. If "MYSELF" is not given, trying to DLINE yourself will result in an error.
|
||||||
|
|
||||||
@ -211,7 +213,7 @@ supplied.`,
|
|||||||
},
|
},
|
||||||
"kline": {
|
"kline": {
|
||||||
oper: true,
|
oper: true,
|
||||||
text: `KLINE [MYSELF] [duration] <mask> [ON <server>] [reason [| oper reason]]
|
text: `KLINE [ANDKILL] [MYSELF] [duration] <mask> [ON <server>] [reason [| oper reason]]
|
||||||
|
|
||||||
Bans a mask from connecting to the server. If the duration is given then only for that
|
Bans a mask from connecting to the server. If the duration is given then only for that
|
||||||
long. The reason is shown to the user themselves, but everyone else will see a standard
|
long. The reason is shown to the user themselves, but everyone else will see a standard
|
||||||
@ -219,6 +221,8 @@ message. The oper reason is shown to operators getting info about the KLINEs tha
|
|||||||
|
|
||||||
Bans are saved across subsequent launches of the server.
|
Bans are saved across subsequent launches of the server.
|
||||||
|
|
||||||
|
"ANDKILL" means that all matching clients are also removed from the server.
|
||||||
|
|
||||||
"MYSELF" is required when the KLINE matches the address the person applying it is connected
|
"MYSELF" is required when the KLINE matches the address the person applying it is connected
|
||||||
from. If "MYSELF" is not given, trying to KLINE yourself will result in an error.
|
from. If "MYSELF" is not given, trying to KLINE yourself will result in an error.
|
||||||
|
|
||||||
|
36
irc/kline.go
36
irc/kline.go
@ -110,7 +110,7 @@ func (km *KLineManager) CheckMasks(masks ...string) (isBanned bool, info *IPBanI
|
|||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// KLINE [MYSELF] [duration] <mask> [ON <server>] [reason [| oper reason]]
|
// KLINE [ANDKILL] [MYSELF] [duration] <mask> [ON <server>] [reason [| oper reason]]
|
||||||
func klineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
func klineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||||
// check oper permissions
|
// check oper permissions
|
||||||
if !client.class.Capabilities["oper:local_ban"] {
|
if !client.class.Capabilities["oper:local_ban"] {
|
||||||
@ -120,6 +120,13 @@ func klineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
|
|
||||||
currentArg := 0
|
currentArg := 0
|
||||||
|
|
||||||
|
// when setting a ban, if they say "ANDKILL" we should also kill all users who match it
|
||||||
|
var andKill bool
|
||||||
|
if len(msg.Params) > currentArg+1 && strings.ToLower(msg.Params[currentArg]) == "andkill" {
|
||||||
|
andKill = true
|
||||||
|
currentArg++
|
||||||
|
}
|
||||||
|
|
||||||
// when setting a ban that covers the oper's current connection, we require them to say
|
// when setting a ban that covers the oper's current connection, we require them to say
|
||||||
// "KLINE MYSELF" so that we're sure they really mean it.
|
// "KLINE MYSELF" so that we're sure they really mean it.
|
||||||
var klineMyself bool
|
var klineMyself bool
|
||||||
@ -226,7 +233,32 @@ func klineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
|||||||
client.Notice(fmt.Sprintf("Added K-Line for %s", mask))
|
client.Notice(fmt.Sprintf("Added K-Line for %s", mask))
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
var killClient bool
|
||||||
|
if andKill {
|
||||||
|
var clientsToKill []*Client
|
||||||
|
|
||||||
|
server.clients.ByNickMutex.RLock()
|
||||||
|
for _, mcl := range server.clients.ByNick {
|
||||||
|
for _, clientMask := range mcl.AllNickmasks() {
|
||||||
|
if matcher.Match(clientMask) {
|
||||||
|
clientsToKill = append(clientsToKill, mcl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
server.clients.ByNickMutex.RUnlock()
|
||||||
|
|
||||||
|
for _, mcl := range clientsToKill {
|
||||||
|
mcl.Quit(fmt.Sprintf("You have been banned from this server (%s)", reason))
|
||||||
|
if mcl == client {
|
||||||
|
killClient = true
|
||||||
|
} else {
|
||||||
|
// if mcl == client, we kill them below
|
||||||
|
mcl.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return killClient
|
||||||
}
|
}
|
||||||
|
|
||||||
func unKLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
func unKLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage) bool {
|
||||||
|
@ -1358,7 +1358,7 @@ func (server *Server) rehash() error {
|
|||||||
|
|
||||||
server.clients.ByNickMutex.RLock()
|
server.clients.ByNickMutex.RLock()
|
||||||
for _, client := range server.clients.ByNick {
|
for _, client := range server.clients.ByNick {
|
||||||
ipaddr := net.ParseIP(IPString(client.socket.conn.RemoteAddr()))
|
ipaddr := client.IP()
|
||||||
if ipaddr != nil {
|
if ipaddr != nil {
|
||||||
server.connectionLimits.AddClient(ipaddr, true)
|
server.connectionLimits.AddClient(ipaddr, true)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user