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.
|
||||
type IPBanInfo struct {
|
||||
// RequireSASL indicates a "soft" ban; connections are allowed but they must SASL
|
||||
RequireSASL bool
|
||||
// Reason is the ban reason.
|
||||
Reason string `json:"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.
|
||||
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()
|
||||
defer dm.persistenceMutex.Unlock()
|
||||
|
||||
// assemble ban info
|
||||
info := IPBanInfo{
|
||||
RequireSASL: requireSASL,
|
||||
Reason: reason,
|
||||
OperReason: operReason,
|
||||
OperName: operName,
|
||||
|
@ -818,7 +818,11 @@ func formatBanForListing(client *Client, key string, info IPBanInfo) string {
|
||||
if info.Duration != 0 {
|
||||
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]]
|
||||
@ -906,7 +910,7 @@ func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
|
||||
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 {
|
||||
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:
|
||||
|
||||
1. UBAN ADD <target> [DURATION <duration>] [REASON...]
|
||||
1. UBAN ADD <target> [REQUIRE-SASL] [DURATION <duration>] [REASON...]
|
||||
2. UBAN DEL <target>
|
||||
3. UBAN LIST
|
||||
4. UBAN INFO <target>
|
||||
|
||||
<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": {
|
||||
oper: true,
|
||||
|
@ -179,9 +179,14 @@ func (server *Server) checkBans(config *Config, ipaddr net.IP, checkScripts bool
|
||||
// check DLINEs
|
||||
isBanned, info := server.dlines.CheckIP(flat)
|
||||
if isBanned {
|
||||
if info.RequireSASL {
|
||||
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
|
||||
err := server.connectionLimiter.AddClient(flat)
|
||||
@ -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())
|
||||
return false, false, ""
|
||||
}
|
||||
// TODO: currently no way to cache results other than IPBanned
|
||||
if output.Result == IPBanned && output.CacheSeconds != 0 {
|
||||
// TODO: currently no way to cache IPAccepted
|
||||
if (output.Result == IPBanned || output.Result == IPRequireSASL) && output.CacheSeconds != 0 {
|
||||
network, err := flatip.ParseToNormalizedNet(output.CacheNet)
|
||||
if err != nil {
|
||||
server.logger.Error("internal", "invalid dline net from IP ban script", ipaddr.String(), output.CacheNet)
|
||||
} else {
|
||||
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 {
|
||||
server.logger.Error("internal", "couldn't set dline from IP ban script", ipaddr.String(), err.Error())
|
||||
}
|
||||
|
21
irc/uban.go
21
irc/uban.go
@ -16,15 +16,24 @@ import (
|
||||
"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
|
||||
if 2 <= len(remainingParams) && strings.ToLower(remainingParams[0]) == "duration" {
|
||||
for {
|
||||
if duration == 0 && 2 <= len(remainingParams) && strings.ToLower(remainingParams[0]) == "duration" {
|
||||
duration, err = custime.ParseDuration(remainingParams[1])
|
||||
if err != nil {
|
||||
rb.Notice(rb.session.client.t("Invalid time duration for NS SUSPEND"))
|
||||
return
|
||||
}
|
||||
remainingParams = remainingParams[2:]
|
||||
continue
|
||||
}
|
||||
if !requireSASL && 1 <= len(remainingParams) && strings.ToLower(remainingParams[0]) == "require-sasl" {
|
||||
requireSASL = true
|
||||
remainingParams = remainingParams[1:]
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
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 {
|
||||
duration, params, err := consumeDuration(params, rb)
|
||||
duration, requireSASL, params, err := consumeDuration(params, rb)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
@ -148,7 +157,7 @@ func ubanAddHandler(client *Client, target ubanTarget, params []string, rb *Resp
|
||||
|
||||
switch target.banType {
|
||||
case ubanCIDR:
|
||||
ubanAddCIDR(client, target, duration, operReason, rb)
|
||||
ubanAddCIDR(client, target, duration, requireSASL, operReason, rb)
|
||||
case ubanNickmask:
|
||||
ubanAddNickmask(client, target, duration, operReason, rb)
|
||||
case ubanNick:
|
||||
@ -158,8 +167,8 @@ func ubanAddHandler(client *Client, target ubanTarget, params []string, rb *Resp
|
||||
return false
|
||||
}
|
||||
|
||||
func ubanAddCIDR(client *Client, target ubanTarget, duration time.Duration, operReason string, rb *ResponseBuffer) {
|
||||
err := client.server.dlines.AddNetwork(target.cidr, duration, "", operReason, client.Oper().Name)
|
||||
func ubanAddCIDR(client *Client, target ubanTarget, duration time.Duration, requireSASL bool, operReason string, rb *ResponseBuffer) {
|
||||
err := client.server.dlines.AddNetwork(target.cidr, duration, requireSASL, "", operReason, client.Oper().Name)
|
||||
if err == nil {
|
||||
rb.Notice(fmt.Sprintf(client.t("Successfully added UBAN for %s"), target.cidr.HumanReadableString()))
|
||||
} else {
|
||||
|
Loading…
Reference in New Issue
Block a user