This commit is contained in:
Ola Bini 2020-04-11 16:20:28 -07:00 committed by GitHub
commit fe197edba5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 580 additions and 524 deletions

View file

@ -8,6 +8,8 @@ import (
"text/template" "text/template"
) )
// UsageArgs contains usage information that can be
// templated for the final usage display
type UsageArgs struct { type UsageArgs struct {
Version string Version string
BuildDate string BuildDate string
@ -67,6 +69,7 @@ func defaultLogPath() string {
return filepath.Join(defaultDataDir(), "grumble.log") return filepath.Join(defaultDataDir(), "grumble.log")
} }
// Usage will print usage information about the command
func Usage() { func Usage() {
t, err := template.New("usage").Parse(usageTmpl) t, err := template.New("usage").Parse(usageTmpl)
if err != nil { if err != nil {
@ -85,6 +88,7 @@ func Usage() {
} }
} }
// Args contains all the possible arguments to the Grumble command
var Args args var Args args
func init() { func init() {

View file

@ -10,9 +10,9 @@ import (
"mumble.info/grumble/pkg/acl" "mumble.info/grumble/pkg/acl"
) )
// A Mumble channel // Channel represents a Mumble channel
type Channel struct { type Channel struct {
Id int ID int
Name string Name string
Position int Position int
@ -31,9 +31,10 @@ type Channel struct {
DescriptionBlob string DescriptionBlob string
} }
// NewChannel creates a new Mumble channel
func NewChannel(id int, name string) (channel *Channel) { func NewChannel(id int, name string) (channel *Channel) {
channel = new(Channel) channel = new(Channel)
channel.Id = id channel.ID = id
channel.Name = name channel.Name = name
channel.clients = make(map[uint32]*Client) channel.clients = make(map[uint32]*Client)
channel.children = make(map[int]*Channel) channel.children = make(map[int]*Channel)
@ -46,14 +47,14 @@ func NewChannel(id int, name string) (channel *Channel) {
func (channel *Channel) AddChild(child *Channel) { func (channel *Channel) AddChild(child *Channel) {
child.parent = channel child.parent = channel
child.ACL.Parent = &channel.ACL child.ACL.Parent = &channel.ACL
channel.children[child.Id] = child channel.children[child.ID] = child
} }
// RemoveChild removes a child channel from a parent // RemoveChild removes a child channel from a parent
func (channel *Channel) RemoveChild(child *Channel) { func (channel *Channel) RemoveChild(child *Channel) {
child.parent = nil child.parent = nil
child.ACL.Parent = nil child.ACL.Parent = nil
delete(channel.children, child.Id) delete(channel.children, child.ID)
} }
// AddClient adds client // AddClient adds client
@ -92,8 +93,8 @@ func (channel *Channel) AllLinks() (seen map[int]*Channel) {
current := walk[len(walk)-1] current := walk[len(walk)-1]
walk = walk[0 : len(walk)-1] walk = walk[0 : len(walk)-1]
for _, linked := range current.Links { for _, linked := range current.Links {
if _, alreadySeen := seen[linked.Id]; !alreadySeen { if _, alreadySeen := seen[linked.ID]; !alreadySeen {
seen[linked.Id] = linked seen[linked.ID] = linked
walk = append(walk, linked) walk = append(walk, linked)
} }
} }
@ -111,8 +112,8 @@ func (channel *Channel) AllSubChannels() (seen map[int]*Channel) {
current := walk[len(walk)-1] current := walk[len(walk)-1]
walk = walk[0 : len(walk)-1] walk = walk[0 : len(walk)-1]
for _, child := range current.children { for _, child := range current.children {
if _, alreadySeen := seen[child.Id]; !alreadySeen { if _, alreadySeen := seen[child.ID]; !alreadySeen {
seen[child.Id] = child seen[child.ID] = child
walk = append(walk, child) walk = append(walk, child)
} }
} }

View file

@ -23,7 +23,7 @@ import (
"mumble.info/grumble/pkg/packetdata" "mumble.info/grumble/pkg/packetdata"
) )
// A client connection // Client contains all information about a client connection
type Client struct { type Client struct {
// Logging // Logging
*log.Logger *log.Logger
@ -49,12 +49,12 @@ type Client struct {
voiceTargets map[uint32]*VoiceTarget voiceTargets map[uint32]*VoiceTarget
// Ping stats // Ping stats
UdpPingAvg float32 UDPPingAvg float32
UdpPingVar float32 UDPPingVar float32
UdpPackets uint32 UDPPackets uint32
TcpPingAvg float32 TCPPingAvg float32
TcpPingVar float32 TCPPingVar float32
TcpPackets uint32 TCPPackets uint32
// If the client is a registered user on the server, // If the client is a registered user on the server,
// the user field will point to the registration record. // the user field will point to the registration record.
@ -112,32 +112,36 @@ func (client *Client) IsSuperUser() bool {
if client.user == nil { if client.user == nil {
return false return false
} }
return client.user.Id == 0 return client.user.ID == 0
} }
// ACLContext returns the access control list context for this client
func (client *Client) ACLContext() *acl.Context { func (client *Client) ACLContext() *acl.Context {
return &client.Channel.ACL return &client.Channel.ACL
} }
// CertHash returns the certificate hash for this client
func (client *Client) CertHash() string { func (client *Client) CertHash() string {
return client.certHash return client.certHash
} }
// Session returns the session ID for this client
func (client *Client) Session() uint32 { func (client *Client) Session() uint32 {
return client.session return client.session
} }
// Tokens return all tokens for this client
func (client *Client) Tokens() []string { func (client *Client) Tokens() []string {
return client.tokens return client.tokens
} }
// UserId gets the User ID of this client. // UserID gets the User ID of this client.
// Returns -1 if the client is not a registered user. // Returns -1 if the client is not a registered user.
func (client *Client) UserId() int { func (client *Client) UserID() int {
if client.user == nil { if client.user == nil {
return -1 return -1
} }
return int(client.user.Id) return int(client.user.ID)
} }
// ShownName gets the client's shown name. // ShownName gets the client's shown name.
@ -159,13 +163,13 @@ func (client *Client) IsVerified() bool {
return len(state.VerifiedChains) > 0 return len(state.VerifiedChains) > 0
} }
// Log a panic and disconnect the client. // Panic will log a panic and disconnect the client.
func (client *Client) Panic(v ...interface{}) { func (client *Client) Panic(v ...interface{}) {
client.Print(v...) client.Print(v...)
client.Disconnect() client.Disconnect()
} }
// Log a formatted panic and disconnect the client. // Panicf will log a formatted panic and disconnect the client.
func (client *Client) Panicf(format string, v ...interface{}) { func (client *Client) Panicf(format string, v ...interface{}) {
client.Printf(format, v...) client.Printf(format, v...)
client.Disconnect() client.Disconnect()
@ -203,7 +207,7 @@ func (client *Client) Disconnect() {
client.disconnect(false) client.disconnect(false)
} }
// Disconnect a client (kick/ban) // ForceDisconnect will disconnect a client (kick/ban)
func (client *Client) ForceDisconnect() { func (client *Client) ForceDisconnect() {
client.disconnect(true) client.disconnect(true)
} }
@ -215,7 +219,7 @@ func (client *Client) ClearCaches() {
} }
} }
// Reject an authentication attempt // RejectAuth will reject an authentication attempt
func (client *Client) RejectAuth(rejectType mumbleproto.Reject_RejectType, reason string) { func (client *Client) RejectAuth(rejectType mumbleproto.Reject_RejectType, reason string) {
var reasonString *string = nil var reasonString *string = nil
if len(reason) > 0 { if len(reason) > 0 {
@ -265,36 +269,36 @@ func (client *Client) readProtoMessage() (msg *Message, err error) {
} }
// Send permission denied by type // Send permission denied by type
func (c *Client) sendPermissionDeniedType(denyType mumbleproto.PermissionDenied_DenyType) { func (client *Client) sendPermissionDeniedType(denyType mumbleproto.PermissionDenied_DenyType) {
c.sendPermissionDeniedTypeUser(denyType, nil) client.sendPermissionDeniedTypeUser(denyType, nil)
} }
// Send permission denied by type (and user) // Send permission denied by type (and user)
func (c *Client) sendPermissionDeniedTypeUser(denyType mumbleproto.PermissionDenied_DenyType, user *Client) { func (client *Client) sendPermissionDeniedTypeUser(denyType mumbleproto.PermissionDenied_DenyType, user *Client) {
pd := &mumbleproto.PermissionDenied{ pd := &mumbleproto.PermissionDenied{
Type: denyType.Enum(), Type: denyType.Enum(),
} }
if user != nil { if user != nil {
pd.Session = proto.Uint32(uint32(user.Session())) pd.Session = proto.Uint32(uint32(user.Session()))
} }
err := c.sendMessage(pd) err := client.sendMessage(pd)
if err != nil { if err != nil {
c.Panicf("%v", err.Error()) client.Panicf("%v", err.Error())
return return
} }
} }
// Send permission denied by who, what, where // Send permission denied by who, what, where
func (c *Client) sendPermissionDenied(who *Client, where *Channel, what acl.Permission) { func (client *Client) sendPermissionDenied(who *Client, where *Channel, what acl.Permission) {
pd := &mumbleproto.PermissionDenied{ pd := &mumbleproto.PermissionDenied{
Permission: proto.Uint32(uint32(what)), Permission: proto.Uint32(uint32(what)),
ChannelId: proto.Uint32(uint32(where.Id)), ChannelId: proto.Uint32(uint32(where.ID)),
Session: proto.Uint32(who.Session()), Session: proto.Uint32(who.Session()),
Type: mumbleproto.PermissionDenied_Permission.Enum(), Type: mumbleproto.PermissionDenied_Permission.Enum(),
} }
err := c.sendMessage(pd) err := client.sendMessage(pd)
if err != nil { if err != nil {
c.Panicf("%v", err.Error()) client.Panicf("%v", err.Error())
return return
} }
} }
@ -384,7 +388,7 @@ func (client *Client) udpRecvLoop() {
} }
} }
// Send buf as a UDP message. If the client does not have // SendUDP will send buf as a UDP message. If the client does not have
// an established UDP connection, the datagram will be tunelled // an established UDP connection, the datagram will be tunelled
// through the client's control channel (TCP). // through the client's control channel (TCP).
func (client *Client) SendUDP(buf []byte) error { func (client *Client) SendUDP(buf []byte) error {
@ -392,10 +396,9 @@ func (client *Client) SendUDP(buf []byte) error {
crypted := make([]byte, len(buf)+client.crypt.Overhead()) crypted := make([]byte, len(buf)+client.crypt.Overhead())
client.crypt.Encrypt(crypted, buf) client.crypt.Encrypt(crypted, buf)
return client.server.SendUDP(crypted, client.udpaddr) return client.server.SendUDP(crypted, client.udpaddr)
} else {
return client.sendMessage(buf)
} }
panic("unreachable")
return client.sendMessage(buf)
} }
// Send a Message to the client. The Message in msg to the client's // Send a Message to the client. The Message in msg to the client's
@ -590,11 +593,11 @@ func (client *Client) sendChannelList() {
func (client *Client) sendChannelTree(channel *Channel) { func (client *Client) sendChannelTree(channel *Channel) {
chanstate := &mumbleproto.ChannelState{ chanstate := &mumbleproto.ChannelState{
ChannelId: proto.Uint32(uint32(channel.Id)), ChannelId: proto.Uint32(uint32(channel.ID)),
Name: proto.String(channel.Name), Name: proto.String(channel.Name),
} }
if channel.parent != nil { if channel.parent != nil {
chanstate.Parent = proto.Uint32(uint32(channel.parent.Id)) chanstate.Parent = proto.Uint32(uint32(channel.parent.ID))
} }
if channel.HasDescription() { if channel.HasDescription() {
@ -616,7 +619,7 @@ func (client *Client) sendChannelTree(channel *Channel) {
chanstate.Position = proto.Int32(int32(channel.Position)) chanstate.Position = proto.Int32(int32(channel.Position))
links := []uint32{} links := []uint32{}
for cid, _ := range channel.Links { for cid := range channel.Links {
links = append(links, uint32(cid)) links = append(links, uint32(cid))
} }
chanstate.Links = links chanstate.Links = links

View file

@ -22,7 +22,7 @@ import (
"mumble.info/grumble/pkg/serverconf" "mumble.info/grumble/pkg/serverconf"
) )
// Freeze a server to disk and closes the log file. // FreezeToFile will freeze a server to disk and closes the log file.
// This must be called from within the Server's synchronous handler. // This must be called from within the Server's synchronous handler.
func (server *Server) FreezeToFile() error { func (server *Server) FreezeToFile() error {
// See freeeze_{windows,unix}.go for real implementations. // See freeeze_{windows,unix}.go for real implementations.
@ -52,7 +52,7 @@ func (server *Server) openFreezeLog() error {
server.freezelog = nil server.freezelog = nil
} }
logfn := filepath.Join(Args.DataDir, "servers", strconv.FormatInt(server.Id, 10), "log.fz") logfn := filepath.Join(Args.DataDir, "servers", strconv.FormatInt(server.ID, 10), "log.fz")
err := os.Remove(logfn) err := os.Remove(logfn)
if os.IsNotExist(err) { if os.IsNotExist(err) {
// fallthrough // fallthrough
@ -116,10 +116,10 @@ func (server *Server) Freeze() (fs *freezer.Server, err error) {
return fs, nil return fs, nil
} }
// Merge the contents of a freezer.BanList into the server's // UnfreezeBanList will merge the contents of a freezer.BanList into the server's
// ban list. // ban list.
func (s *Server) UnfreezeBanList(fblist *freezer.BanList) { func (server *Server) UnfreezeBanList(fblist *freezer.BanList) {
s.Bans = nil server.Bans = nil
for _, fb := range fblist.Bans { for _, fb := range fblist.Bans {
ban := ban.Ban{} ban := ban.Ban{}
@ -143,11 +143,11 @@ func (s *Server) UnfreezeBanList(fblist *freezer.BanList) {
ban.Duration = *fb.Duration ban.Duration = *fb.Duration
} }
s.Bans = append(s.Bans, ban) server.Bans = append(server.Bans, ban)
} }
} }
// Freeze a ban into a flattened protobuf-based struct // FreezeBan will freeze a ban into a flattened protobuf-based struct
// ready to be persisted to disk. // ready to be persisted to disk.
func FreezeBan(ban ban.Ban) (fb *freezer.Ban) { func FreezeBan(ban ban.Ban) (fb *freezer.Ban) {
fb = new(freezer.Ban) fb = new(freezer.Ban)
@ -167,13 +167,13 @@ func FreezeBan(ban ban.Ban) (fb *freezer.Ban) {
func (channel *Channel) Freeze() (fc *freezer.Channel, err error) { func (channel *Channel) Freeze() (fc *freezer.Channel, err error) {
fc = new(freezer.Channel) fc = new(freezer.Channel)
fc.Id = proto.Uint32(uint32(channel.Id)) fc.Id = proto.Uint32(uint32(channel.ID))
fc.Name = proto.String(channel.Name) fc.Name = proto.String(channel.Name)
if channel.parent != nil { if channel.parent != nil {
fc.ParentId = proto.Uint32(uint32(channel.parent.Id)) fc.ParentId = proto.Uint32(uint32(channel.parent.ID))
} }
fc.Position = proto.Int64(int64(channel.Position)) fc.Position = proto.Int64(int64(channel.Position))
fc.InheritAcl = proto.Bool(channel.ACL.InheritACL) fc.InheritACL = proto.Bool(channel.ACL.InheritACL)
// Freeze the channel's ACLs // Freeze the channel's ACLs
acls := []*freezer.ACL{} acls := []*freezer.ACL{}
@ -184,7 +184,7 @@ func (channel *Channel) Freeze() (fc *freezer.Channel, err error) {
} }
acls = append(acls, facl) acls = append(acls, facl)
} }
fc.Acl = acls fc.ACL = acls
// Freeze the channel's groups // Freeze the channel's groups
groups := []*freezer.Group{} groups := []*freezer.Group{}
@ -199,7 +199,7 @@ func (channel *Channel) Freeze() (fc *freezer.Channel, err error) {
// Add linked channels // Add linked channels
links := []uint32{} links := []uint32{}
for cid, _ := range channel.Links { for cid := range channel.Links {
links = append(links, uint32(cid)) links = append(links, uint32(cid))
} }
fc.Links = links fc.Links = links
@ -212,24 +212,24 @@ func (channel *Channel) Freeze() (fc *freezer.Channel, err error) {
// Unfreeze unfreezes the contents of a freezer.Channel // Unfreeze unfreezes the contents of a freezer.Channel
// into a channel. // into a channel.
func (c *Channel) Unfreeze(fc *freezer.Channel) { func (channel *Channel) Unfreeze(fc *freezer.Channel) {
if fc.Name != nil { if fc.Name != nil {
c.Name = *fc.Name channel.Name = *fc.Name
} }
if fc.Position != nil { if fc.Position != nil {
c.Position = int(*fc.Position) channel.Position = int(*fc.Position)
} }
if fc.InheritAcl != nil { if fc.InheritACL != nil {
c.ACL.InheritACL = *fc.InheritAcl channel.ACL.InheritACL = *fc.InheritACL
} }
if fc.DescriptionBlob != nil { if fc.DescriptionBlob != nil {
c.DescriptionBlob = *fc.DescriptionBlob channel.DescriptionBlob = *fc.DescriptionBlob
} }
// Update ACLs // Update ACLs
if fc.Acl != nil { if fc.ACL != nil {
c.ACL.ACLs = nil channel.ACL.ACLs = nil
for _, facl := range fc.Acl { for _, facl := range fc.ACL {
aclEntry := acl.ACL{} aclEntry := acl.ACL{}
if facl.ApplyHere != nil { if facl.ApplyHere != nil {
aclEntry.ApplyHere = *facl.ApplyHere aclEntry.ApplyHere = *facl.ApplyHere
@ -237,10 +237,10 @@ func (c *Channel) Unfreeze(fc *freezer.Channel) {
if facl.ApplySubs != nil { if facl.ApplySubs != nil {
aclEntry.ApplySubs = *facl.ApplySubs aclEntry.ApplySubs = *facl.ApplySubs
} }
if facl.UserId != nil { if facl.UserID != nil {
aclEntry.UserId = int(*facl.UserId) aclEntry.UserID = int(*facl.UserID)
} else { } else {
aclEntry.UserId = -1 aclEntry.UserID = -1
} }
if facl.Group != nil { if facl.Group != nil {
aclEntry.Group = *facl.Group aclEntry.Group = *facl.Group
@ -251,13 +251,13 @@ func (c *Channel) Unfreeze(fc *freezer.Channel) {
if facl.Allow != nil { if facl.Allow != nil {
aclEntry.Allow = acl.Permission(*facl.Allow) aclEntry.Allow = acl.Permission(*facl.Allow)
} }
c.ACL.ACLs = append(c.ACL.ACLs, aclEntry) channel.ACL.ACLs = append(channel.ACL.ACLs, aclEntry)
} }
} }
// Update groups // Update groups
if fc.Groups != nil { if fc.Groups != nil {
c.ACL.Groups = make(map[string]acl.Group) channel.ACL.Groups = make(map[string]acl.Group)
for _, fgrp := range fc.Groups { for _, fgrp := range fc.Groups {
if fgrp.Name == nil { if fgrp.Name == nil {
continue continue
@ -275,7 +275,7 @@ func (c *Channel) Unfreeze(fc *freezer.Channel) {
for _, uid := range fgrp.Remove { for _, uid := range fgrp.Remove {
g.Remove[int(uid)] = true g.Remove[int(uid)] = true
} }
c.ACL.Groups[g.Name] = g channel.ACL.Groups[g.Name] = g
} }
} }
@ -283,9 +283,9 @@ func (c *Channel) Unfreeze(fc *freezer.Channel) {
// We can't be sure that the channels the links point to exist // We can't be sure that the channels the links point to exist
// yet, so we delay hooking up the map 'correctly' to later. // yet, so we delay hooking up the map 'correctly' to later.
if fc.Links != nil { if fc.Links != nil {
c.Links = make(map[int]*Channel) channel.Links = make(map[int]*Channel)
for _, link := range fc.Links { for _, link := range fc.Links {
c.Links[int(link)] = c channel.Links[int(link)] = channel
} }
} }
} }
@ -295,60 +295,60 @@ func (c *Channel) Unfreeze(fc *freezer.Channel) {
func (user *User) Freeze() (fu *freezer.User, err error) { func (user *User) Freeze() (fu *freezer.User, err error) {
fu = new(freezer.User) fu = new(freezer.User)
fu.Id = proto.Uint32(user.Id) fu.Id = proto.Uint32(user.ID)
fu.Name = proto.String(user.Name) fu.Name = proto.String(user.Name)
fu.CertHash = proto.String(user.CertHash) fu.CertHash = proto.String(user.CertHash)
fu.Email = proto.String(user.Email) fu.Email = proto.String(user.Email)
fu.TextureBlob = proto.String(user.TextureBlob) fu.TextureBlob = proto.String(user.TextureBlob)
fu.CommentBlob = proto.String(user.CommentBlob) fu.CommentBlob = proto.String(user.CommentBlob)
fu.LastChannelId = proto.Uint32(uint32(user.LastChannelId)) fu.LastChannelID = proto.Uint32(uint32(user.LastChannelID))
fu.LastActive = proto.Uint64(user.LastActive) fu.LastActive = proto.Uint64(user.LastActive)
return return
} }
// Merge the contents of a frozen User into an existing user struct. // Unfreeze will merge the contents of a frozen User into an existing user struct.
func (u *User) Unfreeze(fu *freezer.User) { func (user *User) Unfreeze(fu *freezer.User) {
if fu.Name != nil { if fu.Name != nil {
u.Name = *fu.Name user.Name = *fu.Name
} }
if fu.CertHash != nil { if fu.CertHash != nil {
u.CertHash = *fu.CertHash user.CertHash = *fu.CertHash
} }
if fu.Email != nil { if fu.Email != nil {
u.Email = *fu.Email user.Email = *fu.Email
} }
if fu.TextureBlob != nil { if fu.TextureBlob != nil {
u.TextureBlob = *fu.TextureBlob user.TextureBlob = *fu.TextureBlob
} }
if fu.CommentBlob != nil { if fu.CommentBlob != nil {
u.CommentBlob = *fu.CommentBlob user.CommentBlob = *fu.CommentBlob
} }
if fu.LastChannelId != nil { if fu.LastChannelID != nil {
u.LastChannelId = int(*fu.LastChannelId) user.LastChannelID = int(*fu.LastChannelID)
} }
if fu.LastActive != nil { if fu.LastActive != nil {
u.LastActive = *fu.LastActive user.LastActive = *fu.LastActive
} }
} }
// Freeze a ChannelACL into it a flattened protobuf-based structure // FreezeACL will freeze a ChannelACL into it a flattened protobuf-based structure
// ready to be persisted to disk. // ready to be persisted to disk.
func FreezeACL(aclEntry acl.ACL) (*freezer.ACL, error) { func FreezeACL(aclEntry acl.ACL) (*freezer.ACL, error) {
frozenAcl := &freezer.ACL{} frozenACL := &freezer.ACL{}
if aclEntry.UserId != -1 { if aclEntry.UserID != -1 {
frozenAcl.UserId = proto.Uint32(uint32(aclEntry.UserId)) frozenACL.UserID = proto.Uint32(uint32(aclEntry.UserID))
} else { } else {
frozenAcl.Group = proto.String(aclEntry.Group) frozenACL.Group = proto.String(aclEntry.Group)
} }
frozenAcl.ApplyHere = proto.Bool(aclEntry.ApplyHere) frozenACL.ApplyHere = proto.Bool(aclEntry.ApplyHere)
frozenAcl.ApplySubs = proto.Bool(aclEntry.ApplySubs) frozenACL.ApplySubs = proto.Bool(aclEntry.ApplySubs)
frozenAcl.Allow = proto.Uint32(uint32(aclEntry.Allow)) frozenACL.Allow = proto.Uint32(uint32(aclEntry.Allow))
frozenAcl.Deny = proto.Uint32(uint32(aclEntry.Deny)) frozenACL.Deny = proto.Uint32(uint32(aclEntry.Deny))
return frozenAcl, nil return frozenACL, nil
} }
// Freeze a Group into a flattened protobuf-based structure // FreezeGroup will freeze a Group into a flattened protobuf-based structure
// ready to be persisted to disk. // ready to be persisted to disk.
func FreezeGroup(group acl.Group) (*freezer.Group, error) { func FreezeGroup(group acl.Group) (*freezer.Group, error) {
frozenGroup := &freezer.Group{} frozenGroup := &freezer.Group{}
@ -364,7 +364,7 @@ func FreezeGroup(group acl.Group) (*freezer.Group, error) {
return frozenGroup, nil return frozenGroup, nil
} }
// Create a new server from its on-disk representation. // NewServerFromFrozen will create a new server from its on-disk representation.
// //
// This will read a full serialized server (typically stored in // This will read a full serialized server (typically stored in
// a file called 'main.fz') from disk. It will also check for // a file called 'main.fz') from disk. It will also check for
@ -445,15 +445,15 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
// Update the server's nextChanId field if it needs to be, // Update the server's nextChanId field if it needs to be,
// to make sure the server doesn't re-use channel id's. // to make sure the server doesn't re-use channel id's.
c := NewChannel(int(*fc.Id), *fc.Name) c := NewChannel(int(*fc.Id), *fc.Name)
if c.Id >= s.nextChanId { if c.ID >= s.nextChanID {
s.nextChanId = c.Id + 1 s.nextChanID = c.ID + 1
} }
// Update the channel with the contents of the freezer.Channel. // Update the channel with the contents of the freezer.Channel.
c.Unfreeze(fc) c.Unfreeze(fc)
// Add the channel's id to the server's channel-id-map. // Add the channel's id to the server's channel-id-map.
s.Channels[c.Id] = c s.Channels[c.ID] = c
// Mark the channel's parent // Mark the channel's parent
if fc.ParentId != nil { if fc.ParentId != nil {
@ -472,8 +472,8 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
if u.Id >= s.nextUserId { if u.ID >= s.nextUserID {
s.nextUserId = u.Id + 1 s.nextUserID = u.ID + 1
} }
// Merge the contents of the freezer.User into // Merge the contents of the freezer.User into
@ -482,7 +482,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[u.Name] = u
if len(u.CertHash) > 0 { if len(u.CertHash) > 0 {
s.UserCertMap[u.CertHash] = u s.UserCertMap[u.CertHash] = u
@ -520,14 +520,14 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
continue continue
} }
userId := *fu.Id userID := *fu.Id
// Determine whether the user already exists on the server or not. // Determine whether the user already exists on the server or not.
// If the user already exists, this log entry simply updates the // If the user already exists, this log entry simply updates the
// data for that user. // data for that user.
// If the user doesn't exist, we create it with the data given in // If the user doesn't exist, we create it with the data given in
// this log entry. // this log entry.
user, ok := s.Users[userId] user, ok := s.Users[userID]
if !ok { if !ok {
// If no name is given in the log entry, skip this entry. // If no name is given in the log entry, skip this entry.
// Also, warn the admin. // Also, warn the admin.
@ -535,14 +535,14 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
log.Printf("Skipped User creation log entry: No name given.") log.Printf("Skipped User creation log entry: No name given.")
continue continue
} }
// Create the new user and increment the UserId // Create the new user and increment the UserID
// counter for the server if needed. // counter for the server if needed.
user, err = NewUser(userId, *fu.Name) user, err = NewUser(userID, *fu.Name)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if user.Id >= s.nextUserId { if user.ID >= s.nextUserID {
s.nextUserId = user.Id + 1 s.nextUserID = user.ID + 1
} }
} }
@ -552,7 +552,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[user.Name] = user
if len(user.CertHash) > 0 { if len(user.CertHash) > 0 {
s.UserCertMap[user.CertHash] = user s.UserCertMap[user.CertHash] = user
@ -566,14 +566,14 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
continue continue
} }
userId := *fu.Id userID := *fu.Id
// Does this user even exist? // Does this user even exist?
// Warn if we encounter an illegal delete op. // Warn if we encounter an illegal delete op.
user, ok := s.Users[userId] user, ok := s.Users[userID]
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, user.Name)
if len(user.CertHash) > 0 { if len(user.CertHash) > 0 {
delete(s.UserCertMap, user.CertHash) delete(s.UserCertMap, user.CertHash)
@ -591,9 +591,9 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
continue continue
} }
channelId := int(*fc.Id) channelID := int(*fc.Id)
channel, alreadyExists := s.Channels[channelId] channel, alreadyExists := s.Channels[channelID]
if !alreadyExists { if !alreadyExists {
if fc.Name == nil { if fc.Name == nil {
log.Printf("Skipped Channel creation log entry: No name given.") log.Printf("Skipped Channel creation log entry: No name given.")
@ -601,9 +601,9 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
} }
// Add the channel and increment the server's // Add the channel and increment the server's
// nextChanId field to a consistent state. // nextChanId field to a consistent state.
channel = NewChannel(channelId, *fc.Name) channel = NewChannel(channelID, *fc.Name)
if channel.Id >= s.nextChanId { if channel.ID >= s.nextChanID {
s.nextChanId = channel.Id + 1 s.nextChanID = channel.ID + 1
} }
} }
@ -612,7 +612,7 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
channel.Unfreeze(fc) channel.Unfreeze(fc)
// Re-add it to the server's channel map (in case // Re-add it to the server's channel map (in case
// the channel was newly-created) // the channel was newly-created)
s.Channels[channelId] = channel s.Channels[channelID] = channel
// Mark the channel's parent // Mark the channel's parent
if !alreadyExists { if !alreadyExists {
@ -652,12 +652,12 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
} }
// Hook up children with their parents // Hook up children with their parents
for chanId, parentId := range parents { for chanID, parentID := range parents {
childChan, exists := s.Channels[int(chanId)] childChan, exists := s.Channels[int(chanID)]
if !exists { if !exists {
return nil, errors.New("Non-existant child channel") return nil, errors.New("Non-existant child channel")
} }
parentChan, exists := s.Channels[int(parentId)] parentChan, exists := s.Channels[int(parentID)]
if !exists { if !exists {
return nil, errors.New("Non-existant parent channel") return nil, errors.New("Non-existant parent channel")
} }
@ -669,8 +669,8 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
if len(channel.Links) > 0 { if len(channel.Links) > 0 {
links := channel.Links links := channel.Links
channel.Links = make(map[int]*Channel) channel.Links = make(map[int]*Channel)
for chanId, _ := range links { for chanID := range links {
targetChannel := s.Channels[chanId] targetChannel := s.Channels[chanID]
if targetChannel != nil { if targetChannel != nil {
s.LinkChannels(channel, targetChannel) s.LinkChannels(channel, targetChannel)
} }
@ -681,13 +681,13 @@ func NewServerFromFrozen(name string) (s *Server, err error) {
return s, nil return s, nil
} }
// Update the datastore with the user's current state. // UpdateFrozenUser will update the datastore with the user's current state.
func (server *Server) UpdateFrozenUser(client *Client, state *mumbleproto.UserState) { func (server *Server) UpdateFrozenUser(client *Client, state *mumbleproto.UserState) {
// Full sync If there's no userstate messgae provided, or if there is one, and // Full sync If there's no userstate messgae provided, or if there is one, and
// it includes a registration operation. // it includes a registration operation.
user := client.user user := client.user
nanos := time.Now().Unix() nanos := time.Now().Unix()
if state == nil || state.UserId != nil { if state == nil || state.UserID != nil {
fu, err := user.Freeze() fu, err := user.Freeze()
if err != nil { if err != nil {
server.Fatal(err) server.Fatal(err)
@ -699,9 +699,9 @@ func (server *Server) UpdateFrozenUser(client *Client, state *mumbleproto.UserSt
} }
} else { } else {
fu := &freezer.User{} fu := &freezer.User{}
fu.Id = proto.Uint32(user.Id) fu.Id = proto.Uint32(user.ID)
if state.ChannelId != nil { if state.ChannelId != nil {
fu.LastChannelId = proto.Uint32(uint32(client.Channel.Id)) fu.LastChannelID = proto.Uint32(uint32(client.Channel.ID))
} }
if state.TextureHash != nil { if state.TextureHash != nil {
fu.TextureBlob = proto.String(user.TextureBlob) fu.TextureBlob = proto.String(user.TextureBlob)
@ -715,17 +715,17 @@ func (server *Server) UpdateFrozenUser(client *Client, state *mumbleproto.UserSt
server.Fatal(err) server.Fatal(err)
} }
} }
server.numLogOps += 1 server.numLogOps++
} }
// Update a user's last active channel // UpdateFrozenUserLastChannel will update a user's last active channel
func (server *Server) UpdateFrozenUserLastChannel(client *Client) { func (server *Server) UpdateFrozenUserLastChannel(client *Client) {
if client.IsRegistered() { if client.IsRegistered() {
user := client.user user := client.user
fu := &freezer.User{} fu := &freezer.User{}
fu.Id = proto.Uint32(user.Id) fu.Id = proto.Uint32(user.ID)
fu.LastChannelId = proto.Uint32(uint32(client.Channel.Id)) fu.LastChannelID = proto.Uint32(uint32(client.Channel.ID))
fu.LastActive = proto.Uint64(uint64(time.Now().Unix())) fu.LastActive = proto.Uint64(uint64(time.Now().Unix()))
err := server.freezelog.Put(fu) err := server.freezelog.Put(fu)
@ -733,25 +733,25 @@ func (server *Server) UpdateFrozenUserLastChannel(client *Client) {
server.Fatal(err) server.Fatal(err)
} }
server.numLogOps += 1 server.numLogOps++
} }
} }
// Mark a user as deleted in the datstore. // DeleteFrozenUser will mark a user as deleted in the datstore.
func (server *Server) DeleteFrozenUser(user *User) { func (server *Server) DeleteFrozenUser(user *User) {
err := server.freezelog.Put(&freezer.UserRemove{Id: proto.Uint32(user.Id)}) err := server.freezelog.Put(&freezer.UserRemove{Id: proto.Uint32(user.ID)})
if err != nil { if err != nil {
server.Fatal(err) server.Fatal(err)
} }
server.numLogOps += 1 server.numLogOps++
} }
// Given a target channel and a ChannelState protocol message, create a freezer.Channel that // UpdateFrozenChannel will, given a target channel and a ChannelState protocol message, create a freezer.Channel that
// only includes the values changed by the given ChannelState message. When done, write that // only includes the values changed by the given ChannelState message. When done, write that
// frozen.Channel to the datastore. // frozen.Channel to the datastore.
func (server *Server) UpdateFrozenChannel(channel *Channel, state *mumbleproto.ChannelState) { func (server *Server) UpdateFrozenChannel(channel *Channel, state *mumbleproto.ChannelState) {
fc := &freezer.Channel{} fc := &freezer.Channel{}
fc.Id = proto.Uint32(uint32(channel.Id)) fc.Id = proto.Uint32(uint32(channel.ID))
if state.Name != nil { if state.Name != nil {
fc.Name = state.Name fc.Name = state.Name
} }
@ -760,7 +760,7 @@ func (server *Server) UpdateFrozenChannel(channel *Channel, state *mumbleproto.C
} }
if len(state.LinksAdd) > 0 || len(state.LinksRemove) > 0 { if len(state.LinksAdd) > 0 || len(state.LinksRemove) > 0 {
links := []uint32{} links := []uint32{}
for cid, _ := range channel.Links { for cid := range channel.Links {
links = append(links, uint32(cid)) links = append(links, uint32(cid))
} }
fc.Links = links fc.Links = links
@ -775,7 +775,7 @@ func (server *Server) UpdateFrozenChannel(channel *Channel, state *mumbleproto.C
if err != nil { if err != nil {
server.Fatal(err) server.Fatal(err)
} }
server.numLogOps += 1 server.numLogOps++
} }
// UpdateFrozenChannelACLs writes a channel's ACL and Group data to disk. Mumble doesn't support // UpdateFrozenChannelACLs writes a channel's ACL and Group data to disk. Mumble doesn't support
@ -784,8 +784,8 @@ func (server *Server) UpdateFrozenChannel(channel *Channel, state *mumbleproto.C
func (server *Server) UpdateFrozenChannelACLs(channel *Channel) { func (server *Server) UpdateFrozenChannelACLs(channel *Channel) {
fc := &freezer.Channel{} fc := &freezer.Channel{}
fc.Id = proto.Uint32(uint32(channel.Id)) fc.Id = proto.Uint32(uint32(channel.ID))
fc.InheritAcl = proto.Bool(channel.ACL.InheritACL) fc.InheritACL = proto.Bool(channel.ACL.InheritACL)
acls := []*freezer.ACL{} acls := []*freezer.ACL{}
for _, aclEntry := range channel.ACL.ACLs { for _, aclEntry := range channel.ACL.ACLs {
@ -795,7 +795,7 @@ func (server *Server) UpdateFrozenChannelACLs(channel *Channel) {
} }
acls = append(acls, facl) acls = append(acls, facl)
} }
fc.Acl = acls fc.ACL = acls
groups := []*freezer.Group{} groups := []*freezer.Group{}
for _, grp := range channel.ACL.Groups { for _, grp := range channel.ACL.Groups {
@ -811,16 +811,16 @@ func (server *Server) UpdateFrozenChannelACLs(channel *Channel) {
if err != nil { if err != nil {
server.Fatal(err) server.Fatal(err)
} }
server.numLogOps += 1 server.numLogOps++
} }
// Mark a channel as deleted in the datastore. // DeleteFrozenChannel will mark a channel as deleted in the datastore.
func (server *Server) DeleteFrozenChannel(channel *Channel) { func (server *Server) DeleteFrozenChannel(channel *Channel) {
err := server.freezelog.Put(&freezer.ChannelRemove{Id: proto.Uint32(uint32(channel.Id))}) err := server.freezelog.Put(&freezer.ChannelRemove{Id: proto.Uint32(uint32(channel.ID))})
if err != nil { if err != nil {
server.Fatal(err) server.Fatal(err)
} }
server.numLogOps += 1 server.numLogOps++
} }
// UpdateFrozenBans writes the server's banlist to the datastore. // UpdateFrozenBans writes the server's banlist to the datastore.
@ -833,7 +833,7 @@ func (server *Server) UpdateFrozenBans(bans []ban.Ban) {
if err != nil { if err != nil {
server.Fatal(err) server.Fatal(err)
} }
server.numLogOps += 1 server.numLogOps++
} }
// UpdateConfig writes an updated config value to the datastore. // UpdateConfig writes an updated config value to the datastore.
@ -846,7 +846,7 @@ func (server *Server) UpdateConfig(key, value string) {
if err != nil { if err != nil {
server.Fatal(err) server.Fatal(err)
} }
server.numLogOps += 1 server.numLogOps++
} }
// ResetConfig writes to the freezelog that the config with key // ResetConfig writes to the freezelog that the config with key
@ -859,5 +859,5 @@ func (server *Server) ResetConfig(key string) {
if err != nil { if err != nil {
server.Fatal(err) server.Fatal(err)
} }
server.numLogOps += 1 server.numLogOps++
} }

View file

@ -30,7 +30,7 @@ func (server *Server) freezeToFile() (err error) {
if err != nil { if err != nil {
return err return err
} }
f, err := ioutil.TempFile(filepath.Join(Args.DataDir, "servers", strconv.FormatInt(server.Id, 10)), ".main.fz_") f, err := ioutil.TempFile(filepath.Join(Args.DataDir, "servers", strconv.FormatInt(server.ID, 10)), ".main.fz_")
if err != nil { if err != nil {
return err return err
} }
@ -50,7 +50,7 @@ func (server *Server) freezeToFile() (err error) {
if err != nil { if err != nil {
return err return err
} }
err = os.Rename(f.Name(), filepath.Join(Args.DataDir, "servers", strconv.FormatInt(server.Id, 10), "main.fz")) err = os.Rename(f.Name(), filepath.Join(Args.DataDir, "servers", strconv.FormatInt(server.ID, 10), "main.fz"))
if err != nil { if err != nil {
return err return err
} }

View file

@ -17,7 +17,7 @@ import (
"time" "time"
) )
// Generate a 4096-bit RSA keypair and a Grumble auto-generated X509 // GenerateSelfSignedCert will generate a 4096-bit RSA keypair and a Grumble auto-generated X509
// certificate. Output PEM-encoded DER representations of the resulting // certificate. Output PEM-encoded DER representations of the resulting
// certificate and private key to certpath and keypath. // certificate and private key to certpath and keypath.
func GenerateSelfSignedCert(certpath, keypath string) (err error) { func GenerateSelfSignedCert(certpath, keypath string) (err error) {

View file

@ -185,7 +185,7 @@ func main() {
if err != nil { if err != nil {
log.Fatalf("Unable to freeze server to disk: %v", err.Error()) log.Fatalf("Unable to freeze server to disk: %v", err.Error())
} }
servers[s.Id] = s servers[s.ID] = s
} }
} }
@ -196,7 +196,7 @@ func main() {
log.Fatalf("Couldn't start server: %s", err.Error()) log.Fatalf("Couldn't start server: %s", err.Error())
} }
servers[s.Id] = s servers[s.ID] = s
os.Mkdir(filepath.Join(serversDirPath, fmt.Sprintf("%v", 1)), 0750) os.Mkdir(filepath.Join(serversDirPath, fmt.Sprintf("%v", 1)), 0750)
err = s.FreezeToFile() err = s.FreezeToFile()
if err != nil { if err != nil {
@ -208,7 +208,7 @@ func main() {
for _, server := range servers { for _, server := range servers {
err = server.Start() err = server.Start()
if err != nil { if err != nil {
log.Printf("Unable to start server %v: %v", server.Id, err.Error()) log.Printf("Unable to start server %v: %v", server.ID, err.Error())
} }
} }

View file

@ -18,12 +18,14 @@ import (
"mumble.info/grumble/pkg/mumbleproto" "mumble.info/grumble/pkg/mumbleproto"
) )
// Message contains a specific message for a client
type Message struct { type Message struct {
buf []byte buf []byte
kind uint16 kind uint16
client *Client client *Client
} }
// VoiceBroadcast contains a voice broadcast for a specific client
type VoiceBroadcast struct { type VoiceBroadcast struct {
// The client who is performing the broadcast // The client who is performing the broadcast
client *Client client *Client
@ -56,7 +58,7 @@ func (server *Server) handleCryptSetup(client *Client, msg *Message) {
return return
} }
client.crypt.Resync += 1 client.crypt.Resync++
if copy(client.crypt.DecryptIV[0:], cs.ClientNonce) != aes.BlockSize { if copy(client.crypt.DecryptIV[0:], cs.ClientNonce) != aes.BlockSize {
return return
} }
@ -85,24 +87,24 @@ func (server *Server) handlePingMessage(client *Client, msg *Message) {
client.crypt.RemoteResync = *ping.Resync client.crypt.RemoteResync = *ping.Resync
} }
if ping.UdpPingAvg != nil { if ping.UDPPingAvg != nil {
client.UdpPingAvg = *ping.UdpPingAvg client.UDPPingAvg = *ping.UDPPingAvg
} }
if ping.UdpPingVar != nil { if ping.UDPPingVar != nil {
client.UdpPingVar = *ping.UdpPingVar client.UDPPingVar = *ping.UDPPingVar
} }
if ping.UdpPackets != nil { if ping.UDPPackets != nil {
client.UdpPackets = *ping.UdpPackets client.UDPPackets = *ping.UDPPackets
} }
if ping.TcpPingAvg != nil { if ping.TCPPingAvg != nil {
client.TcpPingAvg = *ping.TcpPingAvg client.TCPPingAvg = *ping.TCPPingAvg
} }
if ping.TcpPingVar != nil { if ping.TCPPingVar != nil {
client.TcpPingVar = *ping.TcpPingVar client.TCPPingVar = *ping.TCPPingVar
} }
if ping.TcpPackets != nil { if ping.TCPPackets != nil {
client.TcpPackets = *ping.TcpPackets client.TCPPackets = *ping.TCPPackets
} }
client.sendMessage(&mumbleproto.Ping{ client.sendMessage(&mumbleproto.Ping{
@ -202,7 +204,7 @@ func (server *Server) handleChannelStateMessage(client *Client, msg *Message) {
name = *chanstate.Name name = *chanstate.Name
// We don't allow renames for the root channel. // We don't allow renames for the root channel.
if channel != nil && channel.Id != 0 { if channel != nil && channel.ID != 0 {
// Pick a parent. If the name change is part of a re-parent (a channel move), // Pick a parent. If the name change is part of a re-parent (a channel move),
// we must evaluate the parent variable. Since we're explicitly exlcuding the root // we must evaluate the parent variable. Since we're explicitly exlcuding the root
// channel from renames, channels that are the target of renames are guaranteed to have // channel from renames, channels that are the target of renames are guaranteed to have
@ -268,7 +270,7 @@ func (server *Server) handleChannelStateMessage(client *Client, msg *Message) {
// Add the creator to the channel's admin group // Add the creator to the channel's admin group
if client.IsRegistered() { if client.IsRegistered() {
grp := acl.EmptyGroupWithName("admin") grp := acl.EmptyGroupWithName("admin")
grp.Add[client.UserId()] = true grp.Add[client.UserID()] = true
channel.ACL.Groups["admin"] = grp channel.ACL.Groups["admin"] = grp
} }
@ -279,7 +281,7 @@ func (server *Server) handleChannelStateMessage(client *Client, msg *Message) {
aclEntry.ApplyHere = true aclEntry.ApplyHere = true
aclEntry.ApplySubs = true aclEntry.ApplySubs = true
if client.IsRegistered() { if client.IsRegistered() {
aclEntry.UserId = client.UserId() aclEntry.UserID = client.UserID()
} else { } else {
aclEntry.Group = "$" + client.CertHash() aclEntry.Group = "$" + client.CertHash()
} }
@ -291,7 +293,7 @@ func (server *Server) handleChannelStateMessage(client *Client, msg *Message) {
server.ClearCaches() server.ClearCaches()
} }
chanstate.ChannelId = proto.Uint32(uint32(channel.Id)) chanstate.ChannelId = proto.Uint32(uint32(channel.ID))
// Broadcast channel add // Broadcast channel add
server.broadcastProtoMessageWithPredicate(chanstate, func(client *Client) bool { server.broadcastProtoMessageWithPredicate(chanstate, func(client *Client) bool {
@ -311,7 +313,7 @@ func (server *Server) handleChannelStateMessage(client *Client, msg *Message) {
if channel.IsTemporary() { if channel.IsTemporary() {
userstate := &mumbleproto.UserState{} userstate := &mumbleproto.UserState{}
userstate.Session = proto.Uint32(client.Session()) userstate.Session = proto.Uint32(client.Session())
userstate.ChannelId = proto.Uint32(uint32(channel.Id)) userstate.ChannelId = proto.Uint32(uint32(channel.ID))
server.userEnterChannel(client, channel, userstate) server.userEnterChannel(client, channel, userstate)
server.broadcastProtoMessage(userstate) server.broadcastProtoMessage(userstate)
} }
@ -323,7 +325,7 @@ func (server *Server) handleChannelStateMessage(client *Client, msg *Message) {
if chanstate.Name != nil { if chanstate.Name != nil {
// The client can only rename the channel if it has WritePermission in the channel. // The client can only rename the channel if it has WritePermission in the channel.
// Also, clients cannot change the name of the root channel. // Also, clients cannot change the name of the root channel.
if !acl.HasPermission(&channel.ACL, client, acl.WritePermission) || channel.Id == 0 { if !acl.HasPermission(&channel.ACL, client, acl.WritePermission) || channel.ID == 0 {
client.sendPermissionDenied(client, channel, acl.WritePermission) client.sendPermissionDenied(client, channel, acl.WritePermission)
return return
} }
@ -661,7 +663,7 @@ func (server *Server) handleUserStateMessage(client *Client, msg *Message) {
} }
// Registration // Registration
if userstate.UserId != nil { if userstate.UserID != nil {
// If user == actor, check for SelfRegisterPermission on root channel. // If user == actor, check for SelfRegisterPermission on root channel.
// If user != actor, check for RegisterPermission permission on root channel. // If user != actor, check for RegisterPermission permission on root channel.
perm := acl.Permission(acl.RegisterPermission) perm := acl.Permission(acl.RegisterPermission)
@ -797,13 +799,13 @@ func (server *Server) handleUserStateMessage(client *Client, msg *Message) {
} }
userRegistrationChanged := false userRegistrationChanged := false
if userstate.UserId != nil { if userstate.UserID != nil {
uid, err := server.RegisterClient(target) uid, err := server.RegisterClient(target)
if err != nil { if err != nil {
client.Printf("Unable to register: %v", err) client.Printf("Unable to register: %v", err)
userstate.UserId = nil userstate.UserID = nil
} else { } else {
userstate.UserId = proto.Uint32(uid) userstate.UserID = proto.Uint32(uid)
client.user = server.Users[uid] client.user = server.Users[uid]
userRegistrationChanged = true userRegistrationChanged = true
} }
@ -1026,7 +1028,7 @@ func (server *Server) handleTextMessage(client *Client, msg *Message) {
} }
// ACL set/query // ACL set/query
func (server *Server) handleAclMessage(client *Client, msg *Message) { func (server *Server) handleACLMessage(client *Client, msg *Message) {
pacl := &mumbleproto.ACL{} pacl := &mumbleproto.ACL{}
err := proto.Unmarshal(msg.buf, pacl) err := proto.Unmarshal(msg.buf, pacl)
if err != nil { if err != nil {
@ -1047,14 +1049,14 @@ func (server *Server) handleAclMessage(client *Client, msg *Message) {
} }
reply := &mumbleproto.ACL{} reply := &mumbleproto.ACL{}
reply.ChannelId = proto.Uint32(uint32(channel.Id)) reply.ChannelId = proto.Uint32(uint32(channel.ID))
channels := []*Channel{} channels := []*Channel{}
users := map[int]bool{} users := map[int]bool{}
// Query the current ACL state for the channel // Query the current ACL state for the channel
if pacl.Query != nil && *pacl.Query != false { if pacl.Query != nil && *pacl.Query != false {
reply.InheritAcls = proto.Bool(channel.ACL.InheritACL) reply.InheritACLs = proto.Bool(channel.ACL.InheritACL)
// Walk the channel tree to get all relevant channels. // Walk the channel tree to get all relevant channels.
// (Stop if we reach a channel that doesn't have the InheritACL flag set) // (Stop if we reach a channel that doesn't have the InheritACL flag set)
iter := channel iter := channel
@ -1069,7 +1071,7 @@ func (server *Server) handleAclMessage(client *Client, msg *Message) {
// Construct the protobuf ChanACL objects corresponding to the ACLs defined // Construct the protobuf ChanACL objects corresponding to the ACLs defined
// in our channel list. // in our channel list.
reply.Acls = []*mumbleproto.ACL_ChanACL{} reply.ACLs = []*mumbleproto.ACL_ChanACL{}
for _, iter := range channels { for _, iter := range channels {
for _, chanacl := range iter.ACL.ACLs { for _, chanacl := range iter.ACL.ACLs {
if iter == channel || chanacl.ApplySubs { if iter == channel || chanacl.ApplySubs {
@ -1077,15 +1079,15 @@ func (server *Server) handleAclMessage(client *Client, msg *Message) {
mpacl.Inherited = proto.Bool(iter != channel) mpacl.Inherited = proto.Bool(iter != channel)
mpacl.ApplyHere = proto.Bool(chanacl.ApplyHere) mpacl.ApplyHere = proto.Bool(chanacl.ApplyHere)
mpacl.ApplySubs = proto.Bool(chanacl.ApplySubs) mpacl.ApplySubs = proto.Bool(chanacl.ApplySubs)
if chanacl.UserId >= 0 { if chanacl.UserID >= 0 {
mpacl.UserId = proto.Uint32(uint32(chanacl.UserId)) mpacl.UserID = proto.Uint32(uint32(chanacl.UserID))
users[chanacl.UserId] = true users[chanacl.UserID] = true
} else { } else {
mpacl.Group = proto.String(chanacl.Group) mpacl.Group = proto.String(chanacl.Group)
} }
mpacl.Grant = proto.Uint32(uint32(chanacl.Allow)) mpacl.Grant = proto.Uint32(uint32(chanacl.Allow))
mpacl.Deny = proto.Uint32(uint32(chanacl.Deny)) mpacl.Deny = proto.Uint32(uint32(chanacl.Deny))
reply.Acls = append(reply.Acls, mpacl) reply.ACLs = append(reply.ACLs, mpacl)
} }
} }
} }
@ -1129,20 +1131,20 @@ func (server *Server) handleAclMessage(client *Client, msg *Message) {
// message that maps user ids to usernames. // message that maps user ids to usernames.
if hasgroup { if hasgroup {
toadd := map[int]bool{} toadd := map[int]bool{}
for uid, _ := range group.Add { for uid := range group.Add {
users[uid] = true users[uid] = true
toadd[uid] = true toadd[uid] = true
} }
for uid, _ := range group.Remove { for uid := range group.Remove {
users[uid] = true users[uid] = true
delete(toadd, uid) delete(toadd, uid)
} }
for uid, _ := range toadd { for uid := range toadd {
mpgroup.Add = append(mpgroup.Add, uint32(uid)) mpgroup.Add = append(mpgroup.Add, uint32(uid))
} }
} }
if haspgroup { if haspgroup {
for uid, _ := range pgroup.MembersInContext(&parent.ACL) { for uid := range pgroup.MembersInContext(&parent.ACL) {
users[uid] = true users[uid] = true
mpgroup.InheritedMembers = append(mpgroup.InheritedMembers, uint32(uid)) mpgroup.InheritedMembers = append(mpgroup.InheritedMembers, uint32(uid))
} }
@ -1158,7 +1160,7 @@ func (server *Server) handleAclMessage(client *Client, msg *Message) {
// Map the user ids in the user map to usernames of users. // Map the user ids in the user map to usernames of users.
queryusers := &mumbleproto.QueryUsers{} queryusers := &mumbleproto.QueryUsers{}
for uid, _ := range users { for uid := range users {
user, ok := server.Users[uint32(uid)] user, ok := server.Users[uint32(uid)]
if !ok { if !ok {
client.Printf("Invalid user id in ACL") client.Printf("Invalid user id in ACL")
@ -1185,7 +1187,7 @@ func (server *Server) handleAclMessage(client *Client, msg *Message) {
channel.ACL.Groups = map[string]acl.Group{} channel.ACL.Groups = map[string]acl.Group{}
// Add the received groups to the channel. // Add the received groups to the channel.
channel.ACL.InheritACL = *pacl.InheritAcls channel.ACL.InheritACL = *pacl.InheritACLs
for _, pbgrp := range pacl.Groups { for _, pbgrp := range pacl.Groups {
changroup := acl.EmptyGroupWithName(*pbgrp.Name) changroup := acl.EmptyGroupWithName(*pbgrp.Name)
@ -1204,12 +1206,12 @@ func (server *Server) handleAclMessage(client *Client, msg *Message) {
channel.ACL.Groups[changroup.Name] = changroup channel.ACL.Groups[changroup.Name] = changroup
} }
// Add the received ACLs to the channel. // Add the received ACLs to the channel.
for _, pbacl := range pacl.Acls { for _, pbacl := range pacl.ACLs {
chanacl := acl.ACL{} chanacl := acl.ACL{}
chanacl.ApplyHere = *pbacl.ApplyHere chanacl.ApplyHere = *pbacl.ApplyHere
chanacl.ApplySubs = *pbacl.ApplySubs chanacl.ApplySubs = *pbacl.ApplySubs
if pbacl.UserId != nil { if pbacl.UserID != nil {
chanacl.UserId = int(*pbacl.UserId) chanacl.UserID = int(*pbacl.UserID)
} else { } else {
chanacl.Group = *pbacl.Group chanacl.Group = *pbacl.Group
} }
@ -1228,7 +1230,7 @@ func (server *Server) handleAclMessage(client *Client, msg *Message) {
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.Group = "$" + client.CertHash() chanacl.Group = "$" + client.CertHash()
} }
@ -1269,7 +1271,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[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)
} }
} }
@ -1356,12 +1358,12 @@ func (server *Server) handleUserStatsMessage(client *Client, msg *Message) {
stats.FromServer = fromServer stats.FromServer = fromServer
} }
stats.UdpPackets = proto.Uint32(target.UdpPackets) stats.UDPPackets = proto.Uint32(target.UDPPackets)
stats.TcpPackets = proto.Uint32(target.TcpPackets) stats.TCPPackets = proto.Uint32(target.TCPPackets)
stats.UdpPingAvg = proto.Float32(target.UdpPingAvg) stats.UDPPingAvg = proto.Float32(target.UDPPingAvg)
stats.UdpPingVar = proto.Float32(target.UdpPingVar) stats.UDPPingVar = proto.Float32(target.UDPPingVar)
stats.TcpPingAvg = proto.Float32(target.TcpPingAvg) stats.TCPPingAvg = proto.Float32(target.TCPPingAvg)
stats.TcpPingVar = proto.Float32(target.TcpPingVar) stats.TCPPingVar = proto.Float32(target.TCPPingVar)
if details { if details {
version := &mumbleproto.Version{} version := &mumbleproto.Version{}
@ -1531,7 +1533,7 @@ func (server *Server) handleRequestBlob(client *Client, msg *Message) {
server.Panicf("Blobstore error: %v", err) server.Panicf("Blobstore error: %v", err)
return return
} }
chanstate.ChannelId = proto.Uint32(uint32(channel.Id)) chanstate.ChannelId = proto.Uint32(uint32(channel.ID))
chanstate.Description = proto.String(string(buf)) chanstate.Description = proto.String(string(buf))
if err := client.sendMessage(chanstate); err != nil { if err := client.sendMessage(chanstate); err != nil {
client.Panic(err) client.Panic(err)
@ -1566,7 +1568,7 @@ func (server *Server) handleUserList(client *Client, msg *Message) {
continue continue
} }
userlist.Users = append(userlist.Users, &mumbleproto.UserList_User{ userlist.Users = append(userlist.Users, &mumbleproto.UserList_User{
UserId: proto.Uint32(uid), UserID: proto.Uint32(uid),
Name: proto.String(user.Name), Name: proto.String(user.Name),
}) })
} }
@ -1579,7 +1581,7 @@ func (server *Server) handleUserList(client *Client, msg *Message) {
if len(userlist.Users) > 0 { if len(userlist.Users) > 0 {
tx := server.freezelog.BeginTx() tx := server.freezelog.BeginTx()
for _, listUser := range userlist.Users { for _, listUser := range userlist.Users {
uid := *listUser.UserId uid := *listUser.UserID
if uid == 0 { if uid == 0 {
continue continue
} }
@ -1588,7 +1590,7 @@ func (server *Server) handleUserList(client *Client, msg *Message) {
if listUser.Name == nil { if listUser.Name == nil {
// De-register // De-register
server.RemoveRegistration(uid) server.RemoveRegistration(uid)
err := tx.Put(&freezer.UserRemove{Id: listUser.UserId}) err := tx.Put(&freezer.UserRemove{Id: listUser.UserID})
if err != nil { if err != nil {
server.Fatal(err) server.Fatal(err)
} }
@ -1596,7 +1598,7 @@ func (server *Server) handleUserList(client *Client, msg *Message) {
// Rename user // Rename user
// todo(mkrautz): Validate name. // todo(mkrautz): Validate name.
user.Name = *listUser.Name user.Name = *listUser.Name
err := tx.Put(&freezer.User{Id: listUser.UserId, Name: listUser.Name}) err := tx.Put(&freezer.User{Id: listUser.UserID, Name: listUser.Name})
if err != nil { if err != nil {
server.Fatal(err) server.Fatal(err)
} }

View file

@ -23,22 +23,31 @@ import (
) )
const ( const (
// ChannelInfoDescription represents the description of a channel info
ChannelInfoDescription int = iota ChannelInfoDescription int = iota
// ChannelInfoPosition represents the position of a channel info
ChannelInfoPosition ChannelInfoPosition
) )
const ( const (
// UserInfoName points to the name field of user information
UserInfoName int = iota UserInfoName int = iota
// UserInfoEmail points to the email field of user information
UserInfoEmail UserInfoEmail
// UserInfoComment points to the comment field of user information
UserInfoComment UserInfoComment
// UserInfoHash points to the hash field of user information
UserInfoHash UserInfoHash
// UserInfoPassword points to the password field of user information
UserInfoPassword UserInfoPassword
// UserInfoLastActive points to the last active field of user information
UserInfoLastActive UserInfoLastActive
) )
// SQLiteSupport marks whether SQLite is supported or not
const SQLiteSupport = true const SQLiteSupport = true
// Import the structure of an existing Murmur SQLite database. // MurmurImport will import the structure of an existing Murmur SQLite database.
func MurmurImport(filename string) (err error) { func MurmurImport(filename string) (err error) {
db, err := sql.Open("sqlite", filename) db, err := sql.Open("sqlite", filename)
if err != nil { if err != nil {
@ -84,7 +93,7 @@ func MurmurImport(filename string) (err error) {
return return
} }
// Create a new Server from a Murmur SQLite database // NewServerFromSQLite will create a new Server from a Murmur SQLite database
func NewServerFromSQLite(id int64, db *sql.DB) (s *Server, err error) { func NewServerFromSQLite(id int64, db *sql.DB) (s *Server, err error) {
s, err = NewServer(id) s, err = NewServer(id)
if err != nil { if err != nil {
@ -137,7 +146,7 @@ func populateChannelInfoFromDatabase(server *Server, c *Channel, db *sql.DB) err
} }
// Fetch description // Fetch description
rows, err := stmt.Query(server.Id, c.Id, ChannelInfoDescription) rows, err := stmt.Query(server.ID, c.ID, ChannelInfoDescription)
if err != nil { if err != nil {
return err return err
} }
@ -158,7 +167,7 @@ func populateChannelInfoFromDatabase(server *Server, c *Channel, db *sql.DB) err
} }
// Fetch position // Fetch position
rows, err = stmt.Query(server.Id, c.Id, ChannelInfoPosition) rows, err = stmt.Query(server.ID, c.ID, ChannelInfoPosition)
if err != nil { if err != nil {
return err return err
} }
@ -181,36 +190,36 @@ func populateChannelACLFromDatabase(server *Server, c *Channel, db *sql.DB) erro
return err return err
} }
rows, err := stmt.Query(server.Id, c.Id) rows, err := stmt.Query(server.ID, c.ID)
if err != nil { if err != nil {
return err return err
} }
for rows.Next() { for rows.Next() {
var ( var (
UserId string UserID string
Group string Group string
ApplyHere bool ApplyHere bool
ApplySub bool ApplySub bool
Allow int64 Allow int64
Deny int64 Deny int64
) )
if err := rows.Scan(&UserId, &Group, &ApplyHere, &ApplySub, &Allow, &Deny); err != nil { if err := rows.Scan(&UserID, &Group, &ApplyHere, &ApplySub, &Allow, &Deny); err != nil {
return err return err
} }
aclEntry := acl.ACL{} aclEntry := acl.ACL{}
aclEntry.ApplyHere = ApplyHere aclEntry.ApplyHere = ApplyHere
aclEntry.ApplySubs = ApplySub aclEntry.ApplySubs = ApplySub
if len(UserId) > 0 { if len(UserID) > 0 {
aclEntry.UserId, err = strconv.Atoi(UserId) aclEntry.UserID, err = strconv.Atoi(UserID)
if err != nil { if err != nil {
return err return err
} }
} else if len(Group) > 0 { } else if len(Group) > 0 {
aclEntry.Group = Group aclEntry.Group = Group
} else { } else {
return errors.New("Invalid ACL: Neither Group or UserId specified") return errors.New("Invalid ACL: Neither Group or UserID specified")
} }
aclEntry.Deny = acl.Permission(Deny) aclEntry.Deny = acl.Permission(Deny)
@ -228,7 +237,7 @@ func populateChannelGroupsFromDatabase(server *Server, c *Channel, db *sql.DB) e
return err return err
} }
rows, err := stmt.Query(server.Id, c.Id) rows, err := stmt.Query(server.ID, c.ID)
if err != nil { if err != nil {
return err return err
} }
@ -237,13 +246,13 @@ func populateChannelGroupsFromDatabase(server *Server, c *Channel, db *sql.DB) e
for rows.Next() { for rows.Next() {
var ( var (
GroupId int64 GroupID int64
Name string Name string
Inherit bool Inherit bool
Inheritable bool Inheritable bool
) )
if err := rows.Scan(&GroupId, &Name, &Inherit, &Inheritable); err != nil { if err := rows.Scan(&GroupID, &Name, &Inherit, &Inheritable); err != nil {
return err return err
} }
@ -251,7 +260,7 @@ func populateChannelGroupsFromDatabase(server *Server, c *Channel, db *sql.DB) e
g.Inherit = Inherit g.Inherit = Inherit
g.Inheritable = Inheritable g.Inheritable = Inheritable
c.ACL.Groups[g.Name] = g c.ACL.Groups[g.Name] = g
groups[GroupId] = g groups[GroupID] = g
} }
stmt, err = db.Prepare("SELECT user_id, addit FROM group_members WHERE server_id=? AND group_id=?") stmt, err = db.Prepare("SELECT user_id, addit FROM group_members WHERE server_id=? AND group_id=?")
@ -260,25 +269,25 @@ func populateChannelGroupsFromDatabase(server *Server, c *Channel, db *sql.DB) e
} }
for gid, grp := range groups { for gid, grp := range groups {
rows, err = stmt.Query(server.Id, gid) rows, err = stmt.Query(server.ID, gid)
if err != nil { if err != nil {
return err return err
} }
for rows.Next() { for rows.Next() {
var ( var (
UserId int64 UserID int64
Add bool Add bool
) )
if err := rows.Scan(&UserId, &Add); err != nil { if err := rows.Scan(&UserID, &Add); err != nil {
return err return err
} }
if Add { if Add {
grp.Add[int(UserId)] = true grp.Add[int(UserID)] = true
} else { } else {
grp.Remove[int(UserId)] = true grp.Remove[int(UserID)] = true
} }
} }
} }
@ -287,8 +296,8 @@ func populateChannelGroupsFromDatabase(server *Server, c *Channel, db *sql.DB) e
} }
// Populate the Server with Channels from the database. // Populate the Server with Channels from the database.
func populateChannelsFromDatabase(server *Server, db *sql.DB, parentId int) error { func populateChannelsFromDatabase(server *Server, db *sql.DB, parentID int) error {
parent, exists := server.Channels[parentId] parent, exists := server.Channels[parentID]
if !exists { if !exists {
return errors.New("Non-existant parent") return errors.New("Non-existant parent")
} }
@ -298,7 +307,7 @@ func populateChannelsFromDatabase(server *Server, db *sql.DB, parentId int) erro
return err return err
} }
rows, err := stmt.Query(server.Id, parentId) rows, err := stmt.Query(server.ID, parentID)
if err != nil { if err != nil {
return err return err
} }
@ -315,7 +324,7 @@ func populateChannelsFromDatabase(server *Server, db *sql.DB, parentId int) erro
} }
c := NewChannel(chanid, name) c := NewChannel(chanid, name)
server.Channels[c.Id] = c server.Channels[c.ID] = c
c.ACL.InheritACL = inherit c.ACL.InheritACL = inherit
parent.AddChild(c) parent.AddChild(c)
} }
@ -345,7 +354,7 @@ func populateChannelsFromDatabase(server *Server, db *sql.DB, parentId int) erro
} }
// Add subchannels // Add subchannels
for id, _ := range parent.children { for id := range parent.children {
err = populateChannelsFromDatabase(server, db, id) err = populateChannelsFromDatabase(server, db, id)
if err != nil { if err != nil {
return err return err
@ -362,28 +371,28 @@ func populateChannelLinkInfo(server *Server, db *sql.DB) (err error) {
return err return err
} }
rows, err := stmt.Query(server.Id) rows, err := stmt.Query(server.ID)
if err != nil { if err != nil {
return err return err
} }
for rows.Next() { for rows.Next() {
var ( var (
ChannelId int ChannelID int
LinkId int LinkID int
) )
if err := rows.Scan(&ChannelId, &LinkId); err != nil { if err := rows.Scan(&ChannelID, &LinkID); err != nil {
return err return err
} }
channel, exists := server.Channels[ChannelId] channel, exists := server.Channels[ChannelID]
if !exists { if !exists {
return errors.New("Attempt to perform link operation on non-existant channel.") return errors.New("attempt to perform link operation on non-existant channel")
} }
other, exists := server.Channels[LinkId] other, exists := server.Channels[LinkID]
if !exists { if !exists {
return errors.New("Attempt to perform link operation on non-existant channel.") return errors.New("attempt to perform link operation on non-existant channel")
} }
server.LinkChannels(channel, other) server.LinkChannels(channel, other)
@ -399,14 +408,14 @@ func populateUsers(server *Server, db *sql.DB) (err error) {
return return
} }
rows, err := stmt.Query(server.Id) rows, err := stmt.Query(server.ID)
if err != nil { if err != nil {
return return
} }
for rows.Next() { for rows.Next() {
var ( var (
UserId int64 UserID int64
UserName string UserName string
SHA1Password string SHA1Password string
LastChannel int LastChannel int
@ -414,16 +423,16 @@ func populateUsers(server *Server, db *sql.DB) (err error) {
LastActive int64 LastActive int64
) )
err = rows.Scan(&UserId, &UserName, &SHA1Password, &LastChannel, &Texture, &LastActive) err = rows.Scan(&UserID, &UserName, &SHA1Password, &LastChannel, &Texture, &LastActive)
if err != nil { if err != nil {
continue continue
} }
if UserId == 0 { if UserID == 0 {
server.cfg.Set("SuperUserPassword", "sha1$$"+SHA1Password) server.cfg.Set("SuperUserPassword", "sha1$$"+SHA1Password)
} }
user, err := NewUser(uint32(UserId), UserName) user, err := NewUser(uint32(UserID), UserName)
if err != nil { if err != nil {
return err return err
} }
@ -437,9 +446,9 @@ func populateUsers(server *Server, db *sql.DB) (err error) {
} }
user.LastActive = uint64(LastActive) user.LastActive = uint64(LastActive)
user.LastChannelId = LastChannel user.LastChannelID = LastChannel
server.Users[user.Id] = user server.Users[user.ID] = user
} }
stmt, err = db.Prepare("SELECT key, value FROM user_info WHERE server_id=? AND user_id=?") stmt, err = db.Prepare("SELECT key, value FROM user_info WHERE server_id=? AND user_id=?")
@ -449,7 +458,7 @@ func populateUsers(server *Server, db *sql.DB) (err error) {
// Populate users with any new-style UserInfo records // Populate users with any new-style UserInfo records
for uid, user := range server.Users { for uid, user := range server.Users {
rows, err = stmt.Query(server.Id, uid) rows, err = stmt.Query(server.ID, uid)
if err != nil { if err != nil {
return err return err
} }
@ -496,7 +505,7 @@ func populateBans(server *Server, db *sql.DB) (err error) {
return return
} }
rows, err := stmt.Query(server.Id) rows, err := stmt.Query(server.ID)
if err != nil { if err != nil {
return err return err
} }

View file

@ -16,6 +16,7 @@ import (
"net/http" "net/http"
) )
// Register contains the information necessary to register a server
type Register struct { type Register struct {
XMLName xml.Name `xml:"server"` XMLName xml.Name `xml:"server"`
Version string `xml:"version"` Version string `xml:"version"`
@ -24,16 +25,16 @@ type Register struct {
Host string `xml:"host"` Host string `xml:"host"`
Password string `xml:"password"` Password string `xml:"password"`
Port int `xml:"port"` Port int `xml:"port"`
Url string `xml:"url"` URL string `xml:"url"`
Digest string `xml:"digest"` Digest string `xml:"digest"`
Users int `xml:"users"` Users int `xml:"users"`
Channels int `xml:"channels"` Channels int `xml:"channels"`
Location string `xml:"location"` Location string `xml:"location"`
} }
const registerUrl = "https://mumble.info/register.cgi" const registerURL = "https://mumble.info/register.cgi"
// Determines whether a server is public by checking whether the // IsPublic Determines whether a server is public by checking whether the
// config values required for public registration are set. // config values required for public registration are set.
// //
// This function is used to determine whether or not to periodically // This function is used to determine whether or not to periodically
@ -54,7 +55,7 @@ func (server *Server) IsPublic() bool {
return true return true
} }
// Perform a public server registration update. // RegisterPublicServer will perform a public server registration update.
// //
// When a Mumble server connects to the master server // When a Mumble server connects to the master server
// for registration, it connects using its server certificate // for registration, it connects using its server certificate
@ -83,7 +84,7 @@ func (server *Server) RegisterPublicServer() {
Name: server.cfg.StringValue("RegisterName"), Name: server.cfg.StringValue("RegisterName"),
Host: server.cfg.StringValue("RegisterHost"), Host: server.cfg.StringValue("RegisterHost"),
Password: server.cfg.StringValue("RegisterPassword"), Password: server.cfg.StringValue("RegisterPassword"),
Url: server.cfg.StringValue("RegisterWebUrl"), URL: server.cfg.StringValue("RegisterWebUrl"),
Location: server.cfg.StringValue("RegisterLocation"), Location: server.cfg.StringValue("RegisterLocation"),
Port: server.CurrentPort(), Port: server.CurrentPort(),
Digest: digest, Digest: digest,
@ -105,7 +106,7 @@ func (server *Server) RegisterPublicServer() {
TLSClientConfig: config, TLSClientConfig: config,
} }
client := &http.Client{Transport: tr} client := &http.Client{Transport: tr}
r, err := client.Post(registerUrl, "text/xml", ioutil.NopCloser(buf)) r, err := client.Post(registerURL, "text/xml", ioutil.NopCloser(buf))
if err != nil { if err != nil {
server.Printf("register: unable to post registration request: %v", err) server.Printf("register: unable to post registration request: %v", err)
return return

View file

@ -36,13 +36,23 @@ import (
"mumble.info/grumble/pkg/web" "mumble.info/grumble/pkg/web"
) )
// The default port a Murmur server listens on // DefaultPort is the default port a Murmur server listens on
const DefaultPort = 64738 const DefaultPort = 64738
// DefaultWebPort is the default web port a Grumble server listens on
const DefaultWebPort = 443 const DefaultWebPort = 443
// UDPPacketSize is the size of each UDP packet
const UDPPacketSize = 1024 const UDPPacketSize = 1024
// LogOpsBeforeSync is the amount of logging operations that can be done
// before syncing
const LogOpsBeforeSync = 100 const LogOpsBeforeSync = 100
// CeltCompatBitstream specifies the codec for celt compatibility
const CeltCompatBitstream = -2147483637 const CeltCompatBitstream = -2147483637
// These constants keep track of the different states the server can be in
const ( const (
StateClientConnected = iota StateClientConnected = iota
StateServerSentVersion StateServerSentVersion
@ -52,15 +62,16 @@ const (
StateClientDead StateClientDead
) )
// KeyValuePair contains a key value pair and a reset flag
type KeyValuePair struct { type KeyValuePair struct {
Key string Key string
Value string Value string
Reset bool Reset bool
} }
// A Murmur server instance // Server is a Grumble server instance
type Server struct { type Server struct {
Id int64 ID int64
tcpl *net.TCPListener tcpl *net.TCPListener
tlsl net.Listener tlsl net.Listener
@ -101,13 +112,13 @@ type Server struct {
// Channels // Channels
Channels map[int]*Channel Channels map[int]*Channel
nextChanId int nextChanID int
// Users // Users
Users map[uint32]*User Users map[uint32]*User
UserCertMap map[string]*User UserCertMap map[string]*User
UserNameMap map[string]*User UserNameMap map[string]*User
nextUserId uint32 nextUserID uint32
// Sessions // Sessions
pool *sessionpool.SessionPool pool *sessionpool.SessionPool
@ -131,17 +142,17 @@ type clientLogForwarder struct {
func (lf clientLogForwarder) Write(incoming []byte) (int, error) { func (lf clientLogForwarder) Write(incoming []byte) (int, error) {
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
buf.WriteString(fmt.Sprintf("<%v:%v(%v)> ", lf.client.Session(), lf.client.ShownName(), lf.client.UserId())) buf.WriteString(fmt.Sprintf("<%v:%v(%v)> ", lf.client.Session(), lf.client.ShownName(), lf.client.UserID()))
buf.Write(incoming) buf.Write(incoming)
lf.logger.Output(3, buf.String()) lf.logger.Output(3, buf.String())
return len(incoming), nil return len(incoming), nil
} }
// Allocate a new Murmur instance // NewServer will allocate a new Grumble instance
func NewServer(id int64) (s *Server, err error) { func NewServer(id int64) (s *Server, err error) {
s = new(Server) s = new(Server)
s.Id = id s.ID = id
s.cfg = serverconf.New(nil) s.cfg = serverconf.New(nil)
@ -150,13 +161,13 @@ func NewServer(id int64) (s *Server, err error) {
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)
s.Channels[0] = NewChannel(0, "Root") s.Channels[0] = NewChannel(0, "Root")
s.nextChanId = 1 s.nextChanID = 1
s.Logger = log.New(&logtarget.Target, fmt.Sprintf("[%v] ", s.Id), log.LstdFlags|log.Lmicroseconds) s.Logger = log.New(&logtarget.Target, fmt.Sprintf("[%v] ", s.ID), log.LstdFlags|log.Lmicroseconds)
return return
} }
@ -175,7 +186,7 @@ func (server *Server) RootChannel() *Channel {
return root return root
} }
// Set password as the new SuperUser password // SetSuperUserPassword will set password as the new SuperUser password
func (server *Server) SetSuperUserPassword(password string) { func (server *Server) SetSuperUserPassword(password string) {
saltBytes := make([]byte, 24) saltBytes := make([]byte, 24)
_, err := rand.Read(saltBytes) _, err := rand.Read(saltBytes)
@ -244,7 +255,7 @@ func (server *Server) handleIncomingClient(conn net.Conn) (err error) {
client := new(Client) client := new(Client)
addr := conn.RemoteAddr() addr := conn.RemoteAddr()
if addr == nil { if addr == nil {
err = errors.New("Unable to extract address for client.") err = errors.New("unable to extract address for client")
return return
} }
@ -342,33 +353,33 @@ func (server *Server) RemoveClient(client *Client, kicked bool) {
// AddChannel adds a new channel to the server. Automatically assign it a channel ID. // AddChannel adds a new channel to the server. Automatically assign it a channel ID.
func (server *Server) AddChannel(name string) (channel *Channel) { func (server *Server) AddChannel(name string) (channel *Channel) {
channel = NewChannel(server.nextChanId, name) channel = NewChannel(server.nextChanID, name)
server.Channels[channel.Id] = channel server.Channels[channel.ID] = channel
server.nextChanId += 1 server.nextChanID++
return return
} }
// RemoveChanel removes a channel from the server. // RemoveChanel removes a channel from the server.
func (server *Server) RemoveChanel(channel *Channel) { func (server *Server) RemoveChanel(channel *Channel) {
if channel.Id == 0 { if channel.ID == 0 {
server.Printf("Attempted to remove root channel.") server.Printf("Attempted to remove root channel.")
return return
} }
delete(server.Channels, channel.Id) delete(server.Channels, channel.ID)
} }
// Link two channels // LinkChannels will link two channels
func (server *Server) LinkChannels(channel *Channel, other *Channel) { func (server *Server) LinkChannels(channel *Channel, other *Channel) {
channel.Links[other.Id] = other channel.Links[other.ID] = other
other.Links[channel.Id] = channel other.Links[channel.ID] = channel
} }
// Unlink two channels // UnlinkChannels will unlink two channels
func (server *Server) UnlinkChannels(channel *Channel, other *Channel) { func (server *Server) UnlinkChannels(channel *Channel, other *Channel) {
delete(channel.Links, other.Id) delete(channel.Links, other.ID)
delete(other.Links, channel.Id) delete(other.Links, channel.ID)
} }
// This is the synchronous handler goroutine. // This is the synchronous handler goroutine.
@ -484,18 +495,17 @@ func (server *Server) handleAuthenticate(client *Client, msg *Message) {
if auth.Password == nil { if auth.Password == nil {
client.RejectAuth(mumbleproto.Reject_WrongUserPW, "") client.RejectAuth(mumbleproto.Reject_WrongUserPW, "")
return return
} 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[client.Username]
if !ok { if !ok {
client.RejectAuth(mumbleproto.Reject_InvalidUsername, "") client.RejectAuth(mumbleproto.Reject_InvalidUsername, "")
return
}
} else {
client.RejectAuth(mumbleproto.Reject_WrongUserPW, "")
return return
} }
} else {
client.RejectAuth(mumbleproto.Reject_WrongUserPW, "")
return
} }
} else { } else {
// First look up registration by name. // First look up registration by name.
@ -557,7 +567,7 @@ func (server *Server) finishAuthenticate(client *Client) {
if client.user != nil { if client.user != nil {
found := false found := false
for _, connectedClient := range server.clients { for _, connectedClient := range server.clients {
if connectedClient.UserId() == client.UserId() { if connectedClient.UserID() == client.UserID() {
found = true found = true
break break
} }
@ -601,7 +611,7 @@ func (server *Server) finishAuthenticate(client *Client) {
channel := server.RootChannel() channel := server.RootChannel()
if client.IsRegistered() { if client.IsRegistered() {
lastChannel := server.Channels[client.user.LastChannelId] lastChannel := server.Channels[client.user.LastChannelID]
if lastChannel != nil { if lastChannel != nil {
channel = lastChannel channel = lastChannel
} }
@ -610,7 +620,7 @@ func (server *Server) finishAuthenticate(client *Client) {
userstate := &mumbleproto.UserState{ userstate := &mumbleproto.UserState{
Session: proto.Uint32(client.Session()), Session: proto.Uint32(client.Session()),
Name: proto.String(client.ShownName()), Name: proto.String(client.ShownName()),
ChannelId: proto.Uint32(uint32(channel.Id)), ChannelId: proto.Uint32(uint32(channel.ID)),
} }
if client.HasCertificate() { if client.HasCertificate() {
@ -618,7 +628,7 @@ func (server *Server) finishAuthenticate(client *Client) {
} }
if client.IsRegistered() { if client.IsRegistered() {
userstate.UserId = proto.Uint32(uint32(client.UserId())) userstate.UserID = proto.Uint32(uint32(client.UserID()))
if client.user.HasTexture() { if client.user.HasTexture() {
// Does the client support blobs? // Does the client support blobs?
@ -706,7 +716,7 @@ func (server *Server) updateCodecVersions(connecting *Client) {
opus++ opus++
} }
for _, codec := range client.codecs { for _, codec := range client.codecs {
codecusers[codec] += 1 codecusers[codec]++
} }
} }
@ -794,7 +804,7 @@ func (server *Server) sendUserList(client *Client) {
userstate := &mumbleproto.UserState{ userstate := &mumbleproto.UserState{
Session: proto.Uint32(connectedClient.Session()), Session: proto.Uint32(connectedClient.Session()),
Name: proto.String(connectedClient.ShownName()), Name: proto.String(connectedClient.ShownName()),
ChannelId: proto.Uint32(uint32(connectedClient.Channel.Id)), ChannelId: proto.Uint32(uint32(connectedClient.Channel.ID)),
} }
if connectedClient.HasCertificate() { if connectedClient.HasCertificate() {
@ -802,7 +812,7 @@ func (server *Server) sendUserList(client *Client) {
} }
if connectedClient.IsRegistered() { if connectedClient.IsRegistered() {
userstate.UserId = proto.Uint32(uint32(connectedClient.UserId())) userstate.UserID = proto.Uint32(uint32(connectedClient.UserID()))
if connectedClient.user.HasTexture() { if connectedClient.user.HasTexture() {
// Does the client support blobs? // Does the client support blobs?
@ -872,15 +882,15 @@ func (server *Server) sendClientPermissions(client *Client, channel *Channel) {
} }
// fixme(mkrautz): re-add when we have ACL caching // fixme(mkrautz): re-add when we have ACL caching
return
perm := acl.Permission(acl.NonePermission) // 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)),
}) // })
} }
// ClientPredicate takes a client and returns a boolean
type ClientPredicate func(client *Client) bool type ClientPredicate func(client *Client) bool
func (server *Server) broadcastProtoMessageWithPredicate(msg interface{}, clientcheck ClientPredicate) error { func (server *Server) broadcastProtoMessageWithPredicate(msg interface{}, clientcheck ClientPredicate) error {
@ -924,7 +934,7 @@ func (server *Server) handleIncomingMessage(client *Client, msg *Message) {
case mumbleproto.MessageTextMessage: case mumbleproto.MessageTextMessage:
server.handleTextMessage(msg.client, msg) server.handleTextMessage(msg.client, msg)
case mumbleproto.MessageACL: case mumbleproto.MessageACL:
server.handleAclMessage(msg.client, msg) server.handleACLMessage(msg.client, msg)
case mumbleproto.MessageQueryUsers: case mumbleproto.MessageQueryUsers:
server.handleQueryUsers(msg.client, msg) server.handleQueryUsers(msg.client, msg)
case mumbleproto.MessageCryptSetup: case mumbleproto.MessageCryptSetup:
@ -944,9 +954,9 @@ func (server *Server) handleIncomingMessage(client *Client, msg *Message) {
} }
} }
// Send the content of buf as a UDP packet to addr. // SendUDP will send the content of buf as a UDP packet to addr.
func (s *Server) SendUDP(buf []byte, addr *net.UDPAddr) (err error) { func (server *Server) SendUDP(buf []byte, addr *net.UDPAddr) (err error) {
_, err = s.udpconn.WriteTo(buf, addr) _, err = server.udpconn.WriteTo(buf, addr)
return return
} }
@ -994,12 +1004,12 @@ func (server *Server) udpListenLoop() {
} }
} else { } else {
server.handleUdpPacket(udpaddr, buf[0:nread]) server.handleUDPPacket(udpaddr, buf[0:nread])
} }
} }
} }
func (server *Server) handleUdpPacket(udpaddr *net.UDPAddr, buf []byte) { func (server *Server) handleUDPPacket(udpaddr *net.UDPAddr, buf []byte) {
var match *Client var match *Client
plain := make([]byte, len(buf)) plain := make([]byte, len(buf))
@ -1029,9 +1039,8 @@ func (server *Server) handleUdpPacket(udpaddr *net.UDPAddr, buf []byte) {
client.Debugf("unable to decrypt incoming packet, requesting resync: %v", err) client.Debugf("unable to decrypt incoming packet, requesting resync: %v", err)
client.cryptResync() client.cryptResync()
return return
} else {
match = client
} }
match = client
} }
if match != nil { if match != nil {
match.udpaddr = udpaddr match.udpaddr = udpaddr
@ -1089,16 +1098,16 @@ func (server *Server) userEnterChannel(client *Client, channel *Channel, usersta
} }
} }
// Register a client on the server. // RegisterClient will register a client on the server.
func (s *Server) RegisterClient(client *Client) (uid uint32, err error) { func (server *Server) RegisterClient(client *Client) (uid uint32, err error) {
// Increment nextUserId only if registration succeeded. // Increment nextUserID only if registration succeeded.
defer func() { defer func() {
if err == nil { if err == nil {
s.nextUserId += 1 server.nextUserID++
} }
}() }()
user, err := NewUser(s.nextUserId, client.Username) user, err := NewUser(server.nextUserID, client.Username)
if err != nil { if err != nil {
return 0, err return 0, err
} }
@ -1111,38 +1120,38 @@ func (s *Server) RegisterClient(client *Client) (uid uint32, err error) {
user.Email = client.Email user.Email = client.Email
user.CertHash = client.CertHash() user.CertHash = client.CertHash()
uid = s.nextUserId uid = server.nextUserID
s.Users[uid] = user server.Users[uid] = user
s.UserCertMap[client.CertHash()] = user server.UserCertMap[client.CertHash()] = user
s.UserNameMap[client.Username] = user server.UserNameMap[client.Username] = user
return uid, nil return uid, nil
} }
// RemoveRegistration removes a registered user. // RemoveRegistration removes a registered user.
func (s *Server) RemoveRegistration(uid uint32) (err error) { func (server *Server) RemoveRegistration(uid uint32) (err error) {
user, ok := s.Users[uid] user, ok := server.Users[uid]
if !ok { if !ok {
return errors.New("Unknown user ID") return errors.New("Unknown user ID")
} }
// Remove from user maps // Remove from user maps
delete(s.Users, uid) delete(server.Users, uid)
delete(s.UserCertMap, user.CertHash) delete(server.UserCertMap, user.CertHash)
delete(s.UserNameMap, user.Name) delete(server.UserNameMap, user.Name)
// Remove from groups and ACLs. // Remove from groups and ACLs.
s.removeRegisteredUserFromChannel(uid, s.RootChannel()) server.removeRegisteredUserFromChannel(uid, server.RootChannel())
return nil return nil
} }
// Remove references for user id uid from channel. Traverses subchannels. // Remove references for user id uid from channel. Traverses subchannels.
func (s *Server) removeRegisteredUserFromChannel(uid uint32, channel *Channel) { func (server *Server) removeRegisteredUserFromChannel(uid uint32, channel *Channel) {
newACL := []acl.ACL{} newACL := []acl.ACL{}
for _, chanacl := range channel.ACL.ACLs { for _, chanacl := range channel.ACL.ACLs {
if chanacl.UserId == int(uid) { if chanacl.UserID == int(uid) {
continue continue
} }
newACL = append(newACL, chanacl) newACL = append(newACL, chanacl)
@ -1162,7 +1171,7 @@ func (s *Server) removeRegisteredUserFromChannel(uid uint32, channel *Channel) {
} }
for _, subChan := range channel.children { for _, subChan := range channel.children {
s.removeRegisteredUserFromChannel(uid, subChan) server.removeRegisteredUserFromChannel(uid, subChan)
} }
} }
@ -1175,7 +1184,7 @@ func (server *Server) RemoveChannel(channel *Channel) {
// Remove all links // Remove all links
for _, linkedChannel := range channel.Links { for _, linkedChannel := range channel.Links {
delete(linkedChannel.Links, channel.Id) delete(linkedChannel.Links, channel.ID)
} }
// Remove all subchannels // Remove all subchannels
@ -1192,7 +1201,7 @@ func (server *Server) RemoveChannel(channel *Channel) {
userstate := &mumbleproto.UserState{} userstate := &mumbleproto.UserState{}
userstate.Session = proto.Uint32(client.Session()) userstate.Session = proto.Uint32(client.Session())
userstate.ChannelId = proto.Uint32(uint32(target.Id)) userstate.ChannelId = proto.Uint32(uint32(target.ID))
server.userEnterChannel(client, target, userstate) server.userEnterChannel(client, target, userstate)
if err := server.broadcastProtoMessage(userstate); err != nil { if err := server.broadcastProtoMessage(userstate); err != nil {
server.Panicf("%v", err) server.Panicf("%v", err)
@ -1201,10 +1210,10 @@ func (server *Server) RemoveChannel(channel *Channel) {
// Remove the channel itself // Remove the channel itself
parent := channel.parent parent := channel.parent
delete(parent.children, channel.Id) delete(parent.children, channel.ID)
delete(server.Channels, channel.Id) delete(server.Channels, channel.ID)
chanremove := &mumbleproto.ChannelRemove{ chanremove := &mumbleproto.ChannelRemove{
ChannelId: proto.Uint32(uint32(channel.Id)), ChannelId: proto.Uint32(uint32(channel.ID)),
} }
if err := server.broadcastProtoMessage(chanremove); err != nil { if err := server.broadcastProtoMessage(chanremove); err != nil {
server.Panicf("%v", err) server.Panicf("%v", err)
@ -1261,7 +1270,7 @@ func (server *Server) IsCertHashBanned(hash string) bool {
return false return false
} }
// Filter incoming text according to the server's current rules. // FilterText filters incoming text according to the server's current rules.
func (server *Server) FilterText(text string) (filtered string, err error) { func (server *Server) FilterText(text string) (filtered string, err error) {
options := &htmlfilter.Options{ options := &htmlfilter.Options{
StripHTML: !server.cfg.BoolValue("AllowHTML"), StripHTML: !server.cfg.BoolValue("AllowHTML"),
@ -1353,7 +1362,7 @@ func (server *Server) cleanPerLaunchData() {
func (server *Server) Port() int { func (server *Server) Port() int {
port := server.cfg.IntValue("Port") port := server.cfg.IntValue("Port")
if port == 0 { if port == 0 {
return DefaultPort + int(server.Id) - 1 return DefaultPort + int(server.ID) - 1
} }
return port return port
} }
@ -1363,7 +1372,7 @@ func (server *Server) Port() int {
func (server *Server) WebPort() int { func (server *Server) WebPort() int {
port := server.cfg.IntValue("WebPort") port := server.cfg.IntValue("WebPort")
if port == 0 { if port == 0 {
return DefaultWebPort + int(server.Id) - 1 return DefaultWebPort + int(server.ID) - 1
} }
return port return port
} }

View file

@ -15,6 +15,7 @@ import (
"mumble.info/grumble/pkg/logtarget" "mumble.info/grumble/pkg/logtarget"
) )
// SignalHandler manages signals on Unix like systems
func SignalHandler() { func SignalHandler() {
sigchan := make(chan os.Signal, 10) sigchan := make(chan os.Signal, 10)
signal.Notify(sigchan, syscall.SIGUSR2, syscall.SIGTERM, syscall.SIGINT) signal.Notify(sigchan, syscall.SIGUSR2, syscall.SIGTERM, syscall.SIGINT)

View file

@ -13,19 +13,20 @@ import (
// //
// Users are registered clients on the server. // Users are registered clients on the server.
// User contains all user information
type User struct { type User struct {
Id uint32 ID uint32
Name string Name string
Password string Password string
CertHash string CertHash string
Email string Email string
TextureBlob string TextureBlob string
CommentBlob string CommentBlob string
LastChannelId int LastChannelID int
LastActive uint64 LastActive uint64
} }
// Create a new User // NewUser will create a new User
func NewUser(id uint32, name string) (user *User, err error) { func NewUser(id uint32, name string) (user *User, err error) {
if id < 0 { if id < 0 {
return nil, errors.New("Invalid user id") return nil, errors.New("Invalid user id")
@ -35,12 +36,12 @@ func NewUser(id uint32, name string) (user *User, err error) {
} }
return &User{ return &User{
Id: id, ID: id,
Name: name, Name: name,
}, nil }, nil
} }
// HasComment Does the channel have comment? // HasComment checks whether the channel have comment?
func (user *User) HasComment() bool { func (user *User) HasComment() bool {
return len(user.CommentBlob) > 0 return len(user.CommentBlob) > 0
} }

View file

@ -6,7 +6,7 @@ package main
import "mumble.info/grumble/pkg/acl" import "mumble.info/grumble/pkg/acl"
// A VoiceTarget holds information about a single // VoiceTarget holds information about a single
// VoiceTarget entry of a Client. // VoiceTarget entry of a Client.
type VoiceTarget struct { type VoiceTarget struct {
sessions []uint32 sessions []uint32
@ -23,7 +23,7 @@ type voiceTargetChannel struct {
onlyGroup string onlyGroup string
} }
// Add's a client's session to the VoiceTarget // AddSession adds a client's session to the VoiceTarget
func (vt *VoiceTarget) AddSession(session uint32) { func (vt *VoiceTarget) AddSession(session uint32) {
vt.sessions = append(vt.sessions, session) vt.sessions = append(vt.sessions, session)
} }
@ -53,7 +53,7 @@ func (vt *VoiceTarget) ClearCache() {
vt.fromChannelsCache = nil vt.fromChannelsCache = nil
} }
// Send the contents of the VoiceBroadcast to all targets specified in the // SendVoiceBroadcast will send the contents of the VoiceBroadcast to all targets specified in the
// VoiceTarget. // VoiceTarget.
func (vt *VoiceTarget) SendVoiceBroadcast(vb *VoiceBroadcast) { func (vt *VoiceTarget) SendVoiceBroadcast(vb *VoiceBroadcast) {
buf := vb.buf buf := vb.buf
@ -85,7 +85,7 @@ func (vt *VoiceTarget) SendVoiceBroadcast(vb *VoiceBroadcast) {
if vtc.links { if vtc.links {
newchans = channel.AllLinks() newchans = channel.AllLinks()
} else { } else {
newchans[channel.Id] = channel newchans[channel.ID] = channel
} }
if vtc.subChannels { if vtc.subChannels {
subchans := channel.AllSubChannels() subchans := channel.AllSubChannels()

View file

@ -4,8 +4,8 @@
package acl package acl
// Per-channel permissions
const ( const (
// Per-channel permissions
NonePermission = 0x0 NonePermission = 0x0
WritePermission = 0x1 WritePermission = 0x1
TraversePermission = 0x2 TraversePermission = 0x2
@ -54,7 +54,7 @@ func (perm Permission) Clean() Permission {
type ACL struct { type ACL struct {
// The user id that this ACL applied to. If this // The user id that this ACL applied to. If this
// field is -1, the ACL is a group ACL. // field is -1, the ACL is a group ACL.
UserId int UserID int
// The group that this ACL applies to. // The group that this ACL applies to.
Group string Group string
@ -75,7 +75,7 @@ type ACL struct {
// IsUserACL returns true if the ACL is defined for a user, // IsUserACL returns true if the ACL is defined for a user,
// as opposed to a group. // as opposed to a group.
func (acl *ACL) IsUserACL() bool { func (acl *ACL) IsUserACL() bool {
return acl.UserId != -1 return acl.UserID != -1
} }
// IsChannelACL returns true if the ACL is defined for a group, // IsChannelACL returns true if the ACL is defined for a group,
@ -93,7 +93,7 @@ func HasPermission(ctx *Context, user User, perm Permission) bool {
} }
// 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 { if perm == SpeakPermission || perm == WhisperPermission {
return false return false
} }
@ -125,7 +125,7 @@ func HasPermission(ctx *Context, user User, perm Permission) bool {
// If it's a group ACL, we have to parse and interpret // If it's 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()
matchGroup := GroupMemberCheck(origCtx, ctx, acl.Group, user) matchGroup := GroupMemberCheck(origCtx, ctx, acl.Group, user)
if matchUser || matchGroup { if matchUser || matchGroup {
if acl.Allow.isSet(TraversePermission) { if acl.Allow.isSet(TraversePermission) {
@ -161,9 +161,7 @@ func HasPermission(ctx *Context, user User, perm Permission) bool {
// permissions exccept SpeakPermission and WhisperPermission. // permissions exccept SpeakPermission and WhisperPermission.
if perm != SpeakPermission && perm != WhisperPermission { if perm != SpeakPermission && perm != WhisperPermission {
return (granted & (perm | WritePermission)) != NonePermission return (granted & (perm | WritePermission)) != NonePermission
} else {
return (granted & perm) != NonePermission
} }
return false return (granted & perm) != NonePermission
} }

View file

@ -1,6 +1,7 @@
// Copyright (c) 2010-2013 The Grumble Authors // Copyright (c) 2010-2013 The Grumble Authors
// The use of this source code is goverened by a BSD-style // The use of this source code is goverened by a BSD-style
// license that can be found in the LICENSE-file. // license that can be found in the LICENSE-file.
package acl package acl
import ( import (
@ -49,7 +50,7 @@ func (group *Group) AddContains(id int) (ok bool) {
// AddUsers gets the list of user ids in the Add set. // AddUsers gets the list of user ids in the Add set.
func (group *Group) AddUsers() []int { func (group *Group) AddUsers() []int {
users := []int{} users := []int{}
for uid, _ := range group.Add { for uid := range group.Add {
users = append(users, uid) users = append(users, uid)
} }
return users return users
@ -64,7 +65,7 @@ func (group *Group) RemoveContains(id int) (ok bool) {
// RemoveUsers gets the list of user ids in the Remove set. // RemoveUsers gets the list of user ids in the Remove set.
func (group *Group) RemoveUsers() []int { func (group *Group) RemoveUsers() []int {
users := []int{} users := []int{}
for uid, _ := range group.Remove { for uid := range group.Remove {
users = append(users, uid) users = append(users, uid)
} }
return users return users
@ -105,10 +106,10 @@ func (group *Group) MembersInContext(ctx *Context) map[int]bool {
} }
for _, curgroup := range groups { for _, curgroup := range groups {
for uid, _ := range curgroup.Add { for uid := range curgroup.Add {
members[uid] = true members[uid] = true
} }
for uid, _ := range curgroup.Remove { for uid := range curgroup.Remove {
delete(members, uid) delete(members, uid)
} }
} }
@ -200,8 +201,8 @@ func GroupMemberCheck(current *Context, acl *Context, name string, user User) (o
return true return true
} else if name == "auth" { } else if name == "auth" {
// The user is part of the auth group is he is authenticated. That is, // The user is part of the auth group is he is authenticated. That is,
// his UserId is >= 0. // his UserID is >= 0.
return user.UserId() >= 0 return user.UserID() >= 0
} else if name == "strong" { } else if name == "strong" {
// The user is part of the strong group if he is authenticated to the server // The user is part of the strong group if he is authenticated to the server
// via a strong certificate (i.e. non-self-signed, trusted by the server's // via a strong certificate (i.e. non-self-signed, trusted by the server's
@ -298,42 +299,40 @@ func GroupMemberCheck(current *Context, acl *Context, name string, user User) (o
pdepth := len(userChain) - 1 pdepth := len(userChain) - 1
return pdepth >= mindepth && pdepth <= maxdepth return pdepth >= mindepth && pdepth <= maxdepth
} else {
// Non-magic groups
groups := []Group{}
iter := channel
for iter != nil {
if group, ok := iter.Groups[name]; ok {
// Skip non-inheritable groups if we're in parents
// of our evaluated context.
if iter != channel && !group.Inheritable {
break
}
// Prepend group
groups = append([]Group{group}, groups...)
// If this group does not inherit from groups in its ancestors, stop looking
// for more ancestor groups.
if !group.Inherit {
break
}
}
iter = iter.Parent
}
isMember := false
for _, group := range groups {
if group.AddContains(user.UserId()) || group.TemporaryContains(user.UserId()) || group.TemporaryContains(-int(user.Session())) {
isMember = true
}
if group.RemoveContains(user.UserId()) {
isMember = false
}
}
return isMember
} }
return false // Non-magic groups
groups := []Group{}
iter := channel
for iter != nil {
if group, ok := iter.Groups[name]; ok {
// Skip non-inheritable groups if we're in parents
// of our evaluated context.
if iter != channel && !group.Inheritable {
break
}
// Prepend group
groups = append([]Group{group}, groups...)
// If this group does not inherit from groups in its ancestors, stop looking
// for more ancestor groups.
if !group.Inherit {
break
}
}
iter = iter.Parent
}
isMember := false
for _, group := range groups {
if group.AddContains(user.UserID()) || group.TemporaryContains(user.UserID()) || group.TemporaryContains(-int(user.Session())) {
isMember = true
}
if group.RemoveContains(user.UserID()) {
isMember = false
}
}
return isMember
} }
// GroupNames gets the list of group names for the given ACL context. // GroupNames gets the list of group names for the given ACL context.

View file

@ -10,7 +10,7 @@ package acl
// permissions in an ACL context. // permissions in an ACL context.
type User interface { type User interface {
Session() uint32 Session() uint32
UserId() int UserID() int
CertHash() string CertHash() string
Tokens() []string Tokens() []string

View file

@ -10,9 +10,11 @@ import (
) )
const ( const (
// ISODate represents ISO 8601 formatting
ISODate = "2006-01-02T15:04:05" ISODate = "2006-01-02T15:04:05"
) )
// Ban contains information about a specific ban
type Ban struct { type Ban struct {
IP net.IP IP net.IP
Mask int Mask int
@ -23,7 +25,7 @@ type Ban struct {
Duration uint32 Duration uint32
} }
// Create a net.IPMask from a specified amount of mask bits // IPMask creates a net.IPMask from a specified amount of mask bits
func (ban Ban) IPMask() (mask net.IPMask) { func (ban Ban) IPMask() (mask net.IPMask) {
allbits := ban.Mask allbits := ban.Mask
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
@ -48,7 +50,7 @@ func (ban Ban) Match(ip net.IP) bool {
return banned.Equal(masked) return banned.Equal(masked)
} }
// Set Start date from an ISO 8601 date (in UTC) // SetISOStartDate sets Start date from an ISO 8601 date (in UTC)
func (ban *Ban) SetISOStartDate(isodate string) { func (ban *Ban) SetISOStartDate(isodate string) {
startTime, err := time.Parse(ISODate, isodate) startTime, err := time.Parse(ISODate, isodate)
if err != nil { if err != nil {

View file

@ -33,12 +33,12 @@ func TestMatchV4(t *testing.T) {
t.Errorf("Invalid IP") t.Errorf("Invalid IP")
} }
clientIp := net.ParseIP("192.168.1.50") clientIP := net.ParseIP("192.168.1.50")
if len(clientIp) == 0 { if len(clientIP) == 0 {
t.Errorf("Invalid IP") t.Errorf("Invalid IP")
} }
if b.Match(clientIp) != true { if b.Match(clientIP) != true {
t.Errorf("IPv4: unexpected match") t.Errorf("IPv4: unexpected match")
} }
} }
@ -51,12 +51,12 @@ func TestMismatchV4(t *testing.T) {
t.Errorf("Invalid IP") t.Errorf("Invalid IP")
} }
clientIp := net.ParseIP("192.168.2.1") clientIP := net.ParseIP("192.168.2.1")
if len(clientIp) == 0 { if len(clientIP) == 0 {
t.Errorf("Invalid IP") t.Errorf("Invalid IP")
} }
if b.Match(clientIp) == true { if b.Match(clientIP) == true {
t.Errorf("IPv4: unexpected mismatch") t.Errorf("IPv4: unexpected mismatch")
} }
} }
@ -69,12 +69,12 @@ func TestMatchV6(t *testing.T) {
t.Errorf("Invalid IP") t.Errorf("Invalid IP")
} }
clientIp := net.ParseIP("2a00:1450:400b:c00::54") clientIP := net.ParseIP("2a00:1450:400b:c00::54")
if len(clientIp) == 0 { if len(clientIP) == 0 {
t.Errorf("Invalid IP") t.Errorf("Invalid IP")
} }
if b.Match(clientIp) != true { if b.Match(clientIP) != true {
t.Errorf("IPv6: unexpected match") t.Errorf("IPv6: unexpected match")
} }
} }
@ -88,12 +88,12 @@ func TestMismatchV6(t *testing.T) {
t.Errorf("Invalid IP") t.Errorf("Invalid IP")
} }
clientIp := net.ParseIP("2a00:1450:400b:deaf:42f0:cafe:babe:54") clientIP := net.ParseIP("2a00:1450:400b:deaf:42f0:cafe:babe:54")
if len(clientIp) == 0 { if len(clientIP) == 0 {
t.Errorf("Invalid IP") t.Errorf("Invalid IP")
} }
if b.Match(clientIp) == true { if b.Match(clientIP) == true {
t.Errorf("IPv6: unexpected mismatch") t.Errorf("IPv6: unexpected mismatch")
} }
} }

View file

@ -2,7 +2,7 @@
// The use of this source code is goverened by a BSD-style // The use of this source code is goverened by a BSD-style
// license that can be found in the LICENSE-file. // license that can be found in the LICENSE-file.
// This package implements a simple disk-persisted content-addressed blobstore. // Package blobstore implements a simple disk-persisted content-addressed blobstore.
package blobstore package blobstore
import ( import (

View file

@ -13,6 +13,7 @@ import (
const decryptHistorySize = 0x100 const decryptHistorySize = 0x100
// CryptoMode represents a specific cryptographic mode
type CryptoMode interface { type CryptoMode interface {
NonceSize() int NonceSize() int
KeySize() int KeySize() int
@ -23,6 +24,7 @@ type CryptoMode interface {
Decrypt(dst []byte, src []byte, nonce []byte) bool Decrypt(dst []byte, src []byte, nonce []byte) bool
} }
// CryptState represents the current state of a cryptographic operation
type CryptState struct { type CryptState struct {
Key []byte Key []byte
EncryptIV []byte EncryptIV []byte
@ -62,6 +64,7 @@ func createMode(mode string) (CryptoMode, error) {
return nil, errors.New("cryptstate: no such CryptoMode") return nil, errors.New("cryptstate: no such CryptoMode")
} }
// GenerateKey will generate a key for the specific mode
func (cs *CryptState) GenerateKey(mode string) error { func (cs *CryptState) GenerateKey(mode string) error {
cm, err := createMode(mode) cm, err := createMode(mode)
if err != nil { if err != nil {
@ -93,6 +96,7 @@ func (cs *CryptState) GenerateKey(mode string) error {
return nil return nil
} }
// SetKey will set the cryptographic key for a specific mode
func (cs *CryptState) SetKey(mode string, key []byte, eiv []byte, div []byte) error { func (cs *CryptState) SetKey(mode string, key []byte, eiv []byte, div []byte) error {
cm, err := createMode(mode) cm, err := createMode(mode)
if err != nil { if err != nil {
@ -115,13 +119,14 @@ func (cs *CryptState) Overhead() int {
return 1 + cs.mode.Overhead() return 1 + cs.mode.Overhead()
} }
// Decrypt decrypts the source into the destination
func (cs *CryptState) Decrypt(dst, src []byte) error { func (cs *CryptState) Decrypt(dst, src []byte) error {
if len(src) < cs.Overhead() { if len(src) < cs.Overhead() {
return errors.New("cryptstate: crypted length too short to decrypt") return errors.New("cryptstate: crypted length too short to decrypt")
} }
plain_len := len(src) - cs.Overhead() plainLen := len(src) - cs.Overhead()
if len(dst) < plain_len { if len(dst) < plainLen {
return errors.New("cryptstate: not enough space in dst for plain text") return errors.New("cryptstate: not enough space in dst for plain text")
} }
@ -140,7 +145,7 @@ func (cs *CryptState) Decrypt(dst, src []byte) error {
} else if ivbyte < cs.DecryptIV[0] { } else if ivbyte < cs.DecryptIV[0] {
cs.DecryptIV[0] = ivbyte cs.DecryptIV[0] = ivbyte
for i := 1; i < len(cs.DecryptIV); i++ { for i := 1; i < len(cs.DecryptIV); i++ {
cs.DecryptIV[i] += 1 cs.DecryptIV[i]++
if cs.DecryptIV[i] > 0 { if cs.DecryptIV[i] > 0 {
break break
} }
@ -170,7 +175,7 @@ func (cs *CryptState) Decrypt(dst, src []byte) error {
lost = -1 lost = -1
cs.DecryptIV[0] = ivbyte cs.DecryptIV[0] = ivbyte
for i := 1; i < len(cs.DecryptIV); i++ { for i := 1; i < len(cs.DecryptIV); i++ {
cs.DecryptIV[i] -= 1 cs.DecryptIV[i]--
if cs.DecryptIV[i] > 0 { if cs.DecryptIV[i] > 0 {
break break
} }
@ -185,7 +190,7 @@ func (cs *CryptState) Decrypt(dst, src []byte) error {
lost = int(256 - int(cs.DecryptIV[0]) + int(ivbyte) - 1) lost = int(256 - int(cs.DecryptIV[0]) + int(ivbyte) - 1)
cs.DecryptIV[0] = ivbyte cs.DecryptIV[0] = ivbyte
for i := 1; i < len(cs.DecryptIV); i++ { for i := 1; i < len(cs.DecryptIV); i++ {
cs.DecryptIV[i] += 1 cs.DecryptIV[i]++
if cs.DecryptIV[i] > 0 { if cs.DecryptIV[i] > 0 {
break break
} }
@ -211,7 +216,7 @@ func (cs *CryptState) Decrypt(dst, src []byte) error {
cs.DecryptIV = saveiv cs.DecryptIV = saveiv
} }
cs.Good += 1 cs.Good++
if late > 0 { if late > 0 {
cs.Late += uint32(late) cs.Late += uint32(late)
} else { } else {
@ -228,10 +233,11 @@ func (cs *CryptState) Decrypt(dst, src []byte) error {
return nil return nil
} }
// Encrypt will encrypt the source into the destination
func (cs *CryptState) Encrypt(dst, src []byte) { func (cs *CryptState) Encrypt(dst, src []byte) {
// First, increase our IV // First, increase our IV
for i := range cs.EncryptIV { for i := range cs.EncryptIV {
cs.EncryptIV[i] += 1 cs.EncryptIV[i]++
if cs.EncryptIV[i] > 0 { if cs.EncryptIV[i] > 0 {
break break
} }

View file

@ -27,7 +27,7 @@ func TestOCB2AES128Encrypt(t *testing.T) {
expected := [19]byte{ expected := [19]byte{
0x1f, 0xfc, 0xdd, 0xb4, 0x68, 0x13, 0x68, 0xb7, 0x92, 0x67, 0xca, 0x2d, 0xba, 0xb7, 0x0d, 0x44, 0xdf, 0x32, 0xd4, 0x1f, 0xfc, 0xdd, 0xb4, 0x68, 0x13, 0x68, 0xb7, 0x92, 0x67, 0xca, 0x2d, 0xba, 0xb7, 0x0d, 0x44, 0xdf, 0x32, 0xd4,
} }
expected_eiv := [aes.BlockSize]byte{ expectedEiv := [aes.BlockSize]byte{
0x1f, 0x2a, 0x9b, 0xd0, 0x2d, 0xa6, 0x8e, 0x46, 0x26, 0x85, 0x83, 0xe9, 0x14, 0x2a, 0xff, 0x2a, 0x1f, 0x2a, 0x9b, 0xd0, 0x2d, 0xa6, 0x8e, 0x46, 0x26, 0x85, 0x83, 0xe9, 0x14, 0x2a, 0xff, 0x2a,
} }
@ -40,7 +40,7 @@ func TestOCB2AES128Encrypt(t *testing.T) {
t.Errorf("Mismatch in output") t.Errorf("Mismatch in output")
} }
if !bytes.Equal(cs.EncryptIV[:], expected_eiv[:]) { if !bytes.Equal(cs.EncryptIV[:], expectedEiv[:]) {
t.Errorf("EIV mismatch") t.Errorf("EIV mismatch")
} }
} }
@ -61,7 +61,7 @@ func TestOCB2AES128Decrypt(t *testing.T) {
expected := [15]byte{ expected := [15]byte{
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
} }
post_div := [aes.BlockSize]byte{ postDiv := [aes.BlockSize]byte{
0x1f, 0x2a, 0x9b, 0xd0, 0x2d, 0xa6, 0x8e, 0x46, 0x26, 0x85, 0x83, 0xe9, 0x14, 0x2a, 0xff, 0x2a, 0x1f, 0x2a, 0x9b, 0xd0, 0x2d, 0xa6, 0x8e, 0x46, 0x26, 0x85, 0x83, 0xe9, 0x14, 0x2a, 0xff, 0x2a,
} }
@ -77,7 +77,7 @@ func TestOCB2AES128Decrypt(t *testing.T) {
t.Errorf("Mismatch in output") t.Errorf("Mismatch in output")
} }
if !bytes.Equal(cs.DecryptIV, post_div[:]) { if !bytes.Equal(cs.DecryptIV, postDiv[:]) {
t.Errorf("Mismatch in DIV") t.Errorf("Mismatch in DIV")
} }
} }

View file

@ -147,7 +147,7 @@ func TestLogging(t *testing.T) {
if !proto.Equal(val, testValues[i]) { if !proto.Equal(val, testValues[i]) {
t.Error("proto message mismatch") t.Error("proto message mismatch")
} }
i += 1 i++
} }
} }

View file

@ -6,6 +6,7 @@ package freezer
type typeKind uint32 type typeKind uint32
// The different types of data that can be frozen
const ( const (
ServerType typeKind = iota ServerType typeKind = iota
ConfigKeyValuePairType ConfigKeyValuePairType

View file

@ -137,7 +137,7 @@ type User struct {
Email *string `protobuf:"bytes,5,opt,name=email" json:"email,omitempty"` Email *string `protobuf:"bytes,5,opt,name=email" json:"email,omitempty"`
TextureBlob *string `protobuf:"bytes,6,opt,name=texture_blob" json:"texture_blob,omitempty"` TextureBlob *string `protobuf:"bytes,6,opt,name=texture_blob" json:"texture_blob,omitempty"`
CommentBlob *string `protobuf:"bytes,7,opt,name=comment_blob" json:"comment_blob,omitempty"` CommentBlob *string `protobuf:"bytes,7,opt,name=comment_blob" json:"comment_blob,omitempty"`
LastChannelId *uint32 `protobuf:"varint,8,opt,name=last_channel_id" json:"last_channel_id,omitempty"` LastChannelID *uint32 `protobuf:"varint,8,opt,name=last_channel_id" json:"last_channel_id,omitempty"`
LastActive *uint64 `protobuf:"varint,9,opt,name=last_active" json:"last_active,omitempty"` LastActive *uint64 `protobuf:"varint,9,opt,name=last_active" json:"last_active,omitempty"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
} }
@ -195,9 +195,9 @@ func (this *User) GetCommentBlob() string {
return "" return ""
} }
func (this *User) GetLastChannelId() uint32 { func (this *User) GetLastChannelID() uint32 {
if this != nil && this.LastChannelId != nil { if this != nil && this.LastChannelID != nil {
return *this.LastChannelId return *this.LastChannelID
} }
return 0 return 0
} }
@ -230,9 +230,9 @@ type Channel struct {
Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
ParentId *uint32 `protobuf:"varint,3,opt,name=parent_id" json:"parent_id,omitempty"` ParentId *uint32 `protobuf:"varint,3,opt,name=parent_id" json:"parent_id,omitempty"`
Position *int64 `protobuf:"varint,4,opt,name=position" json:"position,omitempty"` Position *int64 `protobuf:"varint,4,opt,name=position" json:"position,omitempty"`
InheritAcl *bool `protobuf:"varint,5,opt,name=inherit_acl" json:"inherit_acl,omitempty"` InheritACL *bool `protobuf:"varint,5,opt,name=inherit_acl" json:"inherit_acl,omitempty"`
Links []uint32 `protobuf:"varint,6,rep,name=links" json:"links,omitempty"` Links []uint32 `protobuf:"varint,6,rep,name=links" json:"links,omitempty"`
Acl []*ACL `protobuf:"bytes,7,rep,name=acl" json:"acl,omitempty"` ACL []*ACL `protobuf:"bytes,7,rep,name=acl" json:"acl,omitempty"`
Groups []*Group `protobuf:"bytes,8,rep,name=groups" json:"groups,omitempty"` Groups []*Group `protobuf:"bytes,8,rep,name=groups" json:"groups,omitempty"`
DescriptionBlob *string `protobuf:"bytes,9,opt,name=description_blob" json:"description_blob,omitempty"` DescriptionBlob *string `protobuf:"bytes,9,opt,name=description_blob" json:"description_blob,omitempty"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
@ -270,9 +270,9 @@ func (this *Channel) GetPosition() int64 {
return 0 return 0
} }
func (this *Channel) GetInheritAcl() bool { func (this *Channel) GetInheritACL() bool {
if this != nil && this.InheritAcl != nil { if this != nil && this.InheritACL != nil {
return *this.InheritAcl return *this.InheritACL
} }
return false return false
} }
@ -301,7 +301,7 @@ func (this *ChannelRemove) GetId() uint32 {
} }
type ACL struct { type ACL struct {
UserId *uint32 `protobuf:"varint,1,opt,name=user_id" json:"user_id,omitempty"` UserID *uint32 `protobuf:"varint,1,opt,name=user_id" json:"user_id,omitempty"`
Group *string `protobuf:"bytes,2,opt,name=group" json:"group,omitempty"` Group *string `protobuf:"bytes,2,opt,name=group" json:"group,omitempty"`
ApplyHere *bool `protobuf:"varint,3,opt,name=apply_here" json:"apply_here,omitempty"` ApplyHere *bool `protobuf:"varint,3,opt,name=apply_here" json:"apply_here,omitempty"`
ApplySubs *bool `protobuf:"varint,4,opt,name=apply_subs" json:"apply_subs,omitempty"` ApplySubs *bool `protobuf:"varint,4,opt,name=apply_subs" json:"apply_subs,omitempty"`
@ -314,9 +314,9 @@ func (this *ACL) Reset() { *this = ACL{} }
func (this *ACL) String() string { return proto.CompactTextString(this) } func (this *ACL) String() string { return proto.CompactTextString(this) }
func (*ACL) ProtoMessage() {} func (*ACL) ProtoMessage() {}
func (this *ACL) GetUserId() uint32 { func (this *ACL) GetUserID() uint32 {
if this != nil && this.UserId != nil { if this != nil && this.UserID != nil {
return *this.UserId return *this.UserID
} }
return 0 return 0
} }

View file

@ -23,14 +23,14 @@ func isEOF(err error) bool {
return false return false
} }
// Type Walker implements a method for // Walker implements a method for
// iterating the transaction groups of an // iterating the transaction groups of an
// immutable Log. // immutable Log.
type Walker struct { type Walker struct {
r io.Reader r io.Reader
} }
// Type txReader imlpements a checksumming reader, intended // txReader imlpements a checksumming reader, intended
// for reading transaction groups of a Log. // for reading transaction groups of a Log.
// //
// Besides auto-checksumming the read content, it also // Besides auto-checksumming the read content, it also
@ -79,7 +79,7 @@ func (txr *txReader) Consumed() int {
return txr.consumed return txr.consumed
} }
// Create a new Walker that iterates over the log entries of a given Reader. // NewReaderWalker creates a new Walker that iterates over the log entries of a given Reader.
func NewReaderWalker(r io.Reader) (walker *Walker, err error) { func NewReaderWalker(r io.Reader) (walker *Walker, err error) {
walker = new(Walker) walker = new(Walker)
walker.r = r walker.r = r
@ -224,7 +224,7 @@ func (walker *Walker) Next() (entries []interface{}, err error) {
entries = append(entries, channelRemove) entries = append(entries, channelRemove)
} }
remainOps -= 1 remainOps--
continue continue
} }

View file

@ -41,7 +41,7 @@ type Log struct {
wc io.WriteCloser wc io.WriteCloser
} }
// Type LogTx represents a transaction in the log. // LogTx represents a transaction in the log.
// Transactions can be used to group several changes into an // Transactions can be used to group several changes into an
// atomic entity in the log file. // atomic entity in the log file.
type LogTx struct { type LogTx struct {
@ -51,7 +51,7 @@ type LogTx struct {
numops int numops int
} }
// Create a new log file // NewLogFile creates a new log file
func NewLogFile(fn string) (*Log, error) { func NewLogFile(fn string) (*Log, error) {
f, err := os.Create(fn) f, err := os.Create(fn)
if err != nil { if err != nil {
@ -69,7 +69,7 @@ func (log *Log) Close() error {
return log.wc.Close() return log.wc.Close()
} }
// Append a log entry // Put will append a log entry
// //
// This method implicitly creates a transaction // This method implicitly creates a transaction
// group for this single Put operation. It is merely // group for this single Put operation. It is merely
@ -83,7 +83,7 @@ func (log *Log) Put(value interface{}) (err error) {
return tx.Commit() return tx.Commit()
} }
// Begin a transaction // BeginTx begins a transaction
func (log *Log) BeginTx() *LogTx { func (log *Log) BeginTx() *LogTx {
tx := &LogTx{} tx := &LogTx{}
tx.log = log tx.log = log
@ -92,7 +92,7 @@ func (log *Log) BeginTx() *LogTx {
return tx return tx
} }
// Append a log entry to the transaction. // Put will append a log entry to the transaction.
// The transaction's log entries will not be persisted to // The transaction's log entries will not be persisted to
// the log until the Commit has been called on the transaction. // the log until the Commit has been called on the transaction.
func (tx *LogTx) Put(value interface{}) (err error) { func (tx *LogTx) Put(value interface{}) (err error) {
@ -156,7 +156,7 @@ func (tx *LogTx) Put(value interface{}) (err error) {
return err return err
} }
tx.numops += 1 tx.numops++
return nil return nil
} }

View file

@ -12,6 +12,7 @@ import (
"strings" "strings"
) )
// Options contains the different possible HTML filtering options
type Options struct { type Options struct {
StripHTML bool StripHTML bool
MaxTextMessageLength int MaxTextMessageLength int
@ -24,6 +25,7 @@ var defaultOptions Options = Options{
MaxImageMessageLength: 1024 * 1024, MaxImageMessageLength: 1024 * 1024,
} }
// Errors that can happen in this module
var ( var (
ErrExceedsTextMessageLength = errors.New("Exceeds text message length") ErrExceedsTextMessageLength = errors.New("Exceeds text message length")
ErrExceedsImageMessageLength = errors.New("Exceeds image message length") ErrExceedsImageMessageLength = errors.New("Exceeds image message length")

View file

@ -22,6 +22,7 @@ type LogTarget struct {
memLog *bytes.Buffer memLog *bytes.Buffer
} }
// Target is the current log target
var Target LogTarget var Target LogTarget
// Write writes a log message to all registered io.Writers // Write writes a log message to all registered io.Writers

View file

@ -410,17 +410,17 @@ type Ping struct {
// The amount of nonce resyncs. // The amount of nonce resyncs.
Resync *uint32 `protobuf:"varint,5,opt,name=resync" json:"resync,omitempty"` Resync *uint32 `protobuf:"varint,5,opt,name=resync" json:"resync,omitempty"`
// The total amount of UDP packets received. // The total amount of UDP packets received.
UdpPackets *uint32 `protobuf:"varint,6,opt,name=udp_packets,json=udpPackets" json:"udp_packets,omitempty"` UDPPackets *uint32 `protobuf:"varint,6,opt,name=udp_packets,json=udpPackets" json:"udp_packets,omitempty"`
// The total amount of TCP packets received. // The total amount of TCP packets received.
TcpPackets *uint32 `protobuf:"varint,7,opt,name=tcp_packets,json=tcpPackets" json:"tcp_packets,omitempty"` TCPPackets *uint32 `protobuf:"varint,7,opt,name=tcp_packets,json=tcpPackets" json:"tcp_packets,omitempty"`
// UDP ping average. // UDP ping average.
UdpPingAvg *float32 `protobuf:"fixed32,8,opt,name=udp_ping_avg,json=udpPingAvg" json:"udp_ping_avg,omitempty"` UDPPingAvg *float32 `protobuf:"fixed32,8,opt,name=udp_ping_avg,json=udpPingAvg" json:"udp_ping_avg,omitempty"`
// UDP ping variance. // UDP ping variance.
UdpPingVar *float32 `protobuf:"fixed32,9,opt,name=udp_ping_var,json=udpPingVar" json:"udp_ping_var,omitempty"` UDPPingVar *float32 `protobuf:"fixed32,9,opt,name=udp_ping_var,json=udpPingVar" json:"udp_ping_var,omitempty"`
// TCP ping average. // TCP ping average.
TcpPingAvg *float32 `protobuf:"fixed32,10,opt,name=tcp_ping_avg,json=tcpPingAvg" json:"tcp_ping_avg,omitempty"` TCPPingAvg *float32 `protobuf:"fixed32,10,opt,name=tcp_ping_avg,json=tcpPingAvg" json:"tcp_ping_avg,omitempty"`
// TCP ping variance. // TCP ping variance.
TcpPingVar *float32 `protobuf:"fixed32,11,opt,name=tcp_ping_var,json=tcpPingVar" json:"tcp_ping_var,omitempty"` TCPPingVar *float32 `protobuf:"fixed32,11,opt,name=tcp_ping_var,json=tcpPingVar" json:"tcp_ping_var,omitempty"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
} }
@ -464,44 +464,44 @@ func (m *Ping) GetResync() uint32 {
return 0 return 0
} }
func (m *Ping) GetUdpPackets() uint32 { func (m *Ping) GetUDPPackets() uint32 {
if m != nil && m.UdpPackets != nil { if m != nil && m.UDPPackets != nil {
return *m.UdpPackets return *m.UDPPackets
} }
return 0 return 0
} }
func (m *Ping) GetTcpPackets() uint32 { func (m *Ping) GetTCPPackets() uint32 {
if m != nil && m.TcpPackets != nil { if m != nil && m.TCPPackets != nil {
return *m.TcpPackets return *m.TCPPackets
} }
return 0 return 0
} }
func (m *Ping) GetUdpPingAvg() float32 { func (m *Ping) GetUDPPingAvg() float32 {
if m != nil && m.UdpPingAvg != nil { if m != nil && m.UDPPingAvg != nil {
return *m.UdpPingAvg return *m.UDPPingAvg
} }
return 0 return 0
} }
func (m *Ping) GetUdpPingVar() float32 { func (m *Ping) GetUDPPingVar() float32 {
if m != nil && m.UdpPingVar != nil { if m != nil && m.UDPPingVar != nil {
return *m.UdpPingVar return *m.UDPPingVar
} }
return 0 return 0
} }
func (m *Ping) GetTcpPingAvg() float32 { func (m *Ping) GetTCPPingAvg() float32 {
if m != nil && m.TcpPingAvg != nil { if m != nil && m.TCPPingAvg != nil {
return *m.TcpPingAvg return *m.TCPPingAvg
} }
return 0 return 0
} }
func (m *Ping) GetTcpPingVar() float32 { func (m *Ping) GetTCPPingVar() float32 {
if m != nil && m.TcpPingVar != nil { if m != nil && m.TCPPingVar != nil {
return *m.TcpPingVar return *m.TCPPingVar
} }
return 0 return 0
} }
@ -780,7 +780,7 @@ type UserState struct {
// User name, UTF-8 encoded. // User name, UTF-8 encoded.
Name *string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` Name *string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"`
// Registered user ID if the user is registered. // Registered user ID if the user is registered.
UserId *uint32 `protobuf:"varint,4,opt,name=user_id,json=userId" json:"user_id,omitempty"` UserID *uint32 `protobuf:"varint,4,opt,name=user_id,json=userId" json:"user_id,omitempty"`
// Channel on which the user is. // Channel on which the user is.
ChannelId *uint32 `protobuf:"varint,5,opt,name=channel_id,json=channelId" json:"channel_id,omitempty"` ChannelId *uint32 `protobuf:"varint,5,opt,name=channel_id,json=channelId" json:"channel_id,omitempty"`
// True if the user is muted by admin. // True if the user is muted by admin.
@ -841,9 +841,9 @@ func (m *UserState) GetName() string {
return "" return ""
} }
func (m *UserState) GetUserId() uint32 { func (m *UserState) GetUserID() uint32 {
if m != nil && m.UserId != nil { if m != nil && m.UserID != nil {
return *m.UserId return *m.UserID
} }
return 0 return 0
} }
@ -1183,11 +1183,11 @@ type ACL struct {
// Channel ID of the channel this message affects. // Channel ID of the channel this message affects.
ChannelId *uint32 `protobuf:"varint,1,req,name=channel_id,json=channelId" json:"channel_id,omitempty"` ChannelId *uint32 `protobuf:"varint,1,req,name=channel_id,json=channelId" json:"channel_id,omitempty"`
// True if the channel inherits its parent's ACLs. // True if the channel inherits its parent's ACLs.
InheritAcls *bool `protobuf:"varint,2,opt,name=inherit_acls,json=inheritAcls,def=1" json:"inherit_acls,omitempty"` InheritACLs *bool `protobuf:"varint,2,opt,name=inherit_acls,json=inheritACLs,def=1" json:"inherit_acls,omitempty"`
// User group specifications. // User group specifications.
Groups []*ACL_ChanGroup `protobuf:"bytes,3,rep,name=groups" json:"groups,omitempty"` Groups []*ACL_ChanGroup `protobuf:"bytes,3,rep,name=groups" json:"groups,omitempty"`
// ACL specifications. // ACL specifications.
Acls []*ACL_ChanACL `protobuf:"bytes,4,rep,name=acls" json:"acls,omitempty"` ACLs []*ACL_ChanACL `protobuf:"bytes,4,rep,name=acls" json:"acls,omitempty"`
// True if the message is a query for ACLs instead of setting them. // True if the message is a query for ACLs instead of setting them.
Query *bool `protobuf:"varint,5,opt,name=query,def=0" json:"query,omitempty"` Query *bool `protobuf:"varint,5,opt,name=query,def=0" json:"query,omitempty"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
@ -1198,7 +1198,7 @@ func (m *ACL) String() string { return proto.CompactTextString(m) }
func (*ACL) ProtoMessage() {} func (*ACL) ProtoMessage() {}
func (*ACL) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } func (*ACL) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
const Default_ACL_InheritAcls bool = true const Default_ACL_InheritACLs bool = true
const Default_ACL_Query bool = false const Default_ACL_Query bool = false
func (m *ACL) GetChannelId() uint32 { func (m *ACL) GetChannelId() uint32 {
@ -1208,11 +1208,11 @@ func (m *ACL) GetChannelId() uint32 {
return 0 return 0
} }
func (m *ACL) GetInheritAcls() bool { func (m *ACL) GetInheritACLs() bool {
if m != nil && m.InheritAcls != nil { if m != nil && m.InheritACLs != nil {
return *m.InheritAcls return *m.InheritACLs
} }
return Default_ACL_InheritAcls return Default_ACL_InheritACLs
} }
func (m *ACL) GetGroups() []*ACL_ChanGroup { func (m *ACL) GetGroups() []*ACL_ChanGroup {
@ -1222,9 +1222,9 @@ func (m *ACL) GetGroups() []*ACL_ChanGroup {
return nil return nil
} }
func (m *ACL) GetAcls() []*ACL_ChanACL { func (m *ACL) GetACLs() []*ACL_ChanACL {
if m != nil { if m != nil {
return m.Acls return m.ACLs
} }
return nil return nil
} }
@ -1321,7 +1321,7 @@ type ACL_ChanACL struct {
// True if the ACL has been inherited from the parent. // True if the ACL has been inherited from the parent.
Inherited *bool `protobuf:"varint,3,opt,name=inherited,def=1" json:"inherited,omitempty"` Inherited *bool `protobuf:"varint,3,opt,name=inherited,def=1" json:"inherited,omitempty"`
// ID of the user that is affected by this ACL. // ID of the user that is affected by this ACL.
UserId *uint32 `protobuf:"varint,4,opt,name=user_id,json=userId" json:"user_id,omitempty"` UserID *uint32 `protobuf:"varint,4,opt,name=user_id,json=userId" json:"user_id,omitempty"`
// ID of the group that is affected by this ACL. // ID of the group that is affected by this ACL.
Group *string `protobuf:"bytes,5,opt,name=group" json:"group,omitempty"` Group *string `protobuf:"bytes,5,opt,name=group" json:"group,omitempty"`
// Bit flag field of the permissions granted by this ACL. // Bit flag field of the permissions granted by this ACL.
@ -1361,9 +1361,9 @@ func (m *ACL_ChanACL) GetInherited() bool {
return Default_ACL_ChanACL_Inherited return Default_ACL_ChanACL_Inherited
} }
func (m *ACL_ChanACL) GetUserId() uint32 { func (m *ACL_ChanACL) GetUserID() uint32 {
if m != nil && m.UserId != nil { if m != nil && m.UserID != nil {
return *m.UserId return *m.UserID
} }
return 0 return 0
} }
@ -1561,7 +1561,7 @@ func (m *UserList) GetUsers() []*UserList_User {
type UserList_User struct { type UserList_User struct {
// Registered user ID. // Registered user ID.
UserId *uint32 `protobuf:"varint,1,req,name=user_id,json=userId" json:"user_id,omitempty"` UserID *uint32 `protobuf:"varint,1,req,name=user_id,json=userId" json:"user_id,omitempty"`
// Registered user name. // Registered user name.
Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` Name *string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
LastSeen *string `protobuf:"bytes,3,opt,name=last_seen,json=lastSeen" json:"last_seen,omitempty"` LastSeen *string `protobuf:"bytes,3,opt,name=last_seen,json=lastSeen" json:"last_seen,omitempty"`
@ -1574,9 +1574,9 @@ func (m *UserList_User) String() string { return proto.CompactTextStr
func (*UserList_User) ProtoMessage() {} func (*UserList_User) ProtoMessage() {}
func (*UserList_User) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18, 0} } func (*UserList_User) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18, 0} }
func (m *UserList_User) GetUserId() uint32 { func (m *UserList_User) GetUserID() uint32 {
if m != nil && m.UserId != nil { if m != nil && m.UserID != nil {
return *m.UserId return *m.UserID
} }
return 0 return 0
} }
@ -1795,17 +1795,17 @@ type UserStats struct {
// Packet statistics for packets sent by the server. // Packet statistics for packets sent by the server.
FromServer *UserStats_Stats `protobuf:"bytes,5,opt,name=from_server,json=fromServer" json:"from_server,omitempty"` FromServer *UserStats_Stats `protobuf:"bytes,5,opt,name=from_server,json=fromServer" json:"from_server,omitempty"`
// Amount of UDP packets sent. // Amount of UDP packets sent.
UdpPackets *uint32 `protobuf:"varint,6,opt,name=udp_packets,json=udpPackets" json:"udp_packets,omitempty"` UDPPackets *uint32 `protobuf:"varint,6,opt,name=udp_packets,json=udpPackets" json:"udp_packets,omitempty"`
// Amount of TCP packets sent. // Amount of TCP packets sent.
TcpPackets *uint32 `protobuf:"varint,7,opt,name=tcp_packets,json=tcpPackets" json:"tcp_packets,omitempty"` TCPPackets *uint32 `protobuf:"varint,7,opt,name=tcp_packets,json=tcpPackets" json:"tcp_packets,omitempty"`
// UDP ping average. // UDP ping average.
UdpPingAvg *float32 `protobuf:"fixed32,8,opt,name=udp_ping_avg,json=udpPingAvg" json:"udp_ping_avg,omitempty"` UDPPingAvg *float32 `protobuf:"fixed32,8,opt,name=udp_ping_avg,json=udpPingAvg" json:"udp_ping_avg,omitempty"`
// UDP ping variance. // UDP ping variance.
UdpPingVar *float32 `protobuf:"fixed32,9,opt,name=udp_ping_var,json=udpPingVar" json:"udp_ping_var,omitempty"` UDPPingVar *float32 `protobuf:"fixed32,9,opt,name=udp_ping_var,json=udpPingVar" json:"udp_ping_var,omitempty"`
// TCP ping average. // TCP ping average.
TcpPingAvg *float32 `protobuf:"fixed32,10,opt,name=tcp_ping_avg,json=tcpPingAvg" json:"tcp_ping_avg,omitempty"` TCPPingAvg *float32 `protobuf:"fixed32,10,opt,name=tcp_ping_avg,json=tcpPingAvg" json:"tcp_ping_avg,omitempty"`
// TCP ping variance. // TCP ping variance.
TcpPingVar *float32 `protobuf:"fixed32,11,opt,name=tcp_ping_var,json=tcpPingVar" json:"tcp_ping_var,omitempty"` TCPPingVar *float32 `protobuf:"fixed32,11,opt,name=tcp_ping_var,json=tcpPingVar" json:"tcp_ping_var,omitempty"`
// Client version. // Client version.
Version *Version `protobuf:"bytes,12,opt,name=version" json:"version,omitempty"` Version *Version `protobuf:"bytes,12,opt,name=version" json:"version,omitempty"`
// A list of CELT bitstream version constants supported by the client of this // A list of CELT bitstream version constants supported by the client of this
@ -1869,44 +1869,44 @@ func (m *UserStats) GetFromServer() *UserStats_Stats {
return nil return nil
} }
func (m *UserStats) GetUdpPackets() uint32 { func (m *UserStats) GetUDPPackets() uint32 {
if m != nil && m.UdpPackets != nil { if m != nil && m.UDPPackets != nil {
return *m.UdpPackets return *m.UDPPackets
} }
return 0 return 0
} }
func (m *UserStats) GetTcpPackets() uint32 { func (m *UserStats) GetTCPPackets() uint32 {
if m != nil && m.TcpPackets != nil { if m != nil && m.TCPPackets != nil {
return *m.TcpPackets return *m.TCPPackets
} }
return 0 return 0
} }
func (m *UserStats) GetUdpPingAvg() float32 { func (m *UserStats) GetUDPPingAvg() float32 {
if m != nil && m.UdpPingAvg != nil { if m != nil && m.UDPPingAvg != nil {
return *m.UdpPingAvg return *m.UDPPingAvg
} }
return 0 return 0
} }
func (m *UserStats) GetUdpPingVar() float32 { func (m *UserStats) GetUDPPingVar() float32 {
if m != nil && m.UdpPingVar != nil { if m != nil && m.UDPPingVar != nil {
return *m.UdpPingVar return *m.UDPPingVar
} }
return 0 return 0
} }
func (m *UserStats) GetTcpPingAvg() float32 { func (m *UserStats) GetTCPPingAvg() float32 {
if m != nil && m.TcpPingAvg != nil { if m != nil && m.TCPPingAvg != nil {
return *m.TcpPingAvg return *m.TCPPingAvg
} }
return 0 return 0
} }
func (m *UserStats) GetTcpPingVar() float32 { func (m *UserStats) GetTCPPingVar() float32 {
if m != nil && m.TcpPingVar != nil { if m != nil && m.TCPPingVar != nil {
return *m.TcpPingVar return *m.TCPPingVar
} }
return 0 return 0
} }

View file

@ -4,6 +4,7 @@
package mumbleproto package mumbleproto
// All different message types
const ( const (
MessageVersion uint16 = iota MessageVersion uint16 = iota
MessageUDPTunnel MessageUDPTunnel
@ -32,6 +33,7 @@ const (
MessageServerConfig MessageServerConfig
) )
// All different UDP message types
const ( const (
UDPMessageVoiceCELTAlpha = iota UDPMessageVoiceCELTAlpha = iota
UDPMessagePing UDPMessagePing

View file

@ -9,6 +9,7 @@ import (
"math" "math"
) )
// PacketData contains one packet of information
type PacketData struct { type PacketData struct {
Buf []byte Buf []byte
offset int offset int
@ -17,6 +18,7 @@ type PacketData struct {
ok bool ok bool
} }
// New creates a new packet data from the buffer
func New(buf []byte) (pds *PacketData) { func New(buf []byte) (pds *PacketData) {
pds = new(PacketData) pds = new(PacketData)
pds.Buf = buf pds.Buf = buf
@ -25,10 +27,12 @@ func New(buf []byte) (pds *PacketData) {
return return
} }
// IsValid checks whether the current packet data is valid
func (pds *PacketData) IsValid() bool { func (pds *PacketData) IsValid() bool {
return pds.ok return pds.ok
} }
// Skip will skip some data
func (pds *PacketData) Skip(skip int) { func (pds *PacketData) Skip(skip int) {
if pds.Left() >= skip { if pds.Left() >= skip {
pds.offset += skip pds.offset += skip
@ -53,11 +57,11 @@ func (pds *PacketData) Size() int {
func (pds *PacketData) next() (ret uint64) { func (pds *PacketData) next() (ret uint64) {
if pds.offset < pds.maxsize { if pds.offset < pds.maxsize {
ret = uint64(pds.Buf[pds.offset]) ret = uint64(pds.Buf[pds.offset])
pds.offset += 1 pds.offset++
return return
} else {
pds.ok = false
} }
pds.ok = false
return 0 return 0
} }
@ -65,11 +69,11 @@ func (pds *PacketData) next() (ret uint64) {
func (pds *PacketData) Next8() (ret uint8) { func (pds *PacketData) Next8() (ret uint8) {
if pds.offset < pds.maxsize { if pds.offset < pds.maxsize {
ret = uint8(pds.Buf[pds.offset]) ret = uint8(pds.Buf[pds.offset])
pds.offset += 1 pds.offset++
return return
} else {
pds.ok = false
} }
pds.ok = false
return 0 return 0
} }
@ -83,7 +87,7 @@ func (pds *PacketData) append(val uint64) {
if pds.offset < pds.maxsize { if pds.offset < pds.maxsize {
pds.Buf[pds.offset] = byte(val) pds.Buf[pds.offset] = byte(val)
pds.offset += 1 pds.offset++
} else { } else {
pds.ok = false pds.ok = false
pds.overshoot++ pds.overshoot++
@ -299,7 +303,7 @@ func (pds *PacketData) PutFloat64(val float64) {
pds.append(bits & 0xff) pds.append(bits & 0xff)
} }
// Copy a buffer out of the PacketData into dst. // CopyBytes will copy a buffer out of the PacketData into dst.
func (pds *PacketData) CopyBytes(dst []byte) { func (pds *PacketData) CopyBytes(dst []byte) {
if pds.Left() >= len(dst) { if pds.Left() >= len(dst) {
if copy(dst, pds.Buf[pds.offset:pds.offset+len(dst)]) != len(dst) { if copy(dst, pds.Buf[pds.offset:pds.offset+len(dst)]) != len(dst) {
@ -310,7 +314,7 @@ func (pds *PacketData) CopyBytes(dst []byte) {
} }
} }
// Put a buffer src into the PacketData at the // PutBytes will put a buffer src into the PacketData at the
// current offset. // current offset.
func (pds *PacketData) PutBytes(src []byte) { func (pds *PacketData) PutBytes(src []byte) {
if pds.Left() >= len(src) { if pds.Left() >= len(src) {

View file

@ -4,8 +4,10 @@
package replacefile package replacefile
// Flag is a flag that allows you to ignore some errors
type Flag uint32 type Flag uint32
// The types of errors that can be ignored
const ( const (
IgnoreMergeErrors Flag = 0x2 IgnoreMergeErrors Flag = 0x2
IgnoreACLErrors Flag = 0x4 IgnoreACLErrors Flag = 0x4

View file

@ -10,6 +10,7 @@ import (
"errors" "errors"
) )
// The different types of errors that can happen if we're not on windows
var ( var (
errOnlyWindows = errors.New("replacefile: only implemented on Windows") errOnlyWindows = errors.New("replacefile: only implemented on Windows")
ErrUnableToMoveReplacement error = errOnlyWindows ErrUnableToMoveReplacement error = errOnlyWindows
@ -17,6 +18,7 @@ var (
ErrUnableToRemoveReplaced error = errOnlyWindows ErrUnableToRemoveReplaced error = errOnlyWindows
) )
// ReplaceFile tries to replace the file
func ReplaceFile(replaced string, replacement string, backup string, flags Flag) error { func ReplaceFile(replaced string, replacement string, backup string, flags Flag) error {
return errOnlyWindows return errOnlyWindows
} }

View file

@ -22,12 +22,13 @@ var defaultCfg = map[string]string{
"SendVersion": "true", "SendVersion": "true",
} }
// Config contains all configurations
type Config struct { type Config struct {
cfgMap map[string]string cfgMap map[string]string
mutex sync.RWMutex mutex sync.RWMutex
} }
// Create a new Config using cfgMap as the intial internal config map. // New creates a new Config using cfgMap as the intial internal config map.
// If cfgMap is nil, ConfigWithMap will create a new config map. // If cfgMap is nil, ConfigWithMap will create a new config map.
func New(cfgMap map[string]string) *Config { func New(cfgMap map[string]string) *Config {
if cfgMap == nil { if cfgMap == nil {

View file

@ -10,7 +10,7 @@ import (
"sync" "sync"
) )
// A SessionPool is a pool for session IDs. // SessionPool is a pool for session IDs.
// IDs are re-used in MRU order, for ease of implementation in Go. // IDs are re-used in MRU order, for ease of implementation in Go.
type SessionPool struct { type SessionPool struct {
mutex sync.Mutex mutex sync.Mutex
@ -19,13 +19,13 @@ type SessionPool struct {
cur uint32 cur uint32
} }
// Create a new SessionPool container. // New creates a new SessionPool container.
func New() (pool *SessionPool) { func New() (pool *SessionPool) {
pool = new(SessionPool) pool = new(SessionPool)
return return
} }
// Enable use-tracking for the SessionPool. // EnableUseTracking will enable use-tracking for the SessionPool.
// //
// When enabled, the SessionPool stores all session IDs // When enabled, the SessionPool stores all session IDs
// returned by Get() internally. When an ID is reclaimed, // returned by Get() internally. When an ID is reclaimed,
@ -70,7 +70,7 @@ func (pool *SessionPool) Get() (id uint32) {
// Increment the next session id and return it. // Increment the next session id and return it.
// Note: By incrementing and *then* returning, we skip 0. // Note: By incrementing and *then* returning, we skip 0.
// This is deliberate, as 0 is an invalid session ID in Mumble. // This is deliberate, as 0 is an invalid session ID in Mumble.
pool.cur += 1 pool.cur++
id = pool.cur id = pool.cur
return return
} }

View file

@ -23,6 +23,7 @@ var upgrader = websocket.Upgrader{
}, },
} }
// Listener represents a specific network listener
type Listener struct { type Listener struct {
sockets chan *conn sockets chan *conn
done chan struct{} done chan struct{}
@ -31,6 +32,7 @@ type Listener struct {
logger *log.Logger logger *log.Logger
} }
// NewListener creates a new listener
func NewListener(laddr net.Addr, logger *log.Logger) *Listener { func NewListener(laddr net.Addr, logger *log.Logger) *Listener {
return &Listener{ return &Listener{
sockets: make(chan *conn), sockets: make(chan *conn),
@ -40,6 +42,7 @@ func NewListener(laddr net.Addr, logger *log.Logger) *Listener {
} }
} }
// Accept blocks and waits for a new connection
func (l *Listener) Accept() (net.Conn, error) { func (l *Listener) Accept() (net.Conn, error) {
if atomic.LoadInt32(&l.closed) != 0 { if atomic.LoadInt32(&l.closed) != 0 {
return nil, fmt.Errorf("accept ws %v: use of closed websocket listener", l.addr) return nil, fmt.Errorf("accept ws %v: use of closed websocket listener", l.addr)
@ -52,6 +55,7 @@ func (l *Listener) Accept() (net.Conn, error) {
} }
} }
// Close will close the underlying listener
func (l *Listener) Close() error { func (l *Listener) Close() error {
if !atomic.CompareAndSwapInt32(&l.closed, 0, 1) { if !atomic.CompareAndSwapInt32(&l.closed, 0, 1) {
return fmt.Errorf("close ws %v: use of closed websocket listener", l.addr) return fmt.Errorf("close ws %v: use of closed websocket listener", l.addr)
@ -60,6 +64,7 @@ func (l *Listener) Close() error {
return nil return nil
} }
// Addr returns the internal address
func (l *Listener) Addr() net.Addr { func (l *Listener) Addr() net.Addr {
return l.addr return l.addr
} }