Browse Source

add a config switch to accept hostnames from WEBIRC

See #1686; this allows i2pd to pass the i2p address to Ergo, which may be
useful for moderation under some circumstances.
pull/2146/head
Shivaram Lingamneni 2 weeks ago
parent
commit
7726160ec7
6 changed files with 62 additions and 36 deletions
  1. 4
    0
      default.yaml
  2. 38
    31
      irc/client.go
  3. 1
    0
      irc/gateways.go
  4. 15
    2
      irc/handlers.go
  5. 1
    3
      irc/server.go
  6. 3
    0
      traditional.yaml

+ 4
- 0
default.yaml View File

@@ -218,6 +218,10 @@ server:
218 218
                 # - "192.168.1.1"
219 219
                 # - "192.168.10.1/24"
220 220
 
221
+            # whether to accept the hostname parameter on the WEBIRC line as the IRC hostname
222
+            # (the default/recommended Ergo configuration will use cloaks instead)
223
+            accept-hostname: false
224
+
221 225
     # maximum length of clients' sendQ in bytes
222 226
     # this should be big enough to hold bursts of channel/direct messages
223 227
     max-sendq: 96k

+ 38
- 31
irc/client.go View File

@@ -160,13 +160,14 @@ type Session struct {
160 160
 	idleTimer  *time.Timer
161 161
 	pingSent   bool // we sent PING to a putatively idle connection and we're waiting for PONG
162 162
 
163
-	sessionID   int64
164
-	socket      *Socket
165
-	realIP      net.IP
166
-	proxiedIP   net.IP
167
-	rawHostname string
168
-	isTor       bool
169
-	hideSTS     bool
163
+	sessionID         int64
164
+	socket            *Socket
165
+	realIP            net.IP
166
+	proxiedIP         net.IP
167
+	rawHostname       string
168
+	hostnameFinalized bool
169
+	isTor             bool
170
+	hideSTS           bool
170 171
 
171 172
 	fakelag              Fakelag
172 173
 	deferredFakelagCount int
@@ -488,12 +489,21 @@ func (client *Client) resizeHistory(config *Config) {
488 489
 	}
489 490
 }
490 491
 
491
-// resolve an IP to an IRC-ready hostname, using reverse DNS, forward-confirming if necessary,
492
-// and sending appropriate notices to the client
493
-func (client *Client) lookupHostname(session *Session, overwrite bool) {
492
+// once we have the final IP address (from the connection itself or from proxy data),
493
+// compute the various possibilities for the hostname:
494
+// * In the default/recommended configuration, via the cloak algorithm
495
+// * If hostname lookup is enabled, via (forward-confirmed) reverse DNS
496
+// * If WEBIRC was used, possibly via the hostname passed on the WEBIRC line
497
+func (client *Client) finalizeHostname(session *Session) {
498
+	// only allow this once, since registration can fail (e.g. if the nickname is in use)
499
+	if session.hostnameFinalized {
500
+		return
501
+	}
502
+	session.hostnameFinalized = true
503
+
494 504
 	if session.isTor {
495 505
 		return
496
-	} // else: even if cloaking is enabled, look up the real hostname to show to operators
506
+	}
497 507
 
498 508
 	config := client.server.Config()
499 509
 	ip := session.realIP
@@ -501,30 +511,27 @@ func (client *Client) lookupHostname(session *Session, overwrite bool) {
501 511
 		ip = session.proxiedIP
502 512
 	}
503 513
 
504
-	var hostname string
505
-	lookupSuccessful := false
506
-	if config.Server.lookupHostnames {
507
-		session.Notice("*** Looking up your hostname...")
508
-		hostname, lookupSuccessful = utils.LookupHostname(ip, config.Server.ForwardConfirmHostnames)
509
-		if lookupSuccessful {
510
-			session.Notice("*** Found your hostname")
514
+	// even if cloaking is enabled, we may want to look up the real hostname to show to operators:
515
+	if session.rawHostname == "" {
516
+		var hostname string
517
+		lookupSuccessful := false
518
+		if config.Server.lookupHostnames {
519
+			session.Notice("*** Looking up your hostname...")
520
+			hostname, lookupSuccessful = utils.LookupHostname(ip, config.Server.ForwardConfirmHostnames)
521
+			if lookupSuccessful {
522
+				session.Notice("*** Found your hostname")
523
+			} else {
524
+				session.Notice("*** Couldn't look up your hostname")
525
+			}
511 526
 		} else {
512
-			session.Notice("*** Couldn't look up your hostname")
527
+			hostname = utils.IPStringToHostname(ip.String())
513 528
 		}
514
-	} else {
515
-		hostname = utils.IPStringToHostname(ip.String())
529
+		session.rawHostname = hostname
516 530
 	}
517 531
 
518
-	session.rawHostname = hostname
519
-	cloakedHostname := config.Server.Cloaks.ComputeCloak(ip)
520
-	client.stateMutex.Lock()
521
-	defer client.stateMutex.Unlock()
522
-	// update the hostname if this is a new connection, but not if it's a reattach
523
-	if overwrite || client.rawHostname == "" {
524
-		client.rawHostname = hostname
525
-		client.cloakedHostname = cloakedHostname
526
-		client.updateNickMaskNoMutex()
527
-	}
532
+	// these will be discarded if this is actually a reattach:
533
+	client.rawHostname = session.rawHostname
534
+	client.cloakedHostname = config.Server.Cloaks.ComputeCloak(ip)
528 535
 }
529 536
 
530 537
 func (client *Client) doIdentLookup(conn net.Conn) {

+ 1
- 0
irc/gateways.go View File

@@ -32,6 +32,7 @@ type webircConfig struct {
32 32
 	Fingerprint    *string // legacy name for certfp, #1050
33 33
 	Certfp         string
34 34
 	Hosts          []string
35
+	AcceptHostname bool `yaml:"accept-hostname"`
35 36
 	allowedNets    []net.IPNet
36 37
 }
37 38
 

+ 15
- 2
irc/handlers.go View File

@@ -3512,8 +3512,9 @@ func webircHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respo
3512 3512
 		}
3513 3513
 	}
3514 3514
 
3515
+	config := server.Config()
3515 3516
 	givenPassword := []byte(msg.Params[0])
3516
-	for _, info := range server.Config().Server.WebIRC {
3517
+	for _, info := range config.Server.WebIRC {
3517 3518
 		if utils.IPInNets(client.realIP, info.allowedNets) {
3518 3519
 			// confirm password and/or fingerprint
3519 3520
 			if 0 < len(info.Password) && bcrypt.CompareHashAndPassword(info.Password, givenPassword) != nil {
@@ -3523,11 +3524,23 @@ func webircHandler(server *Server, client *Client, msg ircmsg.Message, rb *Respo
3523 3524
 				continue
3524 3525
 			}
3525 3526
 
3526
-			err, quitMsg := client.ApplyProxiedIP(rb.session, net.ParseIP(msg.Params[3]), secure)
3527
+			candidateIP := msg.Params[3]
3528
+			err, quitMsg := client.ApplyProxiedIP(rb.session, net.ParseIP(candidateIP), secure)
3527 3529
 			if err != nil {
3528 3530
 				client.Quit(quitMsg, rb.session)
3529 3531
 				return true
3530 3532
 			} else {
3533
+				if info.AcceptHostname {
3534
+					candidateHostname := msg.Params[2]
3535
+					if candidateHostname != candidateIP {
3536
+						if utils.IsHostname(candidateHostname) {
3537
+							rb.session.rawHostname = candidateHostname
3538
+						} else {
3539
+							// log this at debug level since it may be spammy
3540
+							server.logger.Debug("internal", "invalid hostname from WEBIRC", candidateHostname)
3541
+						}
3542
+					}
3543
+				}
3531 3544
 				return false
3532 3545
 			}
3533 3546
 		}

+ 1
- 3
irc/server.go View File

@@ -314,9 +314,7 @@ func (server *Server) checkBanScriptExemptSASL(config *Config, session *Session)
314 314
 func (server *Server) tryRegister(c *Client, session *Session) (exiting bool) {
315 315
 	// XXX PROXY or WEBIRC MUST be sent as the first line of the session;
316 316
 	// if we are here at all that means we have the final value of the IP
317
-	if session.rawHostname == "" {
318
-		session.client.lookupHostname(session, false)
319
-	}
317
+	c.finalizeHostname(session)
320 318
 
321 319
 	// try to complete registration normally
322 320
 	// XXX(#1057) username can be filled in by an ident query without the client

+ 3
- 0
traditional.yaml View File

@@ -192,6 +192,9 @@ server:
192 192
                 # - "192.168.1.1"
193 193
                 # - "192.168.10.1/24"
194 194
 
195
+            # whether to accept the hostname parameter on the WEBIRC line as the IRC hostname
196
+            accept-hostname: true
197
+
195 198
     # maximum length of clients' sendQ in bytes
196 199
     # this should be big enough to hold bursts of channel/direct messages
197 200
     max-sendq: 96k

Loading…
Cancel
Save