Remember and verify player XUIDs (controlled by player.verify-xuid in pocketmine.yml)

This commit is contained in:
Dylan K. Taylor 2021-02-05 14:42:57 +00:00
parent c5bdd7dd64
commit 78a62a8b27
No known key found for this signature in database
GPG Key ID: 8927471A91CAFD3D
2 changed files with 25 additions and 2 deletions

View File

@ -100,6 +100,7 @@ use pocketmine\nbt\tag\ByteTag;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\DoubleTag;
use pocketmine\nbt\tag\ListTag;
use pocketmine\nbt\tag\StringTag;
use pocketmine\network\mcpe\convert\ItemTypeDictionary;
use pocketmine\network\mcpe\PlayerNetworkSessionAdapter;
use pocketmine\network\mcpe\protocol\ActorEventPacket;
@ -2080,6 +2081,25 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
* @return void
*/
protected function processLogin(){
$this->namedtag = $this->server->getOfflinePlayerData($this->username);
if((bool) $this->server->getProperty("player.verify-xuid")){
$recordedXUID = $this->namedtag->getTag("LastKnownXUID");
if(!($recordedXUID instanceof StringTag)){
$this->server->getLogger()->debug("No previous XUID recorded for " . $this->getName() . ", no choice but to trust this player");
}elseif($this->xuid !== $recordedXUID->getValue()){
if($this->kick("XUID does not match (possible impersonation attempt)", false)){
//TODO: Longer term, we should be identifying playerdata using something more reliable, like XUID or UUID.
//However, that would be a very disruptive change, so this will serve as a stopgap for now.
//Side note: this will also prevent offline players hijacking XBL playerdata on online servers, since their
//XUID will always be empty.
return;
}
$this->server->getLogger()->debug("XUID mismatch for " . $this->getName() . ", but plugin cancelled event allowing them to join anyway");
}else{
$this->server->getLogger()->debug("XUID match for " . $this->getName());
}
}
foreach($this->server->getLoggedInPlayers() as $p){
if($p !== $this and ($p->iusername === $this->iusername or $this->getUniqueId()->equals($p->getUniqueId()))){
if(!$p->kick("logged in from another location")){
@ -2090,8 +2110,6 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
}
}
$this->namedtag = $this->server->getOfflinePlayerData($this->username);
$this->playedBefore = ($this->getLastPlayed() - $this->getFirstPlayed()) > 1; // microtime(true) - microtime(true) may have less than one millisecond difference
$this->namedtag->setString("NameTag", $this->username);
@ -3756,6 +3774,8 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
parent::saveNBT();
$this->namedtag->setString("LastKnownXUID", $this->xuid);
if($this->isValid()){
$this->namedtag->setString("Level", $this->level->getFolderName());
}

View File

@ -100,6 +100,9 @@ debug:
player:
#Choose whether to enable player data saving.
save-player-data: true
#If true, checks that joining players' Xbox user ID (XUID) match what was previously recorded.
#This also prevents non-XBL players using XBL players' usernames to steal their data on servers with xbox-auth=off.
verify-xuid: true
anti-cheat:
#If false, will try to prevent speed and noclip cheats. May cause movement issues.
allow-movement-cheats: true