diff options
Diffstat (limited to 'vendor/github.com/lrstanley/girc')
-rw-r--r-- | vendor/github.com/lrstanley/girc/README.md | 2 | ||||
-rw-r--r-- | vendor/github.com/lrstanley/girc/builtin.go | 48 | ||||
-rw-r--r-- | vendor/github.com/lrstanley/girc/cap_tags.go | 2 | ||||
-rw-r--r-- | vendor/github.com/lrstanley/girc/client.go | 45 | ||||
-rw-r--r-- | vendor/github.com/lrstanley/girc/commands.go | 6 | ||||
-rw-r--r-- | vendor/github.com/lrstanley/girc/conn.go | 11 | ||||
-rw-r--r-- | vendor/github.com/lrstanley/girc/constants.go | 31 | ||||
-rw-r--r-- | vendor/github.com/lrstanley/girc/ctcp.go | 18 | ||||
-rw-r--r-- | vendor/github.com/lrstanley/girc/event.go | 11 | ||||
-rw-r--r-- | vendor/github.com/lrstanley/girc/state.go | 10 |
10 files changed, 126 insertions, 58 deletions
diff --git a/vendor/github.com/lrstanley/girc/README.md b/vendor/github.com/lrstanley/girc/README.md index ddc1193c..35f3d818 100644 --- a/vendor/github.com/lrstanley/girc/README.md +++ b/vendor/github.com/lrstanley/girc/README.md @@ -88,6 +88,8 @@ girc artwork licensed under [CC 3.0](http://creativecommons.org/licenses/by/3.0/ * [IRCv3: Specification Docs](http://ircv3.net/irc/) * [IRCv3: Specification Repo](https://github.com/ircv3/ircv3-specifications) * [IRCv3 Capability Registry](http://ircv3.net/registry.html) + * [IRCv3: WEBIRC](https://ircv3.net/specs/extensions/webirc.html) + * [KiwiIRC: WEBIRC](https://kiwiirc.com/docs/webirc) * [ISUPPORT Specification Docs](http://www.irc.org/tech_docs/005.html) ([alternative 1](http://defs.ircdocs.horse/defs/isupport.html), [alternative 2](https://github.com/grawity/irc-docs/blob/master/client/RPL_ISUPPORT/draft-hardy-irc-isupport-00.txt), [relevant draft](http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt)) * [IRC Numerics List](http://defs.ircdocs.horse/defs/numerics.html) * [Extended WHO (also known as WHOX)](https://github.com/quakenet/snircd/blob/master/doc/readme.who) diff --git a/vendor/github.com/lrstanley/girc/builtin.go b/vendor/github.com/lrstanley/girc/builtin.go index 12257ca3..9dd02804 100644 --- a/vendor/github.com/lrstanley/girc/builtin.go +++ b/vendor/github.com/lrstanley/girc/builtin.go @@ -145,7 +145,7 @@ func handleJOIN(c *Client, e Event) { user := c.state.lookupUser(e.Source.Name) if user == nil { - if ok := c.state.createUser(e.Source.Name); !ok { + if ok := c.state.createUser(e.Source); !ok { c.state.Unlock() return } @@ -169,7 +169,7 @@ func handleJOIN(c *Client, e Event) { } c.state.Unlock() - if e.Source.Name == c.GetNick() { + if e.Source.ID() == c.GetID() { // If it's us, don't just add our user to the list. Run a WHO which // will tell us who exactly is in the entire channel. c.Send(&Event{Command: WHO, Params: []string{channelName, "%tacuhnr,1"}}) @@ -209,7 +209,7 @@ func handlePART(c *Client, e Event) { defer c.state.notify(c, UPDATE_STATE) - if e.Source.Name == c.GetNick() { + if e.Source.ID() == c.GetID() { c.state.Lock() c.state.deleteChannel(channel) c.state.Unlock() @@ -217,7 +217,7 @@ func handlePART(c *Client, e Event) { } c.state.Lock() - c.state.deleteUser(channel, e.Source.Name) + c.state.deleteUser(channel, e.Source.ID()) c.state.Unlock() } @@ -327,9 +327,9 @@ func handleNICK(c *Client, e Event) { c.state.Lock() // renameUser updates the LastActive time automatically. if len(e.Params) == 1 { - c.state.renameUser(e.Source.Name, e.Params[0]) + c.state.renameUser(e.Source.ID(), e.Params[0]) } else if len(e.Trailing) > 0 { - c.state.renameUser(e.Source.Name, e.Trailing) + c.state.renameUser(e.Source.ID(), e.Trailing) } c.state.Unlock() c.state.notify(c, UPDATE_STATE) @@ -341,12 +341,12 @@ func handleQUIT(c *Client, e Event) { return } - if e.Source.Name == c.GetNick() { + if e.Source.ID() == c.GetID() { return } c.state.Lock() - c.state.deleteUser("", e.Source.Name) + c.state.deleteUser("", e.Source.ID()) c.state.Unlock() c.state.notify(c, UPDATE_STATE) } @@ -443,8 +443,9 @@ func handleNAMES(c *Client, e Event) { parts := strings.Split(e.Trailing, " ") - var host, ident, modes, nick string + var modes, nick string var ok bool + s := &Source{} c.state.Lock() for i := 0; i < len(parts); i++ { @@ -455,36 +456,29 @@ func handleNAMES(c *Client, e Event) { // If userhost-in-names. if strings.Contains(nick, "@") { - s := ParseSource(nick) + s = ParseSource(nick) if s == nil { continue } - host = s.Host - nick = s.Name - ident = s.Ident - } + } else { + s = &Source{ + Name: nick, + } - if !IsValidNick(nick) { - continue + if !IsValidNick(s.Name) { + continue + } } - c.state.createUser(nick) - user := c.state.lookupUser(nick) + c.state.createUser(s) + user := c.state.lookupUser(s.Name) if user == nil { continue } user.addChannel(channel.Name) - channel.addUser(nick) - - // Add necessary userhost-in-names data into the user. - if host != "" { - user.Host = host - } - if ident != "" { - user.Ident = ident - } + channel.addUser(s.ID()) // Don't append modes, overwrite them. perms, _ := user.Perms.Lookup(channel.Name) diff --git a/vendor/github.com/lrstanley/girc/cap_tags.go b/vendor/github.com/lrstanley/girc/cap_tags.go index a4026a01..aff10f69 100644 --- a/vendor/github.com/lrstanley/girc/cap_tags.go +++ b/vendor/github.com/lrstanley/girc/cap_tags.go @@ -25,7 +25,7 @@ func handleTags(c *Client, e Event) { } c.state.Lock() - user := c.state.lookupUser(e.Source.Name) + user := c.state.lookupUser(e.Source.ID()) if user != nil { user.Extras.Account = account } diff --git a/vendor/github.com/lrstanley/girc/client.go b/vendor/github.com/lrstanley/girc/client.go index 63f47eaa..b8abb642 100644 --- a/vendor/github.com/lrstanley/girc/client.go +++ b/vendor/github.com/lrstanley/girc/client.go @@ -81,6 +81,10 @@ type Config struct { // supported. Capability tracking must be enabled for this to work, as // this requires IRCv3 CAP handling. SASL SASLMech + // WebIRC allows forwarding source user hostname/ip information to the server + // (if supported by the server) to ensure the source machine doesn't show as + // the source. See the WebIRC type for more information. + WebIRC WebIRC // Bind is used to bind to a specific host or ip during the dial process // when connecting to the server. This can be a hostname, however it must // resolve to an IPv4/IPv6 address bindable on your system. Otherwise, @@ -154,6 +158,39 @@ type Config struct { HandleNickCollide func(oldNick string) (newNick string) } +// WebIRC is useful when a user connects through an indirect method, such web +// clients, the indirect client sends its own IP address instead of sending the +// user's IP address unless WebIRC is implemented by both the client and the +// server. +// +// Client expectations: +// - Perform any proxy resolution. +// - Check the reverse DNS and forward DNS match. +// - Check the IP against suitable access controls (ipaccess, dnsbl, etc). +// +// More information: +// - https://ircv3.net/specs/extensions/webirc.html +// - https://kiwiirc.com/docs/webirc +type WebIRC struct { + // Password that authenticates the WEBIRC command from this client. + Password string + // Gateway or client type requesting spoof (cgiirc defaults to cgiirc, as an + // example). + Gateway string + // Hostname of user. + Hostname string + // Address either in IPv4 dotted quad notation (e.g. 192.0.0.2) or IPv6 + // notation (e.g. 1234:5678:9abc::def). IPv4-in-IPv6 addresses + // (e.g. ::ffff:192.0.0.2) should not be sent. + Address string +} + +// Params returns the arguments for the WEBIRC command that can be passed to the +// server. +func (w WebIRC) Params() []string { + return []string{w.Password, w.Gateway, w.Hostname, w.Address} +} + // ErrInvalidConfig is returned when the configuration passed to the client // is invalid. type ErrInvalidConfig struct { @@ -273,7 +310,7 @@ func (c *Client) TLSConnectionState() (*tls.ConnectionState, error) { // the connection to the server wasn't made with TLS. var ErrConnNotTLS = errors.New("underlying connection is not tls") -// Close closes the network connection to the server, and sends a STOPPED +// Close closes the network connection to the server, and sends a CLOSED // event. This should cause Connect() to return with nil. This should be // safe to call multiple times. See Connect()'s documentation on how // handlers and goroutines are handled when disconnected from the server. @@ -436,6 +473,12 @@ func (c *Client) GetNick() string { return c.state.nick } +// GetID returns an RFC1459 compliant version of the current nickname. Panics +// if tracking is disabled. +func (c *Client) GetID() string { + return ToRFC1459(c.GetNick()) +} + // GetIdent returns the current ident of the active connection. Panics if // tracking is disabled. May be empty, as this is obtained from when we join // a channel, as there is no other more efficient method to return this info. diff --git a/vendor/github.com/lrstanley/girc/commands.go b/vendor/github.com/lrstanley/girc/commands.go index 300db9ed..79287d52 100644 --- a/vendor/github.com/lrstanley/girc/commands.go +++ b/vendor/github.com/lrstanley/girc/commands.go @@ -359,3 +359,9 @@ func (cmd *Commands) List(channels ...string) { func (cmd *Commands) Whowas(user string, amount int) { cmd.c.Send(&Event{Command: WHOWAS, Params: []string{user, string(amount)}}) } + +// Monitor sends a MONITOR query to the server. The results of the query +// depends on the given modifier, see https://ircv3.net/specs/core/monitor-3.2.html +func (cmd *Commands) Monitor(modifier rune, args ...string) { + cmd.c.Send(&Event{Command: MONITOR, Params: append([]string{string(modifier)}, args...)}) +} diff --git a/vendor/github.com/lrstanley/girc/conn.go b/vendor/github.com/lrstanley/girc/conn.go index 77d87988..d0579815 100644 --- a/vendor/github.com/lrstanley/girc/conn.go +++ b/vendor/github.com/lrstanley/girc/conn.go @@ -284,6 +284,11 @@ func (c *Client) internalConnect(mock net.Conn, dialer Dialer) error { go c.pingLoop(ctx, errs, &wg) // Passwords first. + + if c.Config.WebIRC.Password != "" { + c.write(&Event{Command: WEBIRC, Params: c.Config.WebIRC.Params(), Sensitive: true}) + } + if c.Config.ServerPass != "" { c.write(&Event{Command: PASS, Params: []string{c.Config.ServerPass}, Sensitive: true}) } @@ -314,7 +319,7 @@ func (c *Client) internalConnect(mock net.Conn, dialer Dialer) error { select { case <-ctx.Done(): c.debug.Print("received request to close, beginning clean up") - c.RunHandlers(&Event{Command: STOPPED, Trailing: c.Server()}) + c.RunHandlers(&Event{Command: CLOSED, Trailing: c.Server()}) case err := <-errs: c.debug.Print("received error, beginning clean up") result = err @@ -331,6 +336,8 @@ func (c *Client) internalConnect(mock net.Conn, dialer Dialer) error { c.conn.mu.Unlock() c.mu.RUnlock() + c.RunHandlers(&Event{Command: DISCONNECTED, Trailing: c.Server()}) + // Once we have our error/result, let all other functions know we're done. c.debug.Print("waiting for all routines to finish") @@ -374,7 +381,7 @@ func (c *Client) readLoop(ctx context.Context, errs chan error, wg *sync.WaitGro // Check if it's an echo-message. if !c.Config.disableTracking { event.Echo = (event.Command == PRIVMSG || event.Command == NOTICE) && - event.Source != nil && event.Source.Name == c.GetNick() + event.Source != nil && event.Source.ID() == c.GetID() } c.rx <- event diff --git a/vendor/github.com/lrstanley/girc/constants.go b/vendor/github.com/lrstanley/girc/constants.go index 76ba482d..ddea7d0d 100644 --- a/vendor/github.com/lrstanley/girc/constants.go +++ b/vendor/github.com/lrstanley/girc/constants.go @@ -27,7 +27,7 @@ const ( CONNECTED = "CLIENT_CONNECTED" // when it's safe to send arbitrary commands (joins, list, who, etc), trailing is host:port INITIALIZED = "CLIENT_INIT" // verifies successful socket connection, trailing is host:port DISCONNECTED = "CLIENT_DISCONNECTED" // occurs when we're disconnected from the server (user-requested or not) - STOPPED = "CLIENT_STOPPED" // occurs when Client.Stop() has been called + CLOSED = "CLIENT_CLOSED" // occurs when Client.Close() has been called ) // User/channel prefixes :: RFC1459. @@ -118,6 +118,7 @@ const ( USERS = "USERS" VERSION = "VERSION" WALLOPS = "WALLOPS" + WEBIRC = "WEBIRC" WHO = "WHO" WHOIS = "WHOIS" WHOWAS = "WHOWAS" @@ -268,6 +269,7 @@ const ( // IRCv3 commands and extensions :: http://ircv3.net/irc/. const ( AUTHENTICATE = "AUTHENTICATE" + MONITOR = "MONITOR" STARTTLS = "STARTTLS" CAP = "CAP" @@ -288,17 +290,22 @@ const ( // Numeric IRC reply mapping for ircv3 :: http://ircv3.net/irc/. const ( - RPL_LOGGEDIN = "900" - RPL_LOGGEDOUT = "901" - RPL_NICKLOCKED = "902" - RPL_SASLSUCCESS = "903" - ERR_SASLFAIL = "904" - ERR_SASLTOOLONG = "905" - ERR_SASLABORTED = "906" - ERR_SASLALREADY = "907" - RPL_SASLMECHS = "908" - RPL_STARTTLS = "670" - ERR_STARTTLS = "691" + RPL_LOGGEDIN = "900" + RPL_LOGGEDOUT = "901" + RPL_NICKLOCKED = "902" + RPL_SASLSUCCESS = "903" + ERR_SASLFAIL = "904" + ERR_SASLTOOLONG = "905" + ERR_SASLABORTED = "906" + ERR_SASLALREADY = "907" + RPL_SASLMECHS = "908" + RPL_STARTTLS = "670" + ERR_STARTTLS = "691" + RPL_MONONLINE = "730" + RPL_MONOFFLINE = "731" + RPL_MONLIST = "732" + RPL_ENDOFMONLIST = "733" + ERR_MONLISTFULL = "734" ) // Numeric IRC event mapping :: RFC2812; section 5.3. diff --git a/vendor/github.com/lrstanley/girc/ctcp.go b/vendor/github.com/lrstanley/girc/ctcp.go index 45fc6be5..56f4c85c 100644 --- a/vendor/github.com/lrstanley/girc/ctcp.go +++ b/vendor/github.com/lrstanley/girc/ctcp.go @@ -155,8 +155,8 @@ func (c *CTCP) call(client *Client, event *CTCPEvent) { } // Send a ERRMSG reply, if we know who sent it. - if event.Source != nil && IsValidNick(event.Source.Name) { - client.Cmd.SendCTCPReply(event.Source.Name, CTCP_ERRMSG, "that is an unknown CTCP query") + if event.Source != nil && IsValidNick(event.Source.ID()) { + client.Cmd.SendCTCPReply(event.Source.ID(), CTCP_ERRMSG, "that is an unknown CTCP query") } return } @@ -248,7 +248,7 @@ func handleCTCPPing(client *Client, ctcp CTCPEvent) { if ctcp.Reply { return } - client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_PING, ctcp.Text) + client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_PING, ctcp.Text) } // handleCTCPPong replies with a pong. @@ -256,7 +256,7 @@ func handleCTCPPong(client *Client, ctcp CTCPEvent) { if ctcp.Reply { return } - client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_PONG, "") + client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_PONG, "") } // handleCTCPVersion replies with the name of the client, Go version, as well @@ -264,12 +264,12 @@ func handleCTCPPong(client *Client, ctcp CTCPEvent) { // arm, etc). func handleCTCPVersion(client *Client, ctcp CTCPEvent) { if client.Config.Version != "" { - client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_VERSION, client.Config.Version) + client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_VERSION, client.Config.Version) return } client.Cmd.SendCTCPReplyf( - ctcp.Source.Name, CTCP_VERSION, + ctcp.Source.ID(), CTCP_VERSION, "girc (github.com/lrstanley/girc) using %s (%s, %s)", runtime.Version(), runtime.GOOS, runtime.GOARCH, ) @@ -277,13 +277,13 @@ func handleCTCPVersion(client *Client, ctcp CTCPEvent) { // handleCTCPSource replies with the public git location of this library. func handleCTCPSource(client *Client, ctcp CTCPEvent) { - client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_SOURCE, "https://github.com/lrstanley/girc") + client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_SOURCE, "https://github.com/lrstanley/girc") } // handleCTCPTime replies with a RFC 1123 (Z) formatted version of Go's // local time. func handleCTCPTime(client *Client, ctcp CTCPEvent) { - client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_TIME, ":"+time.Now().Format(time.RFC1123Z)) + client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_TIME, ":"+time.Now().Format(time.RFC1123Z)) } // handleCTCPFinger replies with the realname and idle time of the user. This @@ -293,5 +293,5 @@ func handleCTCPFinger(client *Client, ctcp CTCPEvent) { active := client.conn.lastActive client.conn.mu.RUnlock() - client.Cmd.SendCTCPReply(ctcp.Source.Name, CTCP_FINGER, fmt.Sprintf("%s -- idle %s", client.Config.Name, time.Since(active))) + client.Cmd.SendCTCPReply(ctcp.Source.ID(), CTCP_FINGER, fmt.Sprintf("%s -- idle %s", client.Config.Name, time.Since(active))) } diff --git a/vendor/github.com/lrstanley/girc/event.go b/vendor/github.com/lrstanley/girc/event.go index 0b40b40b..69f82148 100644 --- a/vendor/github.com/lrstanley/girc/event.go +++ b/vendor/github.com/lrstanley/girc/event.go @@ -516,7 +516,8 @@ const ( // Source represents the sender of an IRC event, see RFC1459 section 2.3.1. // <servername> | <nick> [ '!' <user> ] [ '@' <host> ] type Source struct { - // Name is the nickname, server name, or service name. + // Name is the nickname, server name, or service name, in its original + // non-rfc1459 form. Name string `json:"name"` // Ident is commonly known as the "user". Ident string `json:"ident"` @@ -525,6 +526,12 @@ type Source struct { Host string `json:"host"` } +// ID is the nickname, server name, or service name, in it's converted +// and comparable) form. +func (s *Source) ID() string { + return ToRFC1459(s.Name) +} + // Equals compares two Sources for equality. func (s *Source) Equals(ss *Source) bool { if s == nil && ss == nil { @@ -533,7 +540,7 @@ func (s *Source) Equals(ss *Source) bool { if s != nil && ss == nil || s == nil && ss != nil { return false } - if s.Name != ss.Name || s.Ident != ss.Ident || s.Host != ss.Host { + if s.ID() != ss.ID() || s.Ident != ss.Ident || s.Host != ss.Host { return false } return true diff --git a/vendor/github.com/lrstanley/girc/state.go b/vendor/github.com/lrstanley/girc/state.go index 36dcc82b..0660a686 100644 --- a/vendor/github.com/lrstanley/girc/state.go +++ b/vendor/github.com/lrstanley/girc/state.go @@ -419,14 +419,16 @@ func (s *state) lookupUser(name string) *User { } // createUser creates the user in state, if not already done. -func (s *state) createUser(nick string) (ok bool) { - if _, ok := s.users[ToRFC1459(nick)]; ok { +func (s *state) createUser(src *Source) (ok bool) { + if _, ok := s.users[src.ID()]; ok { // User already exists. return false } - s.users[ToRFC1459(nick)] = &User{ - Nick: nick, + s.users[src.ID()] = &User{ + Nick: src.Name, + Host: src.Host, + Ident: src.Ident, FirstSeen: time.Now(), LastActive: time.Now(), Perms: &UserPerms{channels: make(map[string]Perms)}, |