summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/lrstanley/girc
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/lrstanley/girc')
-rw-r--r--vendor/github.com/lrstanley/girc/README.md2
-rw-r--r--vendor/github.com/lrstanley/girc/builtin.go48
-rw-r--r--vendor/github.com/lrstanley/girc/cap_tags.go2
-rw-r--r--vendor/github.com/lrstanley/girc/client.go45
-rw-r--r--vendor/github.com/lrstanley/girc/commands.go6
-rw-r--r--vendor/github.com/lrstanley/girc/conn.go11
-rw-r--r--vendor/github.com/lrstanley/girc/constants.go31
-rw-r--r--vendor/github.com/lrstanley/girc/ctcp.go18
-rw-r--r--vendor/github.com/lrstanley/girc/event.go11
-rw-r--r--vendor/github.com/lrstanley/girc/state.go10
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)},