From 9e0c276783631234805af297b62709388fb9e4cd Mon Sep 17 00:00:00 2001 From: Justin Date: Sun, 9 Aug 2015 09:58:17 -0700 Subject: [PATCH] Fix to not reveal channel key to nonmembers MODE queries were revealing channel key to non-members, now they will just be allowed to see if a key is required to join, but not see the key --- channel.go | 81 ---------------------------------------------- commands.go | 8 +++-- modes.go | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 98 insertions(+), 84 deletions(-) diff --git a/channel.go b/channel.go index b4ca49f..c33f698 100644 --- a/channel.go +++ b/channel.go @@ -83,21 +83,6 @@ func (c *Channel) Join(client *Client, key string) { } -// SetKey sets the channel key -func (c *Channel) SetKey(key string) { - c.AddModeWithValue(ChannelModeKey, key) -} - -// GetKey gets the key for the channel -func (c *Channel) GetKey() string { - val := c.GetMode(ChannelModeKey) - if val == nil { - return "" - } - return val.(string) - -} - // Names responds to to IRC NAMES command for the channel func (c *Channel) Names(client *Client) { @@ -395,72 +380,6 @@ func (c *Channel) TopicCommand(client *Client, topic string) { } -// AddBanMask sets the channel ban mask -func (c *Channel) AddBanMask(mask string) { - masks := c.GetBanMasks() - masks[mask] = nil - c.AddModeWithValue(ChannelModeBan, masks) -} - -// GetBanMasks gets the ban masks for the channel -func (c *Channel) GetBanMasks() map[string]interface{} { - val := c.GetMode(ChannelModeBan) - if val == nil { - return make(map[string]interface{}, 0) - } - return val.(map[string]interface{}) - -} - -// AddExceptionMask sets the channel exception mask -func (c *Channel) AddExceptionMask(mask string) { - masks := c.GetExceptionMasks() - masks[mask] = nil - c.AddModeWithValue(ChannelModeExceptionMask, masks) -} - -// GetExceptionMasks gets the exception masks for the channel -func (c *Channel) GetExceptionMasks() map[string]interface{} { - val := c.GetMode(ChannelModeExceptionMask) - if val == nil { - return make(map[string]interface{}, 0) - } - return val.(map[string]interface{}) - -} - -// AddInvitationMask sets the channel invitation mask -func (c *Channel) AddInvitationMask(mask string) { - masks := c.GetInvitationMasks() - masks[mask] = nil - c.AddModeWithValue(ChannelModeInvitationMask, masks) -} - -// GetInvitationMasks gets the invitation masks for the channel -func (c *Channel) GetInvitationMasks() map[string]interface{} { - val := c.GetMode(ChannelModeInvitationMask) - if val == nil { - return make(map[string]interface{}, 0) - } - return val.(map[string]interface{}) - -} - -// SetLimit sets the channel member limit -func (c *Channel) SetLimit(limit int) { - c.AddModeWithValue(ChannelModeLimit, limit) -} - -// GetLimit gets the member limit for the channel -func (c *Channel) GetLimit() int { - val := c.GetMode(ChannelModeLimit) - if val == nil { - return 0 - } - return val.(int) - -} - // ListMessage creates and returns the message that should be sent for an IRC LIST query func (c *Channel) ListMessage(client *Client) (m *irc.Message) { diff --git a/commands.go b/commands.go index f0c50d3..fb4a0e6 100644 --- a/commands.go +++ b/commands.go @@ -322,7 +322,7 @@ func WhoHandler(message *irc.Message, client *Client) { for clientName := range ch.members { cl, found := client.Server.GetClientByNick(clientName) - if found { + if found && !client.HasMode(UserModeInvisible) { msg := whoLine(cl, ch, client.Nickname) m := irc.Message{Prefix: client.Server.Prefix, Command: irc.RPL_WHOREPLY, Params: strings.Fields(msg)} client.Encode(&m) @@ -523,7 +523,11 @@ func ChannelModeHandler(message *irc.Message, client *Client) { if len(message.Params) == 1 { // just channel name is provided // return current settings for this channel - m := irc.Message{Prefix: client.Server.Prefix, Command: irc.RPL_CHANNELMODEIS, Params: []string{client.Nickname, channel.Name, channel.ChannelModeSet.String()}} + modes := channel.ChannelModeSet.Copy() + if !channel.HasMember(client) { // only current members should see the channel key + modes.SetKey("") + } + m := irc.Message{Prefix: client.Server.Prefix, Command: irc.RPL_CHANNELMODEIS, Params: []string{client.Nickname, channel.Name, modes.String()}} client.Encode(&m) return } diff --git a/modes.go b/modes.go index 395978f..2fefbca 100644 --- a/modes.go +++ b/modes.go @@ -126,6 +126,16 @@ func NewChannelModeSet() *ChannelModeSet { return &c } +// Copy creates and returns a deep copy of a ChannelModeSet +func (c *ChannelModeSet) Copy() *ChannelModeSet { + tmp := NewChannelModeSet() + for k, v := range c.modes { + tmp.modes[k] = v + } + return tmp + +} + // AddMode adds a ChannelMode as active func (c *ChannelModeSet) AddMode(mode ChannelMode) { c.mutex.Lock() @@ -135,7 +145,7 @@ func (c *ChannelModeSet) AddMode(mode ChannelMode) { } // AddModeWithValue adds a ChannelMode as active with a value -func (c *Channel) AddModeWithValue(mode ChannelMode, value interface{}) { +func (c *ChannelModeSet) AddModeWithValue(mode ChannelMode, value interface{}) { c.mutex.Lock() defer c.mutex.Unlock() c.modes[mode] = value @@ -189,3 +199,84 @@ func (c *ChannelModeSet) String() string { return s } + +// AddBanMask sets the channel ban mask +func (c *ChannelModeSet) AddBanMask(mask string) { + masks := c.GetBanMasks() + masks[mask] = nil + c.AddModeWithValue(ChannelModeBan, masks) +} + +// GetBanMasks gets the ban masks for the channel +func (c *ChannelModeSet) GetBanMasks() map[string]interface{} { + val := c.GetMode(ChannelModeBan) + if val == nil { + return make(map[string]interface{}, 0) + } + return val.(map[string]interface{}) + +} + +// AddExceptionMask sets the channel exception mask +func (c *ChannelModeSet) AddExceptionMask(mask string) { + masks := c.GetExceptionMasks() + masks[mask] = nil + c.AddModeWithValue(ChannelModeExceptionMask, masks) +} + +// GetExceptionMasks gets the exception masks for the channel +func (c *ChannelModeSet) GetExceptionMasks() map[string]interface{} { + val := c.GetMode(ChannelModeExceptionMask) + if val == nil { + return make(map[string]interface{}, 0) + } + return val.(map[string]interface{}) + +} + +// AddInvitationMask sets the channel invitation mask +func (c *ChannelModeSet) AddInvitationMask(mask string) { + masks := c.GetInvitationMasks() + masks[mask] = nil + c.AddModeWithValue(ChannelModeInvitationMask, masks) +} + +// GetInvitationMasks gets the invitation masks for the channel +func (c *ChannelModeSet) GetInvitationMasks() map[string]interface{} { + val := c.GetMode(ChannelModeInvitationMask) + if val == nil { + return make(map[string]interface{}, 0) + } + return val.(map[string]interface{}) + +} + +// SetLimit sets the channel member limit +func (c *ChannelModeSet) SetLimit(limit int) { + c.AddModeWithValue(ChannelModeLimit, limit) +} + +// GetLimit gets the member limit for the channel +func (c *ChannelModeSet) GetLimit() int { + val := c.GetMode(ChannelModeLimit) + if val == nil { + return 0 + } + return val.(int) + +} + +// SetKey sets the channel key +func (c *ChannelModeSet) SetKey(key string) { + c.AddModeWithValue(ChannelModeKey, key) +} + +// GetKey gets the key if stored in the ChannelModeSet +func (c *ChannelModeSet) GetKey() string { + val := c.GetMode(ChannelModeKey) + if val == nil { + return "" + } + return val.(string) + +}