Skip to content

Commit

Permalink
fix #1194
Browse files Browse the repository at this point in the history
  • Loading branch information
slingamn committed Oct 9, 2020
1 parent 3cd0e40 commit 78b2f61
Show file tree
Hide file tree
Showing 6 changed files with 34 additions and 15 deletions.
7 changes: 6 additions & 1 deletion conventional.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -597,11 +597,16 @@ opers:
class: "server-admin"

# custom whois line
whois-line: is a cool dude
whois-line: is a server admin

# custom hostname
vhost: "n"

# normally, operator status is visible to unprivileged users in WHO and WHOIS
# responses. this can be disabled with 'hidden'. ('hidden' also causes the
# 'vhost' line above to be ignored.)
hidden: false

# modes are the modes to auto-set upon opering-up
modes: +is acjknoqtuxv

Expand Down
7 changes: 6 additions & 1 deletion default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -625,11 +625,16 @@ opers:
class: "server-admin"

# custom whois line
whois-line: is a cool dude
whois-line: is a server admin

# custom hostname
vhost: "n"

# normally, operator status is visible to unprivileged users in WHO and WHOIS
# responses. this can be disabled with 'hidden'. ('hidden' also causes the
# 'vhost' line above to be ignored.)
hidden: false

# modes are the modes to auto-set upon opering-up
modes: +is acjknoqtuxv

Expand Down
2 changes: 1 addition & 1 deletion irc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1207,7 +1207,7 @@ func (client *Client) getVHostNoMutex() string {
// hostserv vhost OR operclass vhost OR nothing (i.e., normal rdns hostmask)
if client.vhost != "" {
return client.vhost
} else if client.oper != nil {
} else if client.oper != nil && !client.oper.Hidden {
return client.oper.Vhost
} else {
return ""
Expand Down
8 changes: 8 additions & 0 deletions irc/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ type OperConfig struct {
Fingerprint *string // legacy name for certfp, #1050
Certfp string
Auto bool
Hidden bool
Modes string
}

Expand Down Expand Up @@ -723,9 +724,15 @@ type Oper struct {
Pass []byte
Certfp string
Auto bool
Hidden bool
Modes []modes.ModeChange
}

// returns whether this is a publicly visible operator, for WHO/WHOIS purposes
func (oper *Oper) Visible(hasPrivs bool) bool {
return oper != nil && (hasPrivs || !oper.Hidden)
}

// Operators returns a map of operator configs from the given OperClass and config.
func (conf *Config) Operators(oc map[string]*OperClass) (map[string]*Oper, error) {
operators := make(map[string]*Oper)
Expand Down Expand Up @@ -756,6 +763,7 @@ func (conf *Config) Operators(oc map[string]*OperClass) (map[string]*Oper, error
}
}
oper.Auto = opConf.Auto
oper.Hidden = opConf.Hidden

if oper.Pass == nil && oper.Certfp == "" {
return nil, fmt.Errorf("Oper %s has neither a password nor a fingerprint", name)
Expand Down
17 changes: 9 additions & 8 deletions irc/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3018,7 +3018,7 @@ func (fields whoxFields) Has(field rune) bool {
// <channel> <user> <host> <server> <nick> <H|G>[*][~|&|@|%|+][B] :<hopcount> <real name>
// whox format:
// <type> <channel> <user> <ip> <host> <server> <nick> <H|G>[*][~|&|@|%|+][B] <hops> <idle> <account> <rank> :<real name>
func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *ResponseBuffer, isWhox bool, fields whoxFields, whoType string) {
func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *ResponseBuffer, hasPrivs, isWhox bool, fields whoxFields, whoType string) {
params := []string{client.Nick()}

details := target.Details()
Expand All @@ -3038,7 +3038,7 @@ func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *Response
}
if fields.Has('i') {
fIP := "255.255.255.255"
if client.HasMode(modes.Operator) || client == target {
if hasPrivs || client == target {
// you can only see a target's IP if they're you or you're an oper
fIP = target.IPString()
}
Expand All @@ -3061,7 +3061,7 @@ func (client *Client) rplWhoReply(channel *Channel, target *Client, rb *Response
flags.WriteRune('H') // Here
}

if target.HasMode(modes.Operator) {
if target.HasMode(modes.Operator) && target.Oper().Visible(hasPrivs) {
flags.WriteRune('*')
}

Expand Down Expand Up @@ -3169,7 +3169,7 @@ func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Respo
}
for _, member := range members {
if !member.HasMode(modes.Invisible) || isJoined || isOper {
client.rplWhoReply(channel, member, rb, isWhox, fields, whoType)
client.rplWhoReply(channel, member, rb, isOper, isWhox, fields, whoType)
}
}
}
Expand Down Expand Up @@ -3200,7 +3200,7 @@ func whoHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Respo

for mclient := range server.clients.FindAll(mask) {
if isOper || !mclient.HasMode(modes.Invisible) || isFriend(mclient) {
client.rplWhoReply(nil, mclient, rb, isWhox, fields, whoType)
client.rplWhoReply(nil, mclient, rb, isOper, isWhox, fields, whoType)
}
}
}
Expand Down Expand Up @@ -3238,23 +3238,24 @@ func whoisHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res
return true
}

if client.HasMode(modes.Operator) {
hasPrivs := client.HasMode(modes.Operator) // TODO(#1176) figure out the right capab for this
if hasPrivs {
for _, mask := range strings.Split(masksString, ",") {
matches := server.clients.FindAll(mask)
if len(matches) == 0 && !handleService(mask) {
rb.Add(nil, client.server.name, ERR_NOSUCHNICK, client.Nick(), utils.SafeErrorParam(mask), client.t("No such nick"))
continue
}
for mclient := range matches {
client.getWhoisOf(mclient, rb)
client.getWhoisOf(mclient, hasPrivs, rb)
}
}
} else {
// only get the first request; also require a nick, not a mask
nick := strings.Split(masksString, ",")[0]
mclient := server.clients.Get(nick)
if mclient != nil {
client.getWhoisOf(mclient, rb)
client.getWhoisOf(mclient, hasPrivs, rb)
} else if !handleService(nick) {
rb.Add(nil, client.server.name, ERR_NOSUCHNICK, client.Nick(), utils.SafeErrorParam(masksString), client.t("No such nick"))
}
Expand Down
8 changes: 4 additions & 4 deletions irc/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ func (client *Client) WhoisChannelsNames(target *Client, multiPrefix bool) []str
return chstrs
}

func (client *Client) getWhoisOf(target *Client, rb *ResponseBuffer) {
func (client *Client) getWhoisOf(target *Client, hasPrivs bool, rb *ResponseBuffer) {
cnick := client.Nick()
targetInfo := target.Details()
rb.Add(nil, client.server.name, RPL_WHOISUSER, cnick, targetInfo.nick, targetInfo.username, targetInfo.hostname, "*", targetInfo.realname)
Expand All @@ -440,10 +440,10 @@ func (client *Client) getWhoisOf(target *Client, rb *ResponseBuffer) {
rb.Add(nil, client.server.name, RPL_WHOISCHANNELS, cnick, tnick, strings.Join(whoischannels, " "))
}
tOper := target.Oper()
if tOper != nil {
if tOper.Visible(hasPrivs) {
rb.Add(nil, client.server.name, RPL_WHOISOPERATOR, cnick, tnick, tOper.WhoisLine)
}
if client == target || client.HasRoleCapabs("local_ban") {
if client == target || hasPrivs {
rb.Add(nil, client.server.name, RPL_WHOISACTUALLY, cnick, tnick, fmt.Sprintf("%s@%s", targetInfo.username, target.RawHostname()), target.IPString(), client.t("Actual user@host, Actual IP"))
}
if target.HasMode(modes.TLS) {
Expand All @@ -456,7 +456,7 @@ func (client *Client) getWhoisOf(target *Client, rb *ResponseBuffer) {
rb.Add(nil, client.server.name, RPL_WHOISBOT, cnick, tnick, ircfmt.Unescape(fmt.Sprintf(client.t("is a $bBot$b on %s"), client.server.Config().Network.Name)))
}

if client == target || client.HasMode(modes.Operator) {
if client == target || hasPrivs {
for _, session := range target.Sessions() {
if session.certfp != "" {
rb.Add(nil, client.server.name, RPL_WHOISCERTFP, cnick, tnick, fmt.Sprintf(client.t("has client certificate fingerprint %s"), session.certfp))
Expand Down

0 comments on commit 78b2f61

Please sign in to comment.