소스 검색

fix #1443

Improve auditability of sensitive operator actions
tags/v2.5.0-rc1
Shivaram Lingamneni 3 년 전
부모
커밋
64bc363cf1
4개의 변경된 파일40개의 추가작업 그리고 13개의 파일을 삭제
  1. 13
    5
      irc/chanserv.go
  2. 4
    0
      irc/config.go
  3. 15
    4
      irc/handlers.go
  4. 8
    4
      irc/nickserv.go

+ 13
- 5
irc/chanserv.go 파일 보기

502
 	chname = regInfo.Name
502
 	chname = regInfo.Name
503
 	account := client.Account()
503
 	account := client.Account()
504
 	isFounder := account != "" && account == regInfo.Founder
504
 	isFounder := account != "" && account == regInfo.Founder
505
-	hasPrivs := client.HasRoleCapabs("chanreg")
506
-	if !(isFounder || hasPrivs) {
507
-		service.Notice(rb, client.t("Insufficient privileges"))
508
-		return
505
+	var oper *Oper
506
+	if !isFounder {
507
+		oper = client.Oper()
508
+		if !oper.HasRoleCapab("chanreg") {
509
+			service.Notice(rb, client.t("Insufficient privileges"))
510
+			return
511
+		}
509
 	}
512
 	}
510
 	target := params[1]
513
 	target := params[1]
511
 	targetAccount, err := server.accounts.LoadAccount(params[1])
514
 	targetAccount, err := server.accounts.LoadAccount(params[1])
522
 			return
525
 			return
523
 		}
526
 		}
524
 	}
527
 	}
525
-	status, err := channel.Transfer(client, target, hasPrivs)
528
+	if !isFounder {
529
+		message := fmt.Sprintf("Operator %s ran CS TRANSFER on %s to account %s", oper.Name, chname, target)
530
+		server.snomasks.Send(sno.LocalOpers, message)
531
+		server.logger.Info("opers", message)
532
+	}
533
+	status, err := channel.Transfer(client, target, oper != nil)
526
 	if err == nil {
534
 	if err == nil {
527
 		switch status {
535
 		switch status {
528
 		case channelTransferComplete:
536
 		case channelTransferComplete:

+ 4
- 0
irc/config.go 파일 보기

733
 	Modes     []modes.ModeChange
733
 	Modes     []modes.ModeChange
734
 }
734
 }
735
 
735
 
736
+func (oper *Oper) HasRoleCapab(capab string) bool {
737
+	return oper != nil && oper.Class.Capabilities.Has(capab)
738
+}
739
+
736
 // Operators returns a map of operator configs from the given OperClass and config.
740
 // Operators returns a map of operator configs from the given OperClass and config.
737
 func (conf *Config) Operators(oc map[string]*OperClass) (map[string]*Oper, error) {
741
 func (conf *Config) Operators(oc map[string]*OperClass) (map[string]*Oper, error) {
738
 	operators := make(map[string]*Oper)
742
 	operators := make(map[string]*Oper)

+ 15
- 4
irc/handlers.go 파일 보기

826
 func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
826
 func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
827
 	// check oper permissions
827
 	// check oper permissions
828
 	oper := client.Oper()
828
 	oper := client.Oper()
829
-	if oper == nil || !oper.Class.Capabilities.Has("ban") {
829
+	if !oper.HasRoleCapab("ban") {
830
 		rb.Add(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
830
 		rb.Add(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
831
 		return false
831
 		return false
832
 	}
832
 	}
1273
 		}
1273
 		}
1274
 	}
1274
 	}
1275
 
1275
 
1276
+	message := fmt.Sprintf("Operator %s ran SAJOIN %s", client.Oper().Name, strings.Join(msg.Params, " "))
1277
+	server.snomasks.Send(sno.LocalOpers, message)
1278
+	server.logger.Info("opers", message)
1279
+
1276
 	channels := strings.Split(channelString, ",")
1280
 	channels := strings.Split(channelString, ",")
1277
 	for _, chname := range channels {
1281
 	for _, chname := range channels {
1278
 		err, _ := server.channels.Join(target, chname, "", true, rb)
1282
 		err, _ := server.channels.Join(target, chname, "", true, rb)
1364
 	details := client.Details()
1368
 	details := client.Details()
1365
 	// check oper permissions
1369
 	// check oper permissions
1366
 	oper := client.Oper()
1370
 	oper := client.Oper()
1367
-	if oper == nil || !oper.Class.Capabilities.Has("ban") {
1371
+	if !oper.HasRoleCapab("ban") {
1368
 		rb.Add(nil, server.name, ERR_NOPRIVS, details.nick, msg.Command, client.t("Insufficient oper privs"))
1372
 		rb.Add(nil, server.name, ERR_NOPRIVS, details.nick, msg.Command, client.t("Insufficient oper privs"))
1369
 		return false
1373
 		return false
1370
 	}
1374
 	}
1737
 		return false
1741
 		return false
1738
 	}
1742
 	}
1739
 
1743
 
1744
+	if msg.Command == "SAMODE" {
1745
+		message := fmt.Sprintf("Operator %s ran SAMODE %s", client.Oper().Name, strings.Join(msg.Params, " "))
1746
+		server.snomasks.Send(sno.LocalOpers, message)
1747
+		server.logger.Info("opers", message)
1748
+	}
1749
+
1740
 	// applied mode changes
1750
 	// applied mode changes
1741
 	applied := make(modes.ModeChanges, 0)
1751
 	applied := make(modes.ModeChanges, 0)
1742
 
1752
 
2307
 		copy(modeChanges[1:], oper.Modes)
2317
 		copy(modeChanges[1:], oper.Modes)
2308
 		applied := ApplyUserModeChanges(client, modeChanges, true, oper)
2318
 		applied := ApplyUserModeChanges(client, modeChanges, true, oper)
2309
 
2319
 
2320
+		client.server.logger.Info("opers", details.nick, "opered up as", oper.Name)
2310
 		client.server.snomasks.Send(sno.LocalOpers, fmt.Sprintf(ircfmt.Unescape("Client opered up $c[grey][$r%s$c[grey], $r%s$c[grey]]"), newDetails.nickMask, oper.Name))
2321
 		client.server.snomasks.Send(sno.LocalOpers, fmt.Sprintf(ircfmt.Unescape("Client opered up $c[grey][$r%s$c[grey], $r%s$c[grey]]"), newDetails.nickMask, oper.Name))
2311
 
2322
 
2312
 		rb.Broadcast(nil, client.server.name, RPL_YOUREOPER, details.nick, client.t("You are now an IRC operator"))
2323
 		rb.Broadcast(nil, client.server.name, RPL_YOUREOPER, details.nick, client.t("You are now an IRC operator"))
2814
 func unDLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2825
 func unDLineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *ResponseBuffer) bool {
2815
 	// check oper permissions
2826
 	// check oper permissions
2816
 	oper := client.Oper()
2827
 	oper := client.Oper()
2817
-	if oper == nil || !oper.Class.Capabilities.Has("ban") {
2828
+	if !oper.HasRoleCapab("ban") {
2818
 		rb.Add(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
2829
 		rb.Add(nil, server.name, ERR_NOPRIVS, client.nick, msg.Command, client.t("Insufficient oper privs"))
2819
 		return false
2830
 		return false
2820
 	}
2831
 	}
2853
 	details := client.Details()
2864
 	details := client.Details()
2854
 	// check oper permissions
2865
 	// check oper permissions
2855
 	oper := client.Oper()
2866
 	oper := client.Oper()
2856
-	if oper == nil || !oper.Class.Capabilities.Has("ban") {
2867
+	if !oper.HasRoleCapab("ban") {
2857
 		rb.Add(nil, server.name, ERR_NOPRIVS, details.nick, msg.Command, client.t("Insufficient oper privs"))
2868
 		rb.Add(nil, server.name, ERR_NOPRIVS, details.nick, msg.Command, client.t("Insufficient oper privs"))
2858
 		return false
2869
 		return false
2859
 	}
2870
 	}

+ 8
- 4
irc/nickserv.go 파일 보기

995
 	var newPassword string
995
 	var newPassword string
996
 	var errorMessage string
996
 	var errorMessage string
997
 
997
 
998
-	hasPrivs := client.HasRoleCapabs("accreg")
998
+	var oper *Oper
999
 
999
 
1000
 	switch len(params) {
1000
 	switch len(params) {
1001
 	case 2:
1001
 	case 2:
1002
-		if !hasPrivs {
1002
+		oper = client.Oper()
1003
+		if !oper.HasRoleCapab("accreg") {
1003
 			errorMessage = `Insufficient privileges`
1004
 			errorMessage = `Insufficient privileges`
1004
 		} else {
1005
 		} else {
1005
 			target, newPassword = params[0], params[1]
1006
 			target, newPassword = params[0], params[1]
1006
 			if newPassword == "*" {
1007
 			if newPassword == "*" {
1007
 				newPassword = ""
1008
 				newPassword = ""
1008
 			}
1009
 			}
1010
+			message := fmt.Sprintf("Operator %s ran NS PASSWD for account %s", oper.Name, target)
1011
+			server.snomasks.Send(sno.LocalOpers, message)
1012
+			server.logger.Info("opers", message)
1009
 		}
1013
 		}
1010
 	case 3:
1014
 	case 3:
1011
 		target = client.Account()
1015
 		target = client.Account()
1041
 		return
1045
 		return
1042
 	}
1046
 	}
1043
 
1047
 
1044
-	err := server.accounts.setPassword(target, newPassword, hasPrivs)
1048
+	err := server.accounts.setPassword(target, newPassword, oper != nil)
1045
 	switch err {
1049
 	switch err {
1046
 	case nil:
1050
 	case nil:
1047
 		service.Notice(rb, client.t("Password changed"))
1051
 		service.Notice(rb, client.t("Password changed"))
1144
 		// User must have "kill" privileges to logout other user sessions.
1148
 		// User must have "kill" privileges to logout other user sessions.
1145
 		if target != client {
1149
 		if target != client {
1146
 			oper := client.Oper()
1150
 			oper := client.Oper()
1147
-			if oper == nil || !oper.Class.Capabilities.Has("kill") {
1151
+			if oper.HasRoleCapab("kill") {
1148
 				service.Notice(rb, client.t("Insufficient oper privs"))
1152
 				service.Notice(rb, client.t("Insufficient oper privs"))
1149
 				return
1153
 				return
1150
 			}
1154
 			}

Loading…
취소
저장