Browse Source

allow UBAN <ip> REQUIRE-SASL

tags/v2.5.0-rc1
Shivaram Lingamneni 3 years ago
parent
commit
07fa2ecb3e
5 changed files with 42 additions and 21 deletions
  1. 4
    1
      irc/dline.go
  2. 6
    2
      irc/handlers.go
  3. 2
    2
      irc/help.go
  4. 10
    5
      irc/server.go
  5. 20
    11
      irc/uban.go

+ 4
- 1
irc/dline.go View File

@@ -20,6 +20,8 @@ const (
20 20
 
21 21
 // IPBanInfo holds info about an IP/net ban.
22 22
 type IPBanInfo struct {
23
+	// RequireSASL indicates a "soft" ban; connections are allowed but they must SASL
24
+	RequireSASL bool
23 25
 	// Reason is the ban reason.
24 26
 	Reason string `json:"reason"`
25 27
 	// OperReason is an oper ban reason.
@@ -95,12 +97,13 @@ func (dm *DLineManager) AllBans() map[string]IPBanInfo {
95 97
 }
96 98
 
97 99
 // AddNetwork adds a network to the blocked list.
98
-func (dm *DLineManager) AddNetwork(network flatip.IPNet, duration time.Duration, reason, operReason, operName string) error {
100
+func (dm *DLineManager) AddNetwork(network flatip.IPNet, duration time.Duration, requireSASL bool, reason, operReason, operName string) error {
99 101
 	dm.persistenceMutex.Lock()
100 102
 	defer dm.persistenceMutex.Unlock()
101 103
 
102 104
 	// assemble ban info
103 105
 	info := IPBanInfo{
106
+		RequireSASL: requireSASL,
104 107
 		Reason:      reason,
105 108
 		OperReason:  operReason,
106 109
 		OperName:    operName,

+ 6
- 2
irc/handlers.go View File

@@ -818,7 +818,11 @@ func formatBanForListing(client *Client, key string, info IPBanInfo) string {
818 818
 	if info.Duration != 0 {
819 819
 		desc = fmt.Sprintf("%s [%s]", desc, info.TimeLeft())
820 820
 	}
821
-	return fmt.Sprintf(client.t("Ban - %[1]s - added by %[2]s - %[3]s"), key, info.OperName, desc)
821
+	banType := "Ban"
822
+	if info.RequireSASL {
823
+		banType = "SASL required"
824
+	}
825
+	return fmt.Sprintf(client.t("%[1]s - %[2]s - added by %[3]s - %[4]s"), banType, key, info.OperName, desc)
822 826
 }
823 827
 
824 828
 // 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
906 910
 		operName = server.name
907 911
 	}
908 912
 
909
-	err = server.dlines.AddNetwork(flatip.FromNetIPNet(hostNet), duration, reason, operReason, operName)
913
+	err = server.dlines.AddNetwork(flatip.FromNetIPNet(hostNet), duration, false, reason, operReason, operName)
910 914
 
911 915
 	if err != nil {
912 916
 		rb.Notice(fmt.Sprintf(client.t("Could not successfully save new D-LINE: %s"), err.Error()))

+ 2
- 2
irc/help.go View File

@@ -518,13 +518,13 @@ given, views the current topic on the channel.`,
518 518
 
519 519
 Oragono's "unified ban" system. Accepts the following subcommands:
520 520
 
521
-1. UBAN ADD <target> [DURATION <duration>] [REASON...]
521
+1. UBAN ADD <target> [REQUIRE-SASL] [DURATION <duration>] [REASON...]
522 522
 2. UBAN DEL <target>
523 523
 3. UBAN LIST
524 524
 4. UBAN INFO <target>
525 525
 
526 526
 <target> may be an IP, a CIDR, a nickmask with wildcards, or the name of an
527
-account to suspend.`,
527
+account to suspend. Note that REQUIRE-SASL is only valid for IP and CIDR bans.`,
528 528
 	},
529 529
 	"undline": {
530 530
 		oper: true,

+ 10
- 5
irc/server.go View File

@@ -179,8 +179,13 @@ func (server *Server) checkBans(config *Config, ipaddr net.IP, checkScripts bool
179 179
 	// check DLINEs
180 180
 	isBanned, info := server.dlines.CheckIP(flat)
181 181
 	if isBanned {
182
-		server.logger.Info("connect-ip", "Client rejected by d-line", ipaddr.String())
183
-		return true, false, info.BanMessage("You are banned from this server (%s)")
182
+		if info.RequireSASL {
183
+			server.logger.Info("connect-ip", "Requiring SASL from client due to d-line", ipaddr.String())
184
+			return false, true, info.BanMessage("You must authenticate with SASL to connect from this IP (%s)")
185
+		} else {
186
+			server.logger.Info("connect-ip", "Client rejected by d-line", ipaddr.String())
187
+			return true, false, info.BanMessage("You are banned from this server (%s)")
188
+		}
184 189
 	}
185 190
 
186 191
 	// check connection limits
@@ -202,14 +207,14 @@ func (server *Server) checkBans(config *Config, ipaddr net.IP, checkScripts bool
202 207
 			server.logger.Error("internal", "couldn't check IP ban script", ipaddr.String(), err.Error())
203 208
 			return false, false, ""
204 209
 		}
205
-		// TODO: currently no way to cache results other than IPBanned
206
-		if output.Result == IPBanned && output.CacheSeconds != 0 {
210
+		// TODO: currently no way to cache IPAccepted
211
+		if (output.Result == IPBanned || output.Result == IPRequireSASL) && output.CacheSeconds != 0 {
207 212
 			network, err := flatip.ParseToNormalizedNet(output.CacheNet)
208 213
 			if err != nil {
209 214
 				server.logger.Error("internal", "invalid dline net from IP ban script", ipaddr.String(), output.CacheNet)
210 215
 			} else {
211 216
 				dlineDuration := time.Duration(output.CacheSeconds) * time.Second
212
-				err := server.dlines.AddNetwork(network, dlineDuration, output.BanMessage, "", "")
217
+				err := server.dlines.AddNetwork(network, dlineDuration, output.Result == IPRequireSASL, output.BanMessage, "", "")
213 218
 				if err != nil {
214 219
 					server.logger.Error("internal", "couldn't set dline from IP ban script", ipaddr.String(), err.Error())
215 220
 				}

+ 20
- 11
irc/uban.go View File

@@ -16,15 +16,24 @@ import (
16 16
 	"github.com/oragono/oragono/irc/utils"
17 17
 )
18 18
 
19
-func consumeDuration(params []string, rb *ResponseBuffer) (duration time.Duration, remainingParams []string, err error) {
19
+func consumeDuration(params []string, rb *ResponseBuffer) (duration time.Duration, requireSASL bool, remainingParams []string, err error) {
20 20
 	remainingParams = params
21
-	if 2 <= len(remainingParams) && strings.ToLower(remainingParams[0]) == "duration" {
22
-		duration, err = custime.ParseDuration(remainingParams[1])
23
-		if err != nil {
24
-			rb.Notice(rb.session.client.t("Invalid time duration for NS SUSPEND"))
25
-			return
21
+	for {
22
+		if duration == 0 && 2 <= len(remainingParams) && strings.ToLower(remainingParams[0]) == "duration" {
23
+			duration, err = custime.ParseDuration(remainingParams[1])
24
+			if err != nil {
25
+				rb.Notice(rb.session.client.t("Invalid time duration for NS SUSPEND"))
26
+				return
27
+			}
28
+			remainingParams = remainingParams[2:]
29
+			continue
30
+		}
31
+		if !requireSASL && 1 <= len(remainingParams) && strings.ToLower(remainingParams[0]) == "require-sasl" {
32
+			requireSASL = true
33
+			remainingParams = remainingParams[1:]
34
+			continue
26 35
 		}
27
-		remainingParams = remainingParams[2:]
36
+		break
28 37
 	}
29 38
 	return
30 39
 }
@@ -139,7 +148,7 @@ func sessionsForCIDR(server *Server, cidr flatip.IPNet, exclude *Session) (sessi
139 148
 }
140 149
 
141 150
 func ubanAddHandler(client *Client, target ubanTarget, params []string, rb *ResponseBuffer) bool {
142
-	duration, params, err := consumeDuration(params, rb)
151
+	duration, requireSASL, params, err := consumeDuration(params, rb)
143 152
 	if err != nil {
144 153
 		return false
145 154
 	}
@@ -148,7 +157,7 @@ func ubanAddHandler(client *Client, target ubanTarget, params []string, rb *Resp
148 157
 
149 158
 	switch target.banType {
150 159
 	case ubanCIDR:
151
-		ubanAddCIDR(client, target, duration, operReason, rb)
160
+		ubanAddCIDR(client, target, duration, requireSASL, operReason, rb)
152 161
 	case ubanNickmask:
153 162
 		ubanAddNickmask(client, target, duration, operReason, rb)
154 163
 	case ubanNick:
@@ -158,8 +167,8 @@ func ubanAddHandler(client *Client, target ubanTarget, params []string, rb *Resp
158 167
 	return false
159 168
 }
160 169
 
161
-func ubanAddCIDR(client *Client, target ubanTarget, duration time.Duration, operReason string, rb *ResponseBuffer) {
162
-	err := client.server.dlines.AddNetwork(target.cidr, duration, "", operReason, client.Oper().Name)
170
+func ubanAddCIDR(client *Client, target ubanTarget, duration time.Duration, requireSASL bool, operReason string, rb *ResponseBuffer) {
171
+	err := client.server.dlines.AddNetwork(target.cidr, duration, requireSASL, "", operReason, client.Oper().Name)
163 172
 	if err == nil {
164 173
 		rb.Notice(fmt.Sprintf(client.t("Successfully added UBAN for %s"), target.cidr.HumanReadableString()))
165 174
 	} else {

Loading…
Cancel
Save