diff options
| author | Přemysl Eric Janouch <p@janouch.name> | 2022-03-15 18:58:27 +0100 | 
|---|---|---|
| committer | Přemysl Eric Janouch <p@janouch.name> | 2022-03-15 19:57:31 +0100 | 
| commit | 9603456cd6f76554f0be8af1eb23c20872ad8e3d (patch) | |
| tree | e7acc4edb998dc4ce97ff80dbab92f2b384e5c4c /hid | |
| parent | b832a38ca63a4bdc777291709baaad233e25e2a4 (diff) | |
| download | haven-9603456cd6f76554f0be8af1eb23c20872ad8e3d.tar.gz haven-9603456cd6f76554f0be8af1eb23c20872ad8e3d.tar.xz haven-9603456cd6f76554f0be8af1eb23c20872ad8e3d.zip | |
hid: add WebIRC support
Such clients can only be identified through STATS L.
It's a bit weird to abuse the "port" field this way,
but right now, it serves its purpose.
Diffstat (limited to 'hid')
| -rw-r--r-- | hid/main.go | 50 | 
1 files changed, 45 insertions, 5 deletions
| diff --git a/hid/main.go b/hid/main.go index fd8d8fb..43a04f2 100644 --- a/hid/main.go +++ b/hid/main.go @@ -1,5 +1,5 @@  // -// Copyright (c) 2014 - 2018, Přemysl Eric Janouch <p@janouch.name> +// Copyright (c) 2014 - 2022, Přemysl Eric Janouch <p@janouch.name>  //  // Permission to use, copy, modify, and/or distribute this software for any  // purpose with or without fee is hereby granted. @@ -414,6 +414,7 @@ var configTable = []simpleConfigItem{  	{"bind", ":6667", "Bind addresses of the IRC server"},  	{"tls_cert", "", "Server TLS certificate (PEM)"},  	{"tls_key", "", "Server TLS private key (PEM)"}, +	{"webirc_password", "", "Password for WebIRC"},  	{"operators", "", "IRCop TLS certificate SHA-256 fingerprints"}, @@ -1437,6 +1438,44 @@ var ircCapHandlers = map[string]func(*client, *ircCapArgs){  // XXX: Maybe these also deserve to be methods for client?  They operate on  // global state, though. +func ircParseWEBIRCOptions(options string, out map[string]string) { +	for _, option := range strings.Split(options, " ") { +		if equal := strings.IndexByte(option, '='); equal < 0 { +			out[option] = "" +		} else { +			out[option[:equal]] = ircUnescapeMessageTag(option[equal+1:]) +		} +	} +} + +func ircHandleWEBIRC(msg *message, c *client) { +	if len(msg.params) < 4 { +		c.sendReply(ERR_NEEDMOREPARAMS, msg.command) +		return +	} + +	password, gateway, hostname := msg.params[0], msg.params[1], msg.params[2] +	if config["webirc_password"] != password { +		c.closeLink("Invalid WebIRC password") +		return +	} + +	options := make(map[string]string) +	if len(msg.params) >= 5 { +		ircParseWEBIRCOptions(msg.params[4], options) +	} + +	c.hostname = hostname +	c.port = "WebIRC-" + gateway +	c.address = net.JoinHostPort(hostname, c.port) + +	// Note that this overrides the gateway's certificate, conditionally. +	fp, _ := options["certfp-sha-256"] +	if _, secure := options["secure"]; secure && ircIsValidFingerprint(fp) { +		c.tlsCertFingerprint = strings.ToLower(fp) +	} +} +  func ircHandleCAP(msg *message, c *client) {  	if len(msg.params) < 1 {  		c.sendReply(ERR_NEEDMOREPARAMS, msg.command) @@ -2908,10 +2947,11 @@ func ircHandleDIE(msg *message, c *client) {  // TODO: Add a minimal parameter count?  // TODO: Add a field for oper-only commands? Use flags?  var ircHandlers = map[string]*ircCommand{ -	"CAP":  {false, ircHandleCAP, 0, 0}, -	"PASS": {false, ircHandlePASS, 0, 0}, -	"NICK": {false, ircHandleNICK, 0, 0}, -	"USER": {false, ircHandleUSER, 0, 0}, +	"WEBIRC": {false, ircHandleWEBIRC, 0, 0}, +	"CAP":    {false, ircHandleCAP, 0, 0}, +	"PASS":   {false, ircHandlePASS, 0, 0}, +	"NICK":   {false, ircHandleNICK, 0, 0}, +	"USER":   {false, ircHandleUSER, 0, 0},  	"USERHOST": {true, ircHandleUSERHOST, 0, 0},  	"LUSERS":   {true, ircHandleLUSERS, 0, 0}, | 
