// Merge the contents of a freezer.BanList into the server's // ban list. func (s *Server) UnfreezeBanList(fblist *freezer.BanList) { s.Bans = nil for _, fb := range fblist.Bans { ban := ban.Ban{} ban.IP = fb.Ip if fb.Mask != nil { ban.Mask = int(*fb.Mask) } if fb.Username != nil { ban.Username = *fb.Username } if fb.CertHash != nil { ban.CertHash = *fb.CertHash } if fb.Reason != nil { ban.Reason = *fb.Reason } if fb.Start != nil { ban.Start = *fb.Start } if fb.Duration != nil { ban.Duration = *fb.Duration } s.Bans = append(s.Bans, ban) } }
// Populate bans func populateBans(server *Server, db *sql.DB) (err error) { stmt, err := db.Prepare("SELECT base, mask, name, hash, reason, start, duration FROM bans WHERE server_id=?") if err != nil { return } rows, err := stmt.Query(server.Id) if err != nil { return err } for rows.Next() { var ( Ban ban.Ban IP []byte StartDate string Duration int64 ) err = rows.Scan(&IP, &Ban.Mask, &Ban.Username, &Ban.CertHash, &Ban.Reason, &StartDate, &Duration) if err != nil { return err } if len(IP) == 16 && IP[10] == 0xff && IP[11] == 0xff { Ban.IP = net.IPv4(IP[12], IP[13], IP[14], IP[15]) } else { Ban.IP = IP } Ban.SetISOStartDate(StartDate) Ban.Duration = uint32(Duration) server.Bans = append(server.Bans, Ban) } return }
func (server *Server) handleBanListMessage(client *Client, msg *Message) { banlist := &mumbleproto.BanList{} err := proto.Unmarshal(msg.buf, banlist) if err != nil { client.Panic(err) return } rootChan := server.RootChannel() if !acl.HasPermission(&rootChan.ACL, client, acl.BanPermission) { client.sendPermissionDenied(client, rootChan, acl.BanPermission) return } if banlist.Query != nil && *banlist.Query != false { banlist.Reset() server.banlock.RLock() defer server.banlock.RUnlock() for _, ban := range server.Bans { entry := &mumbleproto.BanList_BanEntry{} entry.Address = ban.IP entry.Mask = proto.Uint32(uint32(ban.Mask)) entry.Name = proto.String(ban.Username) entry.Hash = proto.String(ban.CertHash) entry.Reason = proto.String(ban.Reason) entry.Start = proto.String(ban.ISOStartDate()) entry.Duration = proto.Uint32(ban.Duration) banlist.Bans = append(banlist.Bans, entry) } if err := client.sendMessage(banlist); err != nil { client.Panic("Unable to send BanList") } } else { server.banlock.Lock() defer server.banlock.Unlock() server.Bans = server.Bans[0:0] for _, entry := range banlist.Bans { ban := ban.Ban{} ban.IP = entry.Address ban.Mask = int(*entry.Mask) if entry.Name != nil { ban.Username = *entry.Name } if entry.Hash != nil { ban.CertHash = *entry.Hash } if entry.Reason != nil { ban.Reason = *entry.Reason } if entry.Start != nil { ban.SetISOStartDate(*entry.Start) } if entry.Duration != nil { ban.Duration = *entry.Duration } server.Bans = append(server.Bans, ban) } server.UpdateFrozenBans(server.Bans) client.Printf("Banlist updated") } }
// Handle a user remove packet. This can either be a client disconnecting, or a // user kicking or kick-banning another player. func (server *Server) handleUserRemoveMessage(client *Client, msg *Message) { userremove := &mumbleproto.UserRemove{} err := proto.Unmarshal(msg.buf, userremove) if err != nil { client.Panic(err) return } // Get the client to be removed. removeClient, ok := server.clients[*userremove.Session] if !ok { client.Panic("Invalid session in UserRemove message") return } isBan := false if userremove.Ban != nil { isBan = *userremove.Ban } // Check client's permissions perm := acl.Permission(acl.KickPermission) if isBan { perm = acl.Permission(acl.BanPermission) } rootChan := server.RootChannel() if removeClient.IsSuperUser() || !acl.HasPermission(&rootChan.ACL, client, perm) { client.sendPermissionDenied(client, rootChan, perm) return } if isBan { ban := ban.Ban{} ban.IP = removeClient.conn.RemoteAddr().(*net.TCPAddr).IP ban.Mask = 128 if userremove.Reason != nil { ban.Reason = *userremove.Reason } ban.Username = removeClient.ShownName() ban.CertHash = removeClient.CertHash() ban.Start = time.Now().Unix() ban.Duration = 0 server.banlock.Lock() server.Bans = append(server.Bans, ban) server.UpdateFrozenBans(server.Bans) server.banlock.Unlock() } userremove.Actor = proto.Uint32(uint32(client.Session())) if err = server.broadcastProtoMessage(userremove); err != nil { server.Panicf("Unable to broadcast UserRemove message") return } if isBan { client.Printf("Kick-banned %v (%v)", removeClient.ShownName(), removeClient.Session()) } else { client.Printf("Kicked %v (%v)", removeClient.ShownName(), removeClient.Session()) } removeClient.ForceDisconnect() }