]> git.lizzy.rs Git - minetest.git/commitdiff
Protect per-player detached inventory actions
authorSmallJoker <mk939@ymail.com>
Sun, 7 Mar 2021 09:04:07 +0000 (10:04 +0100)
committerSmallJoker <SmallJoker@users.noreply.github.com>
Sun, 7 Mar 2021 16:18:02 +0000 (17:18 +0100)
src/network/serverpackethandler.cpp
src/server/serverinventorymgr.cpp
src/server/serverinventorymgr.h

index ddc6f4e47c4ecb64d75a9c9f44d7476244a842bd..f1ed42302f21278f59db9d2f0e60f0a325773b96 100644 (file)
@@ -626,7 +626,7 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)
 
        const bool player_has_interact = checkPriv(player->getName(), "interact");
 
-       auto check_inv_access = [player, player_has_interact] (
+       auto check_inv_access = [player, player_has_interact, this] (
                        const InventoryLocation &loc) -> bool {
                if (loc.type == InventoryLocation::CURRENT_PLAYER)
                        return false; // Only used internally on the client, never sent
@@ -634,6 +634,10 @@ void Server::handleCommand_InventoryAction(NetworkPacket* pkt)
                        // Allow access to own inventory in all cases
                        return loc.name == player->getName();
                }
+               if (loc.type == InventoryLocation::DETACHED) {
+                       if (!getInventoryMgr()->checkDetachedInventoryAccess(loc, player->getName()))
+                               return false;
+               }
 
                if (!player_has_interact) {
                        infostream << "Cannot modify foreign inventory: "
index 555e01ec61a57fafecd5734f68a26bffdd77624a..2a80c9bbe8da1a036d9def8c1e3268a711f4cb0f 100644 (file)
@@ -168,6 +168,18 @@ bool ServerInventoryManager::removeDetachedInventory(const std::string &name)
        return true;
 }
 
+bool ServerInventoryManager::checkDetachedInventoryAccess(
+               const InventoryLocation &loc, const std::string &player) const
+{
+       SANITY_CHECK(loc.type == InventoryLocation::DETACHED);
+
+       const auto &inv_it = m_detached_inventories.find(loc.name);
+       if (inv_it == m_detached_inventories.end())
+               return false;
+
+       return inv_it->second.owner.empty() || inv_it->second.owner == player;
+}
+
 void ServerInventoryManager::sendDetachedInventories(const std::string &peer_name,
                bool incremental,
                std::function<void(const std::string &, Inventory *)> apply_cb)
index ccf6d3b2e49b3083eb3bbbd2f79b9eb5b569fee6..0e4b7241537e63b4128449fed4ae63286cbfbc23 100644 (file)
@@ -43,6 +43,7 @@ class ServerInventoryManager : public InventoryManager
        Inventory *createDetachedInventory(const std::string &name, IItemDefManager *idef,
                        const std::string &player = "");
        bool removeDetachedInventory(const std::string &name);
+       bool checkDetachedInventoryAccess(const InventoryLocation &loc, const std::string &player) const;
 
        void sendDetachedInventories(const std::string &peer_name, bool incremental,
                        std::function<void(const std::string &, Inventory *)> apply_cb);