示例#1
0
文件: freeze.go 项目: dmorlo/grumble
// 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)
	}
}
示例#2
0
// 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
}
示例#3
0
文件: message.go 项目: dmorlo/grumble
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")
	}
}
示例#4
0
文件: message.go 项目: dmorlo/grumble
// 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()
}