mirror of
https://github.com/ergochat/ergo.git
synced 2024-12-22 18:52:41 +01:00
Merge pull request #1504 from slingamn/soft_dline
allow UBAN <ip> REQUIRE-SASL
This commit is contained in:
commit
a988434bf3
@ -20,6 +20,8 @@ const (
|
|||||||
|
|
||||||
// IPBanInfo holds info about an IP/net ban.
|
// IPBanInfo holds info about an IP/net ban.
|
||||||
type IPBanInfo struct {
|
type IPBanInfo struct {
|
||||||
|
// RequireSASL indicates a "soft" ban; connections are allowed but they must SASL
|
||||||
|
RequireSASL bool
|
||||||
// Reason is the ban reason.
|
// Reason is the ban reason.
|
||||||
Reason string `json:"reason"`
|
Reason string `json:"reason"`
|
||||||
// OperReason is an oper ban reason.
|
// OperReason is an oper ban reason.
|
||||||
@ -95,12 +97,13 @@ func (dm *DLineManager) AllBans() map[string]IPBanInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddNetwork adds a network to the blocked list.
|
// AddNetwork adds a network to the blocked list.
|
||||||
func (dm *DLineManager) AddNetwork(network flatip.IPNet, duration time.Duration, reason, operReason, operName string) error {
|
func (dm *DLineManager) AddNetwork(network flatip.IPNet, duration time.Duration, requireSASL bool, reason, operReason, operName string) error {
|
||||||
dm.persistenceMutex.Lock()
|
dm.persistenceMutex.Lock()
|
||||||
defer dm.persistenceMutex.Unlock()
|
defer dm.persistenceMutex.Unlock()
|
||||||
|
|
||||||
// assemble ban info
|
// assemble ban info
|
||||||
info := IPBanInfo{
|
info := IPBanInfo{
|
||||||
|
RequireSASL: requireSASL,
|
||||||
Reason: reason,
|
Reason: reason,
|
||||||
OperReason: operReason,
|
OperReason: operReason,
|
||||||
OperName: operName,
|
OperName: operName,
|
||||||
|
@ -818,7 +818,11 @@ func formatBanForListing(client *Client, key string, info IPBanInfo) string {
|
|||||||
if info.Duration != 0 {
|
if info.Duration != 0 {
|
||||||
desc = fmt.Sprintf("%s [%s]", desc, info.TimeLeft())
|
desc = fmt.Sprintf("%s [%s]", desc, info.TimeLeft())
|
||||||
}
|
}
|
||||||
return fmt.Sprintf(client.t("Ban - %[1]s - added by %[2]s - %[3]s"), key, info.OperName, desc)
|
banType := "Ban"
|
||||||
|
if info.RequireSASL {
|
||||||
|
banType = "SASL required"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(client.t("%[1]s - %[2]s - added by %[3]s - %[4]s"), banType, key, info.OperName, desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DLINE [ANDKILL] [MYSELF] [duration] <ip>/<net> [ON <server>] [reason [| oper reason]]
|
// DLINE [ANDKILL] [MYSELF] [duration] <ip>/<net> [ON <server>] [reason [| oper reason]]
|
||||||
@ -906,7 +910,7 @@ func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
|
|||||||
operName = server.name
|
operName = server.name
|
||||||
}
|
}
|
||||||
|
|
||||||
err = server.dlines.AddNetwork(flatip.FromNetIPNet(hostNet), duration, reason, operReason, operName)
|
err = server.dlines.AddNetwork(flatip.FromNetIPNet(hostNet), duration, false, reason, operReason, operName)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rb.Notice(fmt.Sprintf(client.t("Could not successfully save new D-LINE: %s"), err.Error()))
|
rb.Notice(fmt.Sprintf(client.t("Could not successfully save new D-LINE: %s"), err.Error()))
|
||||||
|
@ -518,13 +518,13 @@ given, views the current topic on the channel.`,
|
|||||||
|
|
||||||
Oragono's "unified ban" system. Accepts the following subcommands:
|
Oragono's "unified ban" system. Accepts the following subcommands:
|
||||||
|
|
||||||
1. UBAN ADD <target> [DURATION <duration>] [REASON...]
|
1. UBAN ADD <target> [REQUIRE-SASL] [DURATION <duration>] [REASON...]
|
||||||
2. UBAN DEL <target>
|
2. UBAN DEL <target>
|
||||||
3. UBAN LIST
|
3. UBAN LIST
|
||||||
4. UBAN INFO <target>
|
4. UBAN INFO <target>
|
||||||
|
|
||||||
<target> may be an IP, a CIDR, a nickmask with wildcards, or the name of an
|
<target> may be an IP, a CIDR, a nickmask with wildcards, or the name of an
|
||||||
account to suspend.`,
|
account to suspend. Note that REQUIRE-SASL is only valid for IP and CIDR bans.`,
|
||||||
},
|
},
|
||||||
"undline": {
|
"undline": {
|
||||||
oper: true,
|
oper: true,
|
||||||
|
@ -179,8 +179,13 @@ func (server *Server) checkBans(config *Config, ipaddr net.IP, checkScripts bool
|
|||||||
// check DLINEs
|
// check DLINEs
|
||||||
isBanned, info := server.dlines.CheckIP(flat)
|
isBanned, info := server.dlines.CheckIP(flat)
|
||||||
if isBanned {
|
if isBanned {
|
||||||
server.logger.Info("connect-ip", "Client rejected by d-line", ipaddr.String())
|
if info.RequireSASL {
|
||||||
return true, false, info.BanMessage("You are banned from this server (%s)")
|
server.logger.Info("connect-ip", "Requiring SASL from client due to d-line", ipaddr.String())
|
||||||
|
return false, true, info.BanMessage("You must authenticate with SASL to connect from this IP (%s)")
|
||||||
|
} else {
|
||||||
|
server.logger.Info("connect-ip", "Client rejected by d-line", ipaddr.String())
|
||||||
|
return true, false, info.BanMessage("You are banned from this server (%s)")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check connection limits
|
// check connection limits
|
||||||
@ -202,14 +207,14 @@ func (server *Server) checkBans(config *Config, ipaddr net.IP, checkScripts bool
|
|||||||
server.logger.Error("internal", "couldn't check IP ban script", ipaddr.String(), err.Error())
|
server.logger.Error("internal", "couldn't check IP ban script", ipaddr.String(), err.Error())
|
||||||
return false, false, ""
|
return false, false, ""
|
||||||
}
|
}
|
||||||
// TODO: currently no way to cache results other than IPBanned
|
// TODO: currently no way to cache IPAccepted
|
||||||
if output.Result == IPBanned && output.CacheSeconds != 0 {
|
if (output.Result == IPBanned || output.Result == IPRequireSASL) && output.CacheSeconds != 0 {
|
||||||
network, err := flatip.ParseToNormalizedNet(output.CacheNet)
|
network, err := flatip.ParseToNormalizedNet(output.CacheNet)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
server.logger.Error("internal", "invalid dline net from IP ban script", ipaddr.String(), output.CacheNet)
|
server.logger.Error("internal", "invalid dline net from IP ban script", ipaddr.String(), output.CacheNet)
|
||||||
} else {
|
} else {
|
||||||
dlineDuration := time.Duration(output.CacheSeconds) * time.Second
|
dlineDuration := time.Duration(output.CacheSeconds) * time.Second
|
||||||
err := server.dlines.AddNetwork(network, dlineDuration, output.BanMessage, "", "")
|
err := server.dlines.AddNetwork(network, dlineDuration, output.Result == IPRequireSASL, output.BanMessage, "", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
server.logger.Error("internal", "couldn't set dline from IP ban script", ipaddr.String(), err.Error())
|
server.logger.Error("internal", "couldn't set dline from IP ban script", ipaddr.String(), err.Error())
|
||||||
}
|
}
|
||||||
|
31
irc/uban.go
31
irc/uban.go
@ -16,15 +16,24 @@ import (
|
|||||||
"github.com/oragono/oragono/irc/utils"
|
"github.com/oragono/oragono/irc/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func consumeDuration(params []string, rb *ResponseBuffer) (duration time.Duration, remainingParams []string, err error) {
|
func consumeDuration(params []string, rb *ResponseBuffer) (duration time.Duration, requireSASL bool, remainingParams []string, err error) {
|
||||||
remainingParams = params
|
remainingParams = params
|
||||||
if 2 <= len(remainingParams) && strings.ToLower(remainingParams[0]) == "duration" {
|
for {
|
||||||
duration, err = custime.ParseDuration(remainingParams[1])
|
if duration == 0 && 2 <= len(remainingParams) && strings.ToLower(remainingParams[0]) == "duration" {
|
||||||
if err != nil {
|
duration, err = custime.ParseDuration(remainingParams[1])
|
||||||
rb.Notice(rb.session.client.t("Invalid time duration for NS SUSPEND"))
|
if err != nil {
|
||||||
return
|
rb.Notice(rb.session.client.t("Invalid time duration for NS SUSPEND"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
remainingParams = remainingParams[2:]
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
remainingParams = remainingParams[2:]
|
if !requireSASL && 1 <= len(remainingParams) && strings.ToLower(remainingParams[0]) == "require-sasl" {
|
||||||
|
requireSASL = true
|
||||||
|
remainingParams = remainingParams[1:]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -139,7 +148,7 @@ func sessionsForCIDR(server *Server, cidr flatip.IPNet, exclude *Session) (sessi
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ubanAddHandler(client *Client, target ubanTarget, params []string, rb *ResponseBuffer) bool {
|
func ubanAddHandler(client *Client, target ubanTarget, params []string, rb *ResponseBuffer) bool {
|
||||||
duration, params, err := consumeDuration(params, rb)
|
duration, requireSASL, params, err := consumeDuration(params, rb)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -148,7 +157,7 @@ func ubanAddHandler(client *Client, target ubanTarget, params []string, rb *Resp
|
|||||||
|
|
||||||
switch target.banType {
|
switch target.banType {
|
||||||
case ubanCIDR:
|
case ubanCIDR:
|
||||||
ubanAddCIDR(client, target, duration, operReason, rb)
|
ubanAddCIDR(client, target, duration, requireSASL, operReason, rb)
|
||||||
case ubanNickmask:
|
case ubanNickmask:
|
||||||
ubanAddNickmask(client, target, duration, operReason, rb)
|
ubanAddNickmask(client, target, duration, operReason, rb)
|
||||||
case ubanNick:
|
case ubanNick:
|
||||||
@ -158,8 +167,8 @@ func ubanAddHandler(client *Client, target ubanTarget, params []string, rb *Resp
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func ubanAddCIDR(client *Client, target ubanTarget, duration time.Duration, operReason string, rb *ResponseBuffer) {
|
func ubanAddCIDR(client *Client, target ubanTarget, duration time.Duration, requireSASL bool, operReason string, rb *ResponseBuffer) {
|
||||||
err := client.server.dlines.AddNetwork(target.cidr, duration, "", operReason, client.Oper().Name)
|
err := client.server.dlines.AddNetwork(target.cidr, duration, requireSASL, "", operReason, client.Oper().Name)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
rb.Notice(fmt.Sprintf(client.t("Successfully added UBAN for %s"), target.cidr.HumanReadableString()))
|
rb.Notice(fmt.Sprintf(client.t("Successfully added UBAN for %s"), target.cidr.HumanReadableString()))
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user