forked from lug/matterbridge
		
	Add support for stateless bridging via draft/relaymsg (irc) (#1339)
* irc: add support for stateless bridging via draft/relaymsg As discussed at https://github.com/42wim/matterbridge/issues/667#issuecomment-634214165 * irc: handle the draft/relaymsg tag in spoofed messages too * Apply suggestions from code review Co-authored-by: Wim <wim@42.be> * Run gofmt on irc.go * Document relaymsg in matterbridge.toml.sample Co-authored-by: Wim <wim@42.be>
This commit is contained in:
		| @@ -205,27 +205,58 @@ func (b *Birc) doConnect() { | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Sanitize nicks for RELAYMSG: replace IRC characters with special meanings with "-" | ||||
| func sanitizeNick(nick string) string { | ||||
| 	sanitize := func(r rune) rune { | ||||
| 		if strings.ContainsRune("!+%@&#$:'\"?*,. ", r) { | ||||
| 			return '-' | ||||
| 		} | ||||
| 		return r | ||||
| 	} | ||||
| 	return strings.Map(sanitize, nick) | ||||
| } | ||||
|  | ||||
| func (b *Birc) doSend() { | ||||
| 	rate := time.Millisecond * time.Duration(b.MessageDelay) | ||||
| 	throttle := time.NewTicker(rate) | ||||
| 	for msg := range b.Local { | ||||
| 		<-throttle.C | ||||
| 		username := msg.Username | ||||
| 		if b.GetBool("Colornicks") && len(username) > 1 { | ||||
| 			checksum := crc32.ChecksumIEEE([]byte(msg.Username)) | ||||
| 			colorCode := checksum%14 + 2 // quick fix - prevent white or black color codes | ||||
| 			username = fmt.Sprintf("\x03%02d%s\x0F", colorCode, msg.Username) | ||||
| 		} | ||||
| 		// Optional support for the proposed RELAYMSG extension, described at | ||||
| 		// https://github.com/jlu5/ircv3-specifications/blob/master/extensions/relaymsg.md | ||||
| 		// nolint:nestif | ||||
| 		if (b.i.HasCapability("overdrivenetworks.com/relaymsg") || b.i.HasCapability("draft/relaymsg")) && | ||||
| 			b.GetBool("UseRelayMsg") { | ||||
| 			username = sanitizeNick(username) | ||||
| 			text := msg.Text | ||||
|  | ||||
| 		switch msg.Event { | ||||
| 		case config.EventUserAction: | ||||
| 			b.i.Cmd.Action(msg.Channel, username+msg.Text) | ||||
| 		case config.EventNoticeIRC: | ||||
| 			b.Log.Debugf("Sending notice to channel %s", msg.Channel) | ||||
| 			b.i.Cmd.Notice(msg.Channel, username+msg.Text) | ||||
| 		default: | ||||
| 			b.Log.Debugf("Sending to channel %s", msg.Channel) | ||||
| 			b.i.Cmd.Message(msg.Channel, username+msg.Text) | ||||
| 			// Work around girc chomping leading commas on single word messages? | ||||
| 			if strings.HasPrefix(text, ":") && !strings.ContainsRune(text, ' ') { | ||||
| 				text = ":" + text | ||||
| 			} | ||||
|  | ||||
| 			if msg.Event == config.EventUserAction { | ||||
| 				b.i.Cmd.SendRawf("RELAYMSG %s %s :\x01ACTION %s\x01", msg.Channel, username, text) //nolint:errcheck | ||||
| 			} else { | ||||
| 				b.Log.Debugf("Sending RELAYMSG to channel %s: nick=%s", msg.Channel, username) | ||||
| 				b.i.Cmd.SendRawf("RELAYMSG %s %s :%s", msg.Channel, username, text) //nolint:errcheck | ||||
| 			} | ||||
| 		} else { | ||||
| 			if b.GetBool("Colornicks") { | ||||
| 				checksum := crc32.ChecksumIEEE([]byte(msg.Username)) | ||||
| 				colorCode := checksum%14 + 2 // quick fix - prevent white or black color codes | ||||
| 				username = fmt.Sprintf("\x03%02d%s\x0F", colorCode, msg.Username) | ||||
| 			} | ||||
| 			switch msg.Event { | ||||
| 			case config.EventUserAction: | ||||
| 				b.i.Cmd.Action(msg.Channel, username+msg.Text) | ||||
| 			case config.EventNoticeIRC: | ||||
| 				b.Log.Debugf("Sending notice to channel %s", msg.Channel) | ||||
| 				b.i.Cmd.Notice(msg.Channel, username+msg.Text) | ||||
| 			default: | ||||
| 				b.Log.Debugf("Sending to channel %s", msg.Channel) | ||||
| 				b.i.Cmd.Message(msg.Channel, username+msg.Text) | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -273,8 +304,9 @@ func (b *Birc) getClient() (*girc.Client, error) { | ||||
| 		TLSConfig:  &tls.Config{InsecureSkipVerify: b.GetBool("SkipTLSVerify"), ServerName: server}, //nolint:gosec | ||||
| 		PingDelay:  pingDelay, | ||||
| 		// skip gIRC internal rate limiting, since we have our own throttling | ||||
| 		AllowFlood: true, | ||||
| 		Debug:      debug, | ||||
| 		AllowFlood:    true, | ||||
| 		Debug:         debug, | ||||
| 		SupportedCaps: map[string][]string{"overdrivenetworks.com/relaymsg": nil, "draft/relaymsg": nil}, | ||||
| 	}) | ||||
| 	return i, nil | ||||
| } | ||||
| @@ -311,6 +343,15 @@ func (b *Birc) skipPrivMsg(event girc.Event) bool { | ||||
| 	if event.Source.Name == b.Nick { | ||||
| 		return true | ||||
| 	} | ||||
| 	// don't forward messages we sent via RELAYMSG | ||||
| 	if relayedNick, ok := event.Tags.Get("draft/relaymsg"); ok && relayedNick == b.Nick { | ||||
| 		return true | ||||
| 	} | ||||
| 	// This is the old name of the cap sent in spoofed messages; I've kept this in | ||||
| 	// for compatibility reasons | ||||
| 	if relayedNick, ok := event.Tags.Get("relaymsg"); ok && relayedNick == b.Nick { | ||||
| 		return true | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -193,6 +193,19 @@ ShowTopicChange=false | ||||
| #OPTIONAL (default 0) | ||||
| JoinDelay=0 | ||||
|  | ||||
| #Use the optional RELAYMSG extension for username spoofing on IRC. | ||||
| #This requires an IRCd that supports the draft/relaymsg specification: currently this includes | ||||
| #Oragono 2.4.0+ and InspIRCd 3 with the m_relaymsg contrib module. | ||||
| #See https://github.com/42wim/matterbridge/issues/667#issuecomment-634214165 for more details. | ||||
| #Spoofed nicks will use the configured RemoteNickFormat, replacing reserved IRC characters | ||||
| #(!+%@&#$:'"?*,.) with a hyphen (-). | ||||
| #On most configurations, the RemoteNickFormat must include a separator character such as "/". | ||||
| #You should make sure that the settings here match your IRCd. | ||||
| #This option overrides ColorNicks. | ||||
| #OPTIONAL (default false) | ||||
| UseRelayMsg=false | ||||
| #RemoteNickFormat="{NICK}/{PROTOCOL}" | ||||
|  | ||||
| ################################################################### | ||||
| #XMPP section | ||||
| ################################################################### | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 James Lu
					James Lu