mirror of
https://github.com/mumble-voip/grumble.git
synced 2025-12-19 21:59:59 -08:00
Merge c69930a7b8 into 3e7af1e0fe
This commit is contained in:
commit
a05dc7c8ff
5 changed files with 38 additions and 36 deletions
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
|
@ -262,7 +263,7 @@ func (c *Channel) Unfreeze(fc *freezer.Channel) {
|
||||||
if fgrp.Name == nil {
|
if fgrp.Name == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
g := acl.Group{}
|
g := acl.EmptyGroupWithName(fgrp.GetName())
|
||||||
if fgrp.Inherit != nil {
|
if fgrp.Inherit != nil {
|
||||||
g.Inherit = *fgrp.Inherit
|
g.Inherit = *fgrp.Inherit
|
||||||
}
|
}
|
||||||
|
|
@ -483,7 +484,7 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
|
||||||
// Update the server's user maps to point correctly
|
// Update the server's user maps to point correctly
|
||||||
// to the new user.
|
// to the new user.
|
||||||
s.Users[u.Id] = u
|
s.Users[u.Id] = u
|
||||||
s.UserNameMap[u.Name] = u
|
s.UserNameMap[strings.ToLower(u.Name)] = u
|
||||||
if len(u.CertHash) > 0 {
|
if len(u.CertHash) > 0 {
|
||||||
s.UserCertMap[u.CertHash] = u
|
s.UserCertMap[u.CertHash] = u
|
||||||
}
|
}
|
||||||
|
|
@ -553,7 +554,7 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
|
||||||
// Update the various user maps in the server to
|
// Update the various user maps in the server to
|
||||||
// be able to correctly look up the user.
|
// be able to correctly look up the user.
|
||||||
s.Users[user.Id] = user
|
s.Users[user.Id] = user
|
||||||
s.UserNameMap[user.Name] = user
|
s.UserNameMap[strings.ToLower(user.Name)] = user
|
||||||
if len(user.CertHash) > 0 {
|
if len(user.CertHash) > 0 {
|
||||||
s.UserCertMap[user.CertHash] = user
|
s.UserCertMap[user.CertHash] = user
|
||||||
}
|
}
|
||||||
|
|
@ -574,7 +575,7 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
|
||||||
if ok {
|
if ok {
|
||||||
// Clear the server maps. That should do it.
|
// Clear the server maps. That should do it.
|
||||||
delete(s.Users, userId)
|
delete(s.Users, userId)
|
||||||
delete(s.UserNameMap, user.Name)
|
delete(s.UserNameMap, strings.ToLower(user.Name))
|
||||||
if len(user.CertHash) > 0 {
|
if len(user.CertHash) > 0 {
|
||||||
delete(s.UserCertMap, user.CertHash)
|
delete(s.UserCertMap, user.CertHash)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
|
|
@ -1211,6 +1212,7 @@ func (server *Server) handleAclMessage(client *Client, msg *Message) {
|
||||||
if pbacl.UserId != nil {
|
if pbacl.UserId != nil {
|
||||||
chanacl.UserId = int(*pbacl.UserId)
|
chanacl.UserId = int(*pbacl.UserId)
|
||||||
} else {
|
} else {
|
||||||
|
chanacl.UserId = -1
|
||||||
chanacl.Group = *pbacl.Group
|
chanacl.Group = *pbacl.Group
|
||||||
}
|
}
|
||||||
chanacl.Deny = acl.Permission(*pbacl.Deny & acl.AllPermissions)
|
chanacl.Deny = acl.Permission(*pbacl.Deny & acl.AllPermissions)
|
||||||
|
|
@ -1223,13 +1225,14 @@ func (server *Server) handleAclMessage(client *Client, msg *Message) {
|
||||||
server.ClearCaches()
|
server.ClearCaches()
|
||||||
|
|
||||||
// Regular user?
|
// Regular user?
|
||||||
if !acl.HasPermission(&channel.ACL, client, acl.WritePermission) && client.IsRegistered() || client.HasCertificate() {
|
if !acl.HasPermission(&channel.ACL, client, acl.WritePermission) && (client.IsRegistered() || client.HasCertificate()) {
|
||||||
chanacl := acl.ACL{}
|
chanacl := acl.ACL{}
|
||||||
chanacl.ApplyHere = true
|
chanacl.ApplyHere = true
|
||||||
chanacl.ApplySubs = false
|
chanacl.ApplySubs = false
|
||||||
if client.IsRegistered() {
|
if client.IsRegistered() {
|
||||||
chanacl.UserId = client.UserId()
|
chanacl.UserId = client.UserId()
|
||||||
} else if client.HasCertificate() {
|
} else if client.HasCertificate() {
|
||||||
|
chanacl.UserId = -1
|
||||||
chanacl.Group = "$" + client.CertHash()
|
chanacl.Group = "$" + client.CertHash()
|
||||||
}
|
}
|
||||||
chanacl.Deny = acl.Permission(acl.NonePermission)
|
chanacl.Deny = acl.Permission(acl.NonePermission)
|
||||||
|
|
@ -1267,7 +1270,7 @@ func (server *Server) handleQueryUsers(client *Client, msg *Message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, name := range query.Names {
|
for _, name := range query.Names {
|
||||||
user, exists := server.UserNameMap[name]
|
user, exists := server.UserNameMap[strings.ToLower(name)]
|
||||||
if exists {
|
if exists {
|
||||||
reply.Ids = append(reply.Ids, user.Id)
|
reply.Ids = append(reply.Ids, user.Id)
|
||||||
reply.Names = append(reply.Names, name)
|
reply.Names = append(reply.Names, name)
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ func NewServer(id int64) (s *Server, err error) {
|
||||||
s.UserCertMap = make(map[string]*User)
|
s.UserCertMap = make(map[string]*User)
|
||||||
s.UserNameMap = make(map[string]*User)
|
s.UserNameMap = make(map[string]*User)
|
||||||
s.Users[0], err = NewUser(0, "SuperUser")
|
s.Users[0], err = NewUser(0, "SuperUser")
|
||||||
s.UserNameMap["SuperUser"] = s.Users[0]
|
s.UserNameMap["superuser"] = s.Users[0]
|
||||||
s.nextUserId = 1
|
s.nextUserId = 1
|
||||||
|
|
||||||
s.Channels = make(map[int]*Channel)
|
s.Channels = make(map[int]*Channel)
|
||||||
|
|
@ -508,7 +508,7 @@ func (server *Server) handleAuthenticate(client *Client, msg *Message) {
|
||||||
} else {
|
} else {
|
||||||
if server.CheckSuperUserPassword(*auth.Password) {
|
if server.CheckSuperUserPassword(*auth.Password) {
|
||||||
ok := false
|
ok := false
|
||||||
client.user, ok = server.UserNameMap[client.Username]
|
client.user, ok = server.UserNameMap[strings.ToLower(client.Username)]
|
||||||
if !ok {
|
if !ok {
|
||||||
client.RejectAuth(mumbleproto.Reject_InvalidUsername, "")
|
client.RejectAuth(mumbleproto.Reject_InvalidUsername, "")
|
||||||
return
|
return
|
||||||
|
|
@ -520,7 +520,7 @@ func (server *Server) handleAuthenticate(client *Client, msg *Message) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// First look up registration by name.
|
// First look up registration by name.
|
||||||
user, exists := server.UserNameMap[client.Username]
|
user, exists := server.UserNameMap[strings.ToLower(client.Username)]
|
||||||
if exists {
|
if exists {
|
||||||
if client.HasCertificate() && user.CertHash == client.CertHash() {
|
if client.HasCertificate() && user.CertHash == client.CertHash() {
|
||||||
client.user = user
|
client.user = user
|
||||||
|
|
@ -689,12 +689,10 @@ func (server *Server) finishAuthenticate(client *Client) {
|
||||||
if client.IsSuperUser() {
|
if client.IsSuperUser() {
|
||||||
sync.Permissions = proto.Uint64(uint64(acl.AllPermissions))
|
sync.Permissions = proto.Uint64(uint64(acl.AllPermissions))
|
||||||
} else {
|
} else {
|
||||||
// fixme(mkrautz): previously we calculated the user's
|
// todo: acl caching?
|
||||||
// permissions and sent them to the client in here. This
|
// It might seem like we should send the permissions relative to the channel joined, but
|
||||||
// code relied on our ACL cache, but that has been temporarily
|
// Murmur sends the root channel permissions, so we do the same
|
||||||
// thrown out because of our ACL handling code moving to its
|
sync.Permissions = proto.Uint64(uint64(acl.EffectivePermission(&server.RootChannel().ACL, client)))
|
||||||
// own package.
|
|
||||||
sync.Permissions = nil
|
|
||||||
}
|
}
|
||||||
if err := client.sendMessage(sync); err != nil {
|
if err := client.sendMessage(sync); err != nil {
|
||||||
client.Panicf("%v", err)
|
client.Panicf("%v", err)
|
||||||
|
|
@ -899,10 +897,8 @@ func (server *Server) sendClientPermissions(client *Client, channel *Channel) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// fixme(mkrautz): re-add when we have ACL caching
|
// todo: acl caching?
|
||||||
return
|
perm := acl.EffectivePermission(&channel.ACL, client)
|
||||||
|
|
||||||
perm := acl.Permission(acl.NonePermission)
|
|
||||||
client.sendMessage(&mumbleproto.PermissionQuery{
|
client.sendMessage(&mumbleproto.PermissionQuery{
|
||||||
ChannelId: proto.Uint32(uint32(channel.Id)),
|
ChannelId: proto.Uint32(uint32(channel.Id)),
|
||||||
Permissions: proto.Uint32(uint32(perm)),
|
Permissions: proto.Uint32(uint32(perm)),
|
||||||
|
|
@ -1142,7 +1138,7 @@ func (s *Server) RegisterClient(client *Client) (uid uint32, err error) {
|
||||||
uid = s.nextUserId
|
uid = s.nextUserId
|
||||||
s.Users[uid] = user
|
s.Users[uid] = user
|
||||||
s.UserCertMap[client.CertHash()] = user
|
s.UserCertMap[client.CertHash()] = user
|
||||||
s.UserNameMap[client.Username] = user
|
s.UserNameMap[strings.ToLower(client.Username)] = user
|
||||||
|
|
||||||
return uid, nil
|
return uid, nil
|
||||||
}
|
}
|
||||||
|
|
@ -1157,7 +1153,7 @@ func (s *Server) RemoveRegistration(uid uint32) (err error) {
|
||||||
// Remove from user maps
|
// Remove from user maps
|
||||||
delete(s.Users, uid)
|
delete(s.Users, uid)
|
||||||
delete(s.UserCertMap, user.CertHash)
|
delete(s.UserCertMap, user.CertHash)
|
||||||
delete(s.UserNameMap, user.Name)
|
delete(s.UserNameMap, strings.ToLower(user.Name))
|
||||||
|
|
||||||
// Remove from groups and ACLs.
|
// Remove from groups and ACLs.
|
||||||
s.removeRegisteredUserFromChannel(uid, s.RootChannel())
|
s.removeRegisteredUserFromChannel(uid, s.RootChannel())
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ type ACL struct {
|
||||||
// The ApplyHere flag determines whether the ACL
|
// The ApplyHere flag determines whether the ACL
|
||||||
// should apply to the current channel.
|
// should apply to the current channel.
|
||||||
ApplyHere bool
|
ApplyHere bool
|
||||||
// The ApplySubs flag determines whethr the ACL
|
// The ApplySubs flag determines whether the ACL
|
||||||
// should apply to subchannels.
|
// should apply to subchannels.
|
||||||
ApplySubs bool
|
ApplySubs bool
|
||||||
|
|
||||||
|
|
@ -87,17 +87,21 @@ func (acl *ACL) IsChannelACL() bool {
|
||||||
// HasPermission checks whether the given user has permission perm in the given context.
|
// HasPermission checks whether the given user has permission perm in the given context.
|
||||||
// The permission perm must be a single permission and not a combination of permissions.
|
// The permission perm must be a single permission and not a combination of permissions.
|
||||||
func HasPermission(ctx *Context, user User, perm Permission) bool {
|
func HasPermission(ctx *Context, user User, perm Permission) bool {
|
||||||
|
// This test mirrors the Murmur behaviour. Unfortunately, this means that a combination of permissions
|
||||||
|
// results in an inclusive OR check i.e. if any one of the bits are set return true.
|
||||||
|
return (EffectivePermission(ctx, user) & perm) != NonePermission
|
||||||
|
}
|
||||||
|
|
||||||
|
// EffectivePermission returns the effective permission bits for a user in the given context.
|
||||||
|
func EffectivePermission(ctx *Context, user User) Permission {
|
||||||
// We can't check permissions on a nil ctx.
|
// We can't check permissions on a nil ctx.
|
||||||
if ctx == nil {
|
if ctx == nil {
|
||||||
panic("acl: HasPermission got nil context")
|
panic("acl: EffectivePermission got nil context")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuperUser can't speak or whisper, but everything else is OK
|
// SuperUser can't speak or whisper, but everything else is OK
|
||||||
if user.UserId() == 0 {
|
if user.UserId() == 0 {
|
||||||
if perm == SpeakPermission || perm == WhisperPermission {
|
return Permission(AllPermissions &^ (SpeakPermission | WhisperPermission))
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default permissions
|
// Default permissions
|
||||||
|
|
@ -116,13 +120,13 @@ func HasPermission(ctx *Context, user User, perm Permission) bool {
|
||||||
}
|
}
|
||||||
// Iterate through ACLs that are defined on ctx. Note: this does not include
|
// Iterate through ACLs that are defined on ctx. Note: this does not include
|
||||||
// ACLs that iter has inherited from a parent (unless there is also a group on
|
// ACLs that iter has inherited from a parent (unless there is also a group on
|
||||||
// iter with the same name, that changes the permissions a bit!)
|
// iter with the same name, that modifies the permissions a bit!)
|
||||||
for _, acl := range ctx.ACLs {
|
for _, acl := range ctx.ACLs {
|
||||||
// Determine whether the ACL applies to user.
|
// Determine whether the ACL applies to user.
|
||||||
// If it is a user ACL and the user id of the ACL
|
// If it is a user ACL and the user id of the ACL
|
||||||
// matches user's id, we're good to go.
|
// matches user's id, we're good to go.
|
||||||
//
|
//
|
||||||
// If it's a group ACL, we have to parse and interpret
|
// If it is a group ACL, we have to parse and interpret
|
||||||
// the group string in the current context to determine
|
// the group string in the current context to determine
|
||||||
// membership. For that we use GroupMemberCheck.
|
// membership. For that we use GroupMemberCheck.
|
||||||
matchUser := acl.IsUserACL() && acl.UserId == user.UserId()
|
matchUser := acl.IsUserACL() && acl.UserId == user.UserId()
|
||||||
|
|
@ -158,12 +162,10 @@ func HasPermission(ctx *Context, user User, perm Permission) bool {
|
||||||
|
|
||||||
// The +write permission implies all permissions except for +speak and +whisper.
|
// The +write permission implies all permissions except for +speak and +whisper.
|
||||||
// This means that if the user has WritePermission, we should return true for all
|
// This means that if the user has WritePermission, we should return true for all
|
||||||
// permissions exccept SpeakPermission and WhisperPermission.
|
// permissions except SpeakPermission and WhisperPermission.
|
||||||
if perm != SpeakPermission && perm != WhisperPermission {
|
if (granted & WritePermission) != NonePermission {
|
||||||
return (granted & (perm | WritePermission)) != NonePermission
|
return granted | (AllPermissions &^ (SpeakPermission | WhisperPermission))
|
||||||
} else {
|
|
||||||
return (granted & perm) != NonePermission
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return granted
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -344,7 +344,7 @@ func GroupMemberCheck(current *Context, acl *Context, name string, user User) (o
|
||||||
func (ctx *Context) GroupNames() []string {
|
func (ctx *Context) GroupNames() []string {
|
||||||
names := map[string]bool{}
|
names := map[string]bool{}
|
||||||
origCtx := ctx
|
origCtx := ctx
|
||||||
contexts := []*Context{}
|
contexts := buildChain(ctx)
|
||||||
|
|
||||||
// Walk through the whole context chain and all groups in it.
|
// Walk through the whole context chain and all groups in it.
|
||||||
for _, ctx := range contexts {
|
for _, ctx := range contexts {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue